From 52124e52dc80d6ba33acae39cfd133402c3f1fb6 Mon Sep 17 00:00:00 2001 From: Eric Scouten Date: Tue, 10 Dec 2024 16:45:43 -0800 Subject: [PATCH 01/29] feat: Add `RawSigner` trait to `c2pa-crypto` (derived from `c2pa::Signer`) (#716) --- docs/usage.md | 1 - internal/crypto/Cargo.toml | 6 +- internal/crypto/src/openssl/cert_chain.rs | 48 +++ internal/crypto/src/openssl/mod.rs | 3 + .../src/openssl/signers/ecdsa_signer.rs | 140 ++++++++ .../src/openssl/signers/ed25519_signer.rs | 105 ++++++ internal/crypto/src/openssl/signers/mod.rs | 67 ++++ .../crypto/src/openssl/signers/rsa_signer.rs | 186 +++++++++++ internal/crypto/src/p1363.rs | 59 ++++ internal/crypto/src/raw_signature/mod.rs | 6 + internal/crypto/src/raw_signature/signer.rs | 269 ++++++++++++++++ .../tests/fixtures/raw_signature/ed25519.priv | 3 + .../tests/fixtures/raw_signature/es256.priv | 5 + .../tests/fixtures/raw_signature/es384.priv | 6 + .../tests/fixtures/raw_signature/es512.priv | 8 + internal/crypto/src/tests/openssl/mod.rs | 1 + .../src/tests/openssl/signers/ecdsa_signer.rs | 176 ++++++++++ .../tests/openssl/signers/ed25519_signer.rs | 72 +++++ .../crypto/src/tests/openssl/signers/mod.rs | 16 + .../src/tests/openssl/signers/rsa_signer.rs | 176 ++++++++++ internal/crypto/src/tests/webcrypto/mod.rs | 1 + .../tests/webcrypto/signers/ed25519_signer.rs | 42 +++ .../crypto/src/tests/webcrypto/signers/mod.rs | 14 + internal/crypto/src/webcrypto/mod.rs | 1 + .../src/webcrypto/signers/ed25519_signer.rs | 101 ++++++ internal/crypto/src/webcrypto/signers/mod.rs | 48 +++ sdk/Cargo.toml | 1 - sdk/src/asset_handlers/c2pa_io.rs | 8 +- sdk/src/builder.rs | 19 +- sdk/src/callback_signer.rs | 14 +- sdk/src/cose_sign.rs | 79 ++++- sdk/src/cose_validator.rs | 45 ++- sdk/src/create_signer.rs | 41 +-- sdk/src/error.rs | 3 + sdk/src/jumbf_io.rs | 6 +- sdk/src/manifest.rs | 56 ++-- sdk/src/openssl/ec_signer.rs | 171 ---------- sdk/src/openssl/ed_signer.rs | 130 -------- sdk/src/openssl/mod.rs | 84 ----- sdk/src/openssl/openssl_trust_handler.rs | 68 ++-- sdk/src/openssl/rsa_signer.rs | 303 ------------------ sdk/src/openssl/temp_signer.rs | 184 ----------- sdk/src/openssl/temp_signer_async.rs | 101 ------ sdk/src/resource_store.rs | 7 +- sdk/src/signer.rs | 167 +++++++++- sdk/src/store.rs | 80 ++--- sdk/src/utils/mod.rs | 4 +- sdk/src/utils/sig_utils.rs | 73 ----- sdk/src/utils/test.rs | 93 +----- sdk/src/utils/test_signer.rs | 146 +++++++++ sdk/src/wasm/rsa_wasm_signer.rs | 5 +- sdk/tests/common/test_signer.rs | 9 +- sdk/tests/v2_api_integration.rs | 4 +- 53 files changed, 2117 insertions(+), 1344 deletions(-) create mode 100644 internal/crypto/src/openssl/cert_chain.rs create mode 100644 internal/crypto/src/openssl/signers/ecdsa_signer.rs create mode 100644 internal/crypto/src/openssl/signers/ed25519_signer.rs create mode 100644 internal/crypto/src/openssl/signers/mod.rs create mode 100644 internal/crypto/src/openssl/signers/rsa_signer.rs create mode 100644 internal/crypto/src/raw_signature/signer.rs create mode 100644 internal/crypto/src/tests/fixtures/raw_signature/ed25519.priv create mode 100644 internal/crypto/src/tests/fixtures/raw_signature/es256.priv create mode 100644 internal/crypto/src/tests/fixtures/raw_signature/es384.priv create mode 100644 internal/crypto/src/tests/fixtures/raw_signature/es512.priv create mode 100644 internal/crypto/src/tests/openssl/signers/ecdsa_signer.rs create mode 100644 internal/crypto/src/tests/openssl/signers/ed25519_signer.rs create mode 100644 internal/crypto/src/tests/openssl/signers/mod.rs create mode 100644 internal/crypto/src/tests/openssl/signers/rsa_signer.rs create mode 100644 internal/crypto/src/tests/webcrypto/signers/ed25519_signer.rs create mode 100644 internal/crypto/src/tests/webcrypto/signers/mod.rs create mode 100644 internal/crypto/src/webcrypto/signers/ed25519_signer.rs create mode 100644 internal/crypto/src/webcrypto/signers/mod.rs delete mode 100644 sdk/src/openssl/ec_signer.rs delete mode 100644 sdk/src/openssl/ed_signer.rs delete mode 100644 sdk/src/openssl/rsa_signer.rs delete mode 100644 sdk/src/openssl/temp_signer.rs delete mode 100644 sdk/src/openssl/temp_signer_async.rs delete mode 100644 sdk/src/utils/sig_utils.rs create mode 100644 sdk/src/utils/test_signer.rs diff --git a/docs/usage.md b/docs/usage.md index 417857ed5..54ce6bfc0 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -42,7 +42,6 @@ The Rust library crate provides the following capabilities: * `no_interleaved_io` forces fully-synchronous I/O; otherwise, the library uses threaded I/O for some operations to improve performance. * `fetch_remote_manifests` enables the verification step to retrieve externally referenced manifest stores. External manifests are only fetched if there is no embedded manifest store and no locally adjacent .c2pa manifest store file of the same name. * `json_schema` is used by `make schema` to produce a JSON schema document that represents the `ManifestStore` data structures. -* `psxxx_ocsp_stapling_experimental` enables a demonstration feature that attempts to fetch the OCSP data from the OCSP responders listed in the manifest signing certificate. The response becomes part of the manifest and is used to prove the certificate was not revoked at the time of signing. This is only implemented for PS256, PS384 and PS512 signatures and is intended as a demonstration. * `openssl_ffi_mutex` prevents multiple threads from accessing the C OpenSSL library simultaneously. (This library is not re-entrant.) In a multi-threaded process (such as Cargo's test runner), this can lead to unpredictable behavior. ### New API diff --git a/internal/crypto/Cargo.toml b/internal/crypto/Cargo.toml index 06b3712f6..3137466a3 100644 --- a/internal/crypto/Cargo.toml +++ b/internal/crypto/Cargo.toml @@ -37,6 +37,7 @@ bcder = "0.7.3" bytes = "1.7.2" c2pa-status-tracker = { path = "../status-tracker", version = "0.1.0" } ciborium = "0.2.2" +const-hex = "1.14" coset = "0.3.1" getrandom = { version = "0.2.7", features = ["js"] } hex = "0.4.3" @@ -74,7 +75,7 @@ features = ["now", "wasmbind"] [target.'cfg(target_arch = "wasm32")'.dependencies] async-trait = { version = "0.1.77" } ecdsa = "0.16.9" -ed25519-dalek = "2.1.1" +ed25519-dalek = { version = "2.1.1", features = ["alloc", "digest", "pem", "pkcs8"] } p256 = "0.13.2" p384 = "0.13.0" rsa = { version = "0.9.6", features = ["sha2"] } @@ -95,5 +96,8 @@ web-time = "1.1" getrandom = { version = "0.2.7", features = ["js"] } js-sys = "0.3.58" +[target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies] +actix = "0.13.1" + [target.'cfg(target_arch = "wasm32")'.dev-dependencies] wasm-bindgen-test = "0.3.31" diff --git a/internal/crypto/src/openssl/cert_chain.rs b/internal/crypto/src/openssl/cert_chain.rs new file mode 100644 index 000000000..f8442bfb3 --- /dev/null +++ b/internal/crypto/src/openssl/cert_chain.rs @@ -0,0 +1,48 @@ +// Copyright 2022 Adobe. All rights reserved. +// This file is licensed to you under the Apache License, +// Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0) +// or the MIT license (http://opensource.org/licenses/MIT), +// at your option. + +// Unless required by applicable law or agreed to in writing, +// this software is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR REPRESENTATIONS OF ANY KIND, either express or +// implied. See the LICENSE-MIT and LICENSE-APACHE files for the +// specific language governing permissions and limitations under +// each license. + +#![allow(dead_code)] // TEMPORARY while refactoring + +use openssl::x509::X509; + +// Verify the certificate chain order. +// +// Return `true` if each cert in the chain can be verified as issued by the next +// issuer. +pub(crate) fn check_chain_order(certs: &[X509]) -> bool { + // IMPORTANT: ffi_mutex::acquire() should have been called by calling fn. Please + // don't make this pub or pub(crate) without finding a way to ensure that + // precondition. + + let mut iter = certs.iter().peekable(); + + while let Some(cert) = iter.next() { + let Some(next) = iter.peek() else { + break; + }; + + let Ok(pkey) = next.public_key() else { + return false; + }; + + let Ok(verified) = cert.verify(&pkey) else { + return false; + }; + + if !verified { + return false; + } + } + + true +} diff --git a/internal/crypto/src/openssl/mod.rs b/internal/crypto/src/openssl/mod.rs index 2b0ad9437..78fda28d4 100644 --- a/internal/crypto/src/openssl/mod.rs +++ b/internal/crypto/src/openssl/mod.rs @@ -18,7 +18,10 @@ //! //! [`openssl` native code library]: https://crates.io/crates/openssl +mod cert_chain; + mod ffi_mutex; pub use ffi_mutex::{OpenSslMutex, OpenSslMutexUnavailable}; +pub(crate) mod signers; pub mod validators; diff --git a/internal/crypto/src/openssl/signers/ecdsa_signer.rs b/internal/crypto/src/openssl/signers/ecdsa_signer.rs new file mode 100644 index 000000000..aa35635e4 --- /dev/null +++ b/internal/crypto/src/openssl/signers/ecdsa_signer.rs @@ -0,0 +1,140 @@ +// Copyright 2022 Adobe. All rights reserved. +// This file is licensed to you under the Apache License, +// Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0) +// or the MIT license (http://opensource.org/licenses/MIT), +// at your option. + +// Unless required by applicable law or agreed to in writing, +// this software is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR REPRESENTATIONS OF ANY KIND, either express or +// implied. See the LICENSE-MIT and LICENSE-APACHE files for the +// specific language governing permissions and limitations under +// each license. + +use openssl::{ + ec::EcKey, + hash::MessageDigest, + pkey::{PKey, Private}, + sign::Signer, + x509::X509, +}; + +use crate::{ + openssl::{cert_chain::check_chain_order, OpenSslMutex}, + p1363::der_to_p1363, + raw_signature::{RawSigner, RawSignerError}, + time_stamp::TimeStampProvider, + SigningAlg, +}; + +enum EcdsaSigningAlg { + Es256, + Es384, + Es512, +} + +/// Implements `Signer` trait using OpenSSL's implementation of +/// ECDSA encryption. +pub struct EcdsaSigner { + alg: EcdsaSigningAlg, + + cert_chain: Vec, + cert_chain_len: usize, + + private_key: EcKey, + + time_stamp_service_url: Option, + time_stamp_size: usize, +} + +impl EcdsaSigner { + pub(crate) fn from_cert_chain_and_private_key( + cert_chain: &[u8], + private_key: &[u8], + alg: SigningAlg, + time_stamp_service_url: Option, + ) -> Result { + let alg = match alg { + SigningAlg::Es256 => EcdsaSigningAlg::Es256, + SigningAlg::Es384 => EcdsaSigningAlg::Es384, + SigningAlg::Es512 => EcdsaSigningAlg::Es512, + _ => { + return Err(RawSignerError::InternalError( + "EcdsaSigner should be used only for SigningAlg::Es***".to_string(), + )); + } + }; + + let _openssl = OpenSslMutex::acquire()?; + + let cert_chain = X509::stack_from_pem(cert_chain)?; + let cert_chain_len = cert_chain.len(); + + if !check_chain_order(&cert_chain) { + return Err(RawSignerError::InvalidSigningCredentials( + "certificate chain in incorrect order".to_string(), + )); + } + + let private_key = EcKey::private_key_from_pem(private_key)?; + + Ok(EcdsaSigner { + alg, + cert_chain, + cert_chain_len, + private_key, + time_stamp_service_url, + time_stamp_size: 10000, + // TO DO: Call out to time stamp service to get actual time stamp and use that size? + }) + } +} + +impl RawSigner for EcdsaSigner { + fn sign(&self, data: &[u8]) -> Result, RawSignerError> { + let _openssl = OpenSslMutex::acquire()?; + + let private_key = PKey::from_ec_key(self.private_key.clone())?; + + let mut signer = match self.alg { + EcdsaSigningAlg::Es256 => Signer::new(MessageDigest::sha256(), &private_key)?, + EcdsaSigningAlg::Es384 => Signer::new(MessageDigest::sha384(), &private_key)?, + EcdsaSigningAlg::Es512 => Signer::new(MessageDigest::sha512(), &private_key)?, + }; + + signer.update(data)?; + + let der_sig = signer.sign_to_vec()?; + der_to_p1363(&der_sig, self.alg()) + } + + fn alg(&self) -> SigningAlg { + match self.alg { + EcdsaSigningAlg::Es256 => SigningAlg::Es256, + EcdsaSigningAlg::Es384 => SigningAlg::Es384, + EcdsaSigningAlg::Es512 => SigningAlg::Es512, + } + } + + fn reserve_size(&self) -> usize { + 1024 + self.cert_chain_len + self.time_stamp_size + } + + fn cert_chain(&self) -> Result>, RawSignerError> { + let _openssl = OpenSslMutex::acquire()?; + + self.cert_chain + .iter() + .map(|cert| { + cert.to_der() + .map_err(|e| RawSignerError::OpenSslError(e.to_string())) + }) + .collect() + } +} + +impl TimeStampProvider for EcdsaSigner { + fn time_stamp_service_url(&self) -> Option { + self.time_stamp_service_url.clone() + } +} diff --git a/internal/crypto/src/openssl/signers/ed25519_signer.rs b/internal/crypto/src/openssl/signers/ed25519_signer.rs new file mode 100644 index 000000000..63e6f574f --- /dev/null +++ b/internal/crypto/src/openssl/signers/ed25519_signer.rs @@ -0,0 +1,105 @@ +// Copyright 2022 Adobe. All rights reserved. +// This file is licensed to you under the Apache License, +// Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0) +// or the MIT license (http://opensource.org/licenses/MIT), +// at your option. + +// Unless required by applicable law or agreed to in writing, +// this software is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR REPRESENTATIONS OF ANY KIND, either express or +// implied. See the LICENSE-MIT and LICENSE-APACHE files for the +// specific language governing permissions and limitations under +// each license. + +use openssl::{ + pkey::{PKey, Private}, + sign::Signer, + x509::X509, +}; + +use crate::{ + openssl::{cert_chain::check_chain_order, OpenSslMutex}, + raw_signature::{RawSigner, RawSignerError}, + time_stamp::TimeStampProvider, + SigningAlg, +}; + +/// Implements `RawSigner` trait using OpenSSL's implementation of +/// Edwards Curve encryption. +pub struct Ed25519Signer { + cert_chain: Vec, + cert_chain_len: usize, + + private_key: PKey, + + time_stamp_service_url: Option, + time_stamp_size: usize, +} + +impl Ed25519Signer { + pub(crate) fn from_cert_chain_and_private_key( + cert_chain: &[u8], + private_key: &[u8], + time_stamp_service_url: Option, + ) -> Result { + let _openssl = OpenSslMutex::acquire()?; + + let cert_chain = X509::stack_from_pem(cert_chain)?; + let cert_chain_len = cert_chain.len(); + + if !check_chain_order(&cert_chain) { + return Err(RawSignerError::InvalidSigningCredentials( + "certificate chain in incorrect order".to_string(), + )); + } + + let private_key = PKey::private_key_from_pem(private_key)?; + + Ok(Ed25519Signer { + cert_chain, + cert_chain_len, + + private_key, + + time_stamp_service_url, + time_stamp_size: 10000, + // TO DO: Call out to time stamp service to get actual time stamp and use that size? + }) + } +} + +impl RawSigner for Ed25519Signer { + fn sign(&self, data: &[u8]) -> Result, RawSignerError> { + let _openssl = OpenSslMutex::acquire()?; + + let mut signer = Signer::new_without_digest(&self.private_key)?; + + Ok(signer.sign_oneshot_to_vec(data)?) + } + + fn alg(&self) -> SigningAlg { + SigningAlg::Ed25519 + } + + fn reserve_size(&self) -> usize { + 1024 + self.cert_chain_len + self.time_stamp_size + } + + fn cert_chain(&self) -> Result>, RawSignerError> { + let _openssl = OpenSslMutex::acquire()?; + + self.cert_chain + .iter() + .map(|cert| { + cert.to_der() + .map_err(|e| RawSignerError::OpenSslError(e.to_string())) + }) + .collect() + } +} + +impl TimeStampProvider for Ed25519Signer { + fn time_stamp_service_url(&self) -> Option { + self.time_stamp_service_url.clone() + } +} diff --git a/internal/crypto/src/openssl/signers/mod.rs b/internal/crypto/src/openssl/signers/mod.rs new file mode 100644 index 000000000..639d0a1c5 --- /dev/null +++ b/internal/crypto/src/openssl/signers/mod.rs @@ -0,0 +1,67 @@ +// Copyright 2024 Adobe. All rights reserved. +// This file is licensed to you under the Apache License, +// Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0) +// or the MIT license (http://opensource.org/licenses/MIT), +// at your option. + +// Unless required by applicable law or agreed to in writing, +// this software is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR REPRESENTATIONS OF ANY KIND, either express or +// implied. See the LICENSE-MIT and LICENSE-APACHE files for the +// specific language governing permissions and limitations under +// each license. + +//! This module binds OpenSSL logic for generating raw signatures to this +//! crate's [`RawSigner`] trait. + +use crate::{ + raw_signature::{RawSigner, RawSignerError}, + SigningAlg, +}; + +mod ecdsa_signer; +mod ed25519_signer; +mod rsa_signer; + +/// Return a built-in [`RawSigner`] instance using the provided signing +/// certificate and private key. +/// +/// Which signers are available may vary depending on the platform and which +/// crate features were enabled. +/// +/// Returns `None` if the signing algorithm is unsupported. May return an `Err` +/// response if the certificate chain or private key are invalid. +pub(crate) fn signer_from_cert_chain_and_private_key( + cert_chain: &[u8], + private_key: &[u8], + alg: SigningAlg, + time_stamp_service_url: Option, +) -> Result, RawSignerError> { + match alg { + SigningAlg::Es256 | SigningAlg::Es384 | SigningAlg::Es512 => Ok(Box::new( + ecdsa_signer::EcdsaSigner::from_cert_chain_and_private_key( + cert_chain, + private_key, + alg, + time_stamp_service_url, + )?, + )), + + SigningAlg::Ed25519 => Ok(Box::new( + ed25519_signer::Ed25519Signer::from_cert_chain_and_private_key( + cert_chain, + private_key, + time_stamp_service_url, + )?, + )), + + SigningAlg::Ps256 | SigningAlg::Ps384 | SigningAlg::Ps512 => Ok(Box::new( + rsa_signer::RsaSigner::from_cert_chain_and_private_key( + cert_chain, + private_key, + alg, + time_stamp_service_url, + )?, + )), + } +} diff --git a/internal/crypto/src/openssl/signers/rsa_signer.rs b/internal/crypto/src/openssl/signers/rsa_signer.rs new file mode 100644 index 000000000..98e58cd26 --- /dev/null +++ b/internal/crypto/src/openssl/signers/rsa_signer.rs @@ -0,0 +1,186 @@ +// Copyright 2022 Adobe. All rights reserved. +// This file is licensed to you under the Apache License, +// Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0) +// or the MIT license (http://opensource.org/licenses/MIT), +// at your option. + +// Unless required by applicable law or agreed to in writing, +// this software is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR REPRESENTATIONS OF ANY KIND, either express or +// implied. See the LICENSE-MIT and LICENSE-APACHE files for the +// specific language governing permissions and limitations under +// each license. + +use openssl::{ + hash::MessageDigest, + pkey::{PKey, Private}, + rsa::{Rsa, RsaPrivateKeyBuilder}, + sign::Signer, + x509::X509, +}; + +use crate::{ + openssl::{cert_chain::check_chain_order, OpenSslMutex}, + raw_signature::{RawSigner, RawSignerError}, + time_stamp::TimeStampProvider, + SigningAlg, +}; + +enum RsaSigningAlg { + Ps256, + Ps384, + Ps512, +} + +/// Implements [`RawSigner`] trait using OpenSSL's implementation of SHA256 + +/// RSA encryption. +pub(crate) struct RsaSigner { + alg: RsaSigningAlg, + + cert_chain: Vec, + cert_chain_len: usize, + + private_key: PKey, + + time_stamp_service_url: Option, + time_stamp_size: usize, +} + +impl RsaSigner { + pub(crate) fn from_cert_chain_and_private_key( + cert_chain: &[u8], + private_key: &[u8], + alg: SigningAlg, + time_stamp_service_url: Option, + ) -> Result { + let _openssl = OpenSslMutex::acquire()?; + + let cert_chain = X509::stack_from_pem(cert_chain)?; + let cert_chain_len = cert_chain.len(); + + if !check_chain_order(&cert_chain) { + return Err(RawSignerError::InvalidSigningCredentials( + "certificate chain in incorrect order".to_string(), + )); + } + + // Rebuild RSA keys to eliminate incompatible values. + let private_key = Rsa::private_key_from_pem(private_key)?; + + let n = private_key.n().to_owned()?; + let e = private_key.e().to_owned()?; + let d = private_key.d().to_owned()?; + let po = private_key.p(); + let qo = private_key.q(); + let dmp1o = private_key.dmp1(); + let dmq1o = private_key.dmq1(); + let iqmpo = private_key.iqmp(); + + let mut pk_builder = RsaPrivateKeyBuilder::new(n, e, d)?; + + if let Some(p) = po { + if let Some(q) = qo { + pk_builder = pk_builder.set_factors(p.to_owned()?, q.to_owned()?)?; + } + } + + if let Some(dmp1) = dmp1o { + if let Some(dmq1) = dmq1o { + if let Some(iqmp) = iqmpo { + pk_builder = pk_builder.set_crt_params( + dmp1.to_owned()?, + dmq1.to_owned()?, + iqmp.to_owned()?, + )?; + } + } + } + + let private_key = PKey::from_rsa(pk_builder.build())?; + + let alg: RsaSigningAlg = match alg { + SigningAlg::Ps256 => RsaSigningAlg::Ps256, + SigningAlg::Ps384 => RsaSigningAlg::Ps384, + SigningAlg::Ps512 => RsaSigningAlg::Ps512, + _ => { + return Err(RawSignerError::InternalError( + "RsaSigner should be used only for SigningAlg::Ps***".to_string(), + )); + } + }; + + Ok(RsaSigner { + alg, + cert_chain, + private_key, + cert_chain_len, + time_stamp_service_url, + time_stamp_size: 10000, + // TO DO: Call out to time stamp service to get actual time stamp and use that size? + }) + } +} + +impl RawSigner for RsaSigner { + fn sign(&self, data: &[u8]) -> Result, RawSignerError> { + let _openssl = OpenSslMutex::acquire()?; + + let mut signer = match self.alg { + RsaSigningAlg::Ps256 => { + let mut signer = Signer::new(MessageDigest::sha256(), &self.private_key)?; + signer.set_rsa_padding(openssl::rsa::Padding::PKCS1_PSS)?; + signer.set_rsa_mgf1_md(MessageDigest::sha256())?; + signer.set_rsa_pss_saltlen(openssl::sign::RsaPssSaltlen::DIGEST_LENGTH)?; + signer + } + + RsaSigningAlg::Ps384 => { + let mut signer = Signer::new(MessageDigest::sha384(), &self.private_key)?; + signer.set_rsa_padding(openssl::rsa::Padding::PKCS1_PSS)?; + signer.set_rsa_mgf1_md(MessageDigest::sha384())?; + signer.set_rsa_pss_saltlen(openssl::sign::RsaPssSaltlen::DIGEST_LENGTH)?; + signer + } + + RsaSigningAlg::Ps512 => { + let mut signer = Signer::new(MessageDigest::sha512(), &self.private_key)?; + signer.set_rsa_padding(openssl::rsa::Padding::PKCS1_PSS)?; + signer.set_rsa_mgf1_md(MessageDigest::sha512())?; + signer.set_rsa_pss_saltlen(openssl::sign::RsaPssSaltlen::DIGEST_LENGTH)?; + signer + } + }; + + Ok(signer.sign_oneshot_to_vec(data)?) + } + + fn reserve_size(&self) -> usize { + 1024 + self.cert_chain_len + self.time_stamp_size + } + + fn cert_chain(&self) -> Result>, RawSignerError> { + let _openssl = OpenSslMutex::acquire()?; + + self.cert_chain + .iter() + .map(|cert| { + cert.to_der() + .map_err(|e| RawSignerError::OpenSslError(e.to_string())) + }) + .collect() + } + + fn alg(&self) -> SigningAlg { + match self.alg { + RsaSigningAlg::Ps256 => SigningAlg::Ps256, + RsaSigningAlg::Ps384 => SigningAlg::Ps384, + RsaSigningAlg::Ps512 => SigningAlg::Ps512, + } + } +} + +impl TimeStampProvider for RsaSigner { + fn time_stamp_service_url(&self) -> Option { + self.time_stamp_service_url.clone() + } +} diff --git a/internal/crypto/src/p1363.rs b/internal/crypto/src/p1363.rs index 4f806d10a..473f24e56 100644 --- a/internal/crypto/src/p1363.rs +++ b/internal/crypto/src/p1363.rs @@ -43,3 +43,62 @@ pub struct EcSigComps<'a> { pub r: &'a [u8], pub s: &'a [u8], } + +#[cfg(not(target_arch = "wasm32"))] // Maye will be used later? +use crate::{raw_signature::RawSignerError, SigningAlg}; + +#[cfg(not(target_arch = "wasm32"))] // Maye will be used later? +pub(crate) fn der_to_p1363(data: &[u8], alg: SigningAlg) -> Result, RawSignerError> { + // P1363 format: r | s + + let (_, p) = parse_ec_der_sig(data) + .map_err(|err| RawSignerError::InternalError(format!("invalid DER signature: {err}")))?; + + let mut r = const_hex::encode(p.r); + let mut s = const_hex::encode(p.s); + + let sig_len: usize = match alg { + SigningAlg::Es256 => 64, + SigningAlg::Es384 => 96, + SigningAlg::Es512 => 132, + _ => { + return Err(RawSignerError::InternalError( + "unsupported algorithm for der_to_p1363".to_string(), + )) + } + }; + + // Pad or truncate as needed. + let rp = if r.len() > sig_len { + let offset = r.len() - sig_len; + &r[offset..r.len()] + } else { + while r.len() != sig_len { + r.insert(0, '0'); + } + r.as_ref() + }; + + let sp = if s.len() > sig_len { + let offset = s.len() - sig_len; + &s[offset..s.len()] + } else { + while s.len() != sig_len { + s.insert(0, '0'); + } + s.as_ref() + }; + + if rp.len() != sig_len || rp.len() != sp.len() { + return Err(RawSignerError::InternalError( + "invalid signature components".to_string(), + )); + } + + // Merge r and s strings. + let new_sig = format!("{rp}{sp}"); + + // Convert back from hex string to byte array. + const_hex::decode(&new_sig) + .map_err(|e| RawSignerError::InternalError(format!("invalid signature components {e}"))) +} diff --git a/internal/crypto/src/raw_signature/mod.rs b/internal/crypto/src/raw_signature/mod.rs index 67e0510b5..b5a54e86e 100644 --- a/internal/crypto/src/raw_signature/mod.rs +++ b/internal/crypto/src/raw_signature/mod.rs @@ -13,6 +13,12 @@ //! Tools for working with raw signature algorithms. +pub(crate) mod signer; +pub use signer::{ + async_signer_from_cert_chain_and_private_key, signer_from_cert_chain_and_private_key, + AsyncRawSigner, RawSigner, RawSignerError, +}; + pub(crate) mod oids; mod validator; diff --git a/internal/crypto/src/raw_signature/signer.rs b/internal/crypto/src/raw_signature/signer.rs new file mode 100644 index 000000000..cca4f607d --- /dev/null +++ b/internal/crypto/src/raw_signature/signer.rs @@ -0,0 +1,269 @@ +// Copyright 2022 Adobe. All rights reserved. +// This file is licensed to you under the Apache License, +// Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0) +// or the MIT license (http://opensource.org/licenses/MIT), +// at your option. + +// Unless required by applicable law or agreed to in writing, +// this software is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR REPRESENTATIONS OF ANY KIND, either express or +// implied. See the LICENSE-MIT and LICENSE-APACHE files for the +// specific language governing permissions and limitations under +// each license. + +use async_trait::async_trait; +use thiserror::Error; + +use crate::{ + time_stamp::{AsyncTimeStampProvider, TimeStampError, TimeStampProvider}, + SigningAlg, +}; + +/// Implementations of the `RawSigner` trait generate a cryptographic signature +/// over an arbitrary byte array. +/// +/// If an implementation _can_ be asynchronous, that is preferred. +pub trait RawSigner: TimeStampProvider { + /// Return a raw signature over the original byte slice. + fn sign(&self, data: &[u8]) -> Result, RawSignerError>; + + /// Return the algorithm implemented by this signer. + fn alg(&self) -> SigningAlg; + + /// Return the signing certificate chain. + /// + /// Each certificate should be encoded in DER format and sequenced from + /// end-entity certificate to the outermost certificate authority. + fn cert_chain(&self) -> Result>, RawSignerError>; + + /// Return the size in bytes of the largest possible expected signature. + /// Signing will fail if the result of the [`sign`] function is larger + /// than this value. + /// + /// [`sign`]: Self::sign + fn reserve_size(&self) -> usize; + + /// Return an OCSP response for the signing certificate if available. + /// + /// By pre-querying the value for the signing certificate, the value can be + /// cached which will reduce load on the certificate authority, as + /// recommended by the C2PA spec. + fn ocsp_response(&self) -> Option> { + None + } +} + +/// Implementations of the `AsyncRawSigner` trait generate a cryptographic +/// signature over an arbitrary byte array. +/// +/// Use this trait only when the implementation must be asynchronous. +#[cfg_attr(target_arch = "wasm32", async_trait(?Send))] +#[cfg_attr(not(target_arch = "wasm32"), async_trait)] +pub trait AsyncRawSigner: Sync + AsyncTimeStampProvider { + /// Return a raw signature over the original byte slice. + async fn sign(&self, data: Vec) -> Result, RawSignerError>; + + /// Return the algorithm implemented by this signer. + fn alg(&self) -> SigningAlg; + + /// Return the signing certificate chain. + /// + /// Each certificate should be encoded in DER format and sequenced from + /// end-entity certificate to the outermost certificate authority. + fn cert_chain(&self) -> Result>, RawSignerError>; + + /// Return the size in bytes of the largest possible expected signature. + /// Signing will fail if the result of the [`sign`] function is larger + /// than this value. + /// + /// [`sign`]: Self::sign + fn reserve_size(&self) -> usize; + + /// Return an OCSP response for the signing certificate if available. + /// + /// By pre-querying the value for the signing certificate, the value can be + /// cached which will reduce load on the certificate authority, as + /// recommended by the C2PA spec. + async fn ocsp_response(&self) -> Option> { + None + } +} + +/// Describes errors that can be identified when generating a raw signature. +#[derive(Debug, Eq, Error, PartialEq)] +#[non_exhaustive] +pub enum RawSignerError { + /// The signing credentials are invalid. + #[error("invalid signing credentials ({0})")] + InvalidSigningCredentials(String), + + /// An I/O error occurred. This typically happens when loading + /// public/private key material from files. + /// + /// NOTE: We do not directly capture the I/O error itself because it + /// lacks an `Eq` implementation. Instead we capture the error description. + #[error("I/O error ({0})")] + IoError(String), + + /// An error was reported by the OpenSSL native code. + /// + /// NOTE: We do not directly capture the OpenSSL error itself because it + /// lacks an `Eq` implementation. Instead we capture the error description. + #[cfg(feature = "openssl")] + #[error("an error was reported by OpenSSL native code: {0}")] + OpenSslError(String), + + /// The OpenSSL native code mutex could not be acquired. + #[cfg(feature = "openssl")] + #[error(transparent)] + OpenSslMutexUnavailable(#[from] crate::openssl::OpenSslMutexUnavailable), + + /// An unexpected internal error occured while requesting the time stamp + /// response. + #[error("internal error ({0})")] + InternalError(String), +} + +impl From for RawSignerError { + fn from(err: std::io::Error) -> Self { + Self::IoError(err.to_string()) + } +} + +#[cfg(feature = "openssl")] +impl From for RawSignerError { + fn from(err: openssl::error::ErrorStack) -> Self { + Self::OpenSslError(err.to_string()) + } +} + +#[cfg(target_arch = "wasm32")] +impl From for RawSignerError { + fn from(err: crate::webcrypto::WasmCryptoError) -> Self { + match err { + crate::webcrypto::WasmCryptoError::UnknownContext => { + Self::InternalError("unknown WASM context".to_string()) + } + crate::webcrypto::WasmCryptoError::NoCryptoAvailable => { + Self::InternalError("WASM crypto unavailable".to_string()) + } + } + } +} + +/// Return a built-in [`RawSigner`] instance using the provided signing +/// certificate and private key. +/// +/// Which signers are available may vary depending on the platform and which +/// crate features were enabled. +/// +/// Returns `None` if the signing algorithm is unsupported. May return an `Err` +/// response if the certificate chain or private key are invalid. +#[allow(unused)] // arguments may or may not be used depending on crate features +pub fn signer_from_cert_chain_and_private_key( + cert_chain: &[u8], + private_key: &[u8], + alg: SigningAlg, + time_stamp_service_url: Option, +) -> Result, RawSignerError> { + #[cfg(feature = "openssl")] + { + return crate::openssl::signers::signer_from_cert_chain_and_private_key( + cert_chain, + private_key, + alg, + time_stamp_service_url, + ); + } + + #[cfg(all(target_arch = "wasm32", not(target_os = "wasi")))] + { + return crate::webcrypto::signers::signer_from_cert_chain_and_private_key( + cert_chain, + private_key, + alg, + time_stamp_service_url, + ); + } + + Err(RawSignerError::InternalError(format!( + "unsupported algorithm: {alg}" + ))) +} + +/// Return a built-in [`AsyncRawSigner`] instance using the provided signing +/// certificate and private key. +/// +/// Which signers are available may vary depending on the platform and which +/// crate features were enabled. +/// +/// Returns `None` if the signing algorithm is unsupported. May return an `Err` +/// response if the certificate chain or private key are invalid. +#[allow(unused)] // arguments may or may not be used depending on crate features +pub fn async_signer_from_cert_chain_and_private_key( + cert_chain: &[u8], + private_key: &[u8], + alg: SigningAlg, + time_stamp_service_url: Option, +) -> Result, RawSignerError> { + // TO DO: Preferentially use WASM-based signers, some of which are necessarily + // async. + + let sync_signer = signer_from_cert_chain_and_private_key( + cert_chain, + private_key, + alg, + time_stamp_service_url, + )?; + + Ok(Box::new(AsyncRawSignerWrapper(sync_signer))) +} + +struct AsyncRawSignerWrapper(Box); + +#[cfg_attr(target_arch = "wasm32", async_trait(?Send))] +#[cfg_attr(not(target_arch = "wasm32"), async_trait)] +impl AsyncRawSigner for AsyncRawSignerWrapper { + async fn sign(&self, data: Vec) -> Result, RawSignerError> { + self.0.sign(&data) + } + + fn alg(&self) -> SigningAlg { + self.0.alg() + } + + fn cert_chain(&self) -> Result>, RawSignerError> { + self.0.cert_chain() + } + + fn reserve_size(&self) -> usize { + self.0.reserve_size() + } + + async fn ocsp_response(&self) -> Option> { + self.0.ocsp_response() + } +} + +#[cfg_attr(not(target_arch = "wasm32"), async_trait)] +#[cfg_attr(target_arch = "wasm32", async_trait(?Send))] +impl AsyncTimeStampProvider for AsyncRawSignerWrapper { + fn time_stamp_service_url(&self) -> Option { + self.0.time_stamp_service_url() + } + + fn time_stamp_request_headers(&self) -> Option> { + self.0.time_stamp_request_headers() + } + + fn time_stamp_request_body(&self, message: &[u8]) -> Result, TimeStampError> { + self.0.time_stamp_request_body(message) + } + + async fn send_time_stamp_request( + &self, + message: &[u8], + ) -> Option, TimeStampError>> { + self.0.send_time_stamp_request(message) + } +} diff --git a/internal/crypto/src/tests/fixtures/raw_signature/ed25519.priv b/internal/crypto/src/tests/fixtures/raw_signature/ed25519.priv new file mode 100644 index 000000000..fda14a840 --- /dev/null +++ b/internal/crypto/src/tests/fixtures/raw_signature/ed25519.priv @@ -0,0 +1,3 @@ +-----BEGIN PRIVATE KEY----- +MC4CAQAwBQYDK2VwBCIEIL2+9INLPNSLH3STzKQJ3Wen9R6uPbIYOIKA2574YQ4O +-----END PRIVATE KEY----- diff --git a/internal/crypto/src/tests/fixtures/raw_signature/es256.priv b/internal/crypto/src/tests/fixtures/raw_signature/es256.priv new file mode 100644 index 000000000..5e59fcc5e --- /dev/null +++ b/internal/crypto/src/tests/fixtures/raw_signature/es256.priv @@ -0,0 +1,5 @@ +-----BEGIN PRIVATE KEY----- +MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgfNJBsaRLSeHizv0m +GL+gcn78QmtfLSm+n+qG9veC2W2hRANCAAQPaL6RkAkYkKU4+IryBSYxJM3h77sF +iMrbvbI8fG7w2Bbl9otNG/cch3DAw5rGAPV7NWkyl3QGuV/wt0MrAPDo +-----END PRIVATE KEY----- diff --git a/internal/crypto/src/tests/fixtures/raw_signature/es384.priv b/internal/crypto/src/tests/fixtures/raw_signature/es384.priv new file mode 100644 index 000000000..9dcc3af1c --- /dev/null +++ b/internal/crypto/src/tests/fixtures/raw_signature/es384.priv @@ -0,0 +1,6 @@ +-----BEGIN PRIVATE KEY----- +MIG2AgEAMBAGByqGSM49AgEGBSuBBAAiBIGeMIGbAgEBBDClh93nMdKl9Ujg71e3 +95QK1Z7OnmHrAYRv9B4ujlgWBoLQVtkoamQdizWQI/GvpAuhZANiAATY7kzZpbiB +azyKpJ3gb/6TZPMaNfJ+P5YeyhCynvzQtQT5l3HnJosPxUWYKTkdwqBWwe9P7QKl +KyX4PpQXVkJXYHffOGYOOKhLkJbc3JpYZzrxlZzY2FiVa1NQ/wOPXiU= +-----END PRIVATE KEY----- diff --git a/internal/crypto/src/tests/fixtures/raw_signature/es512.priv b/internal/crypto/src/tests/fixtures/raw_signature/es512.priv new file mode 100644 index 000000000..33cb2ad84 --- /dev/null +++ b/internal/crypto/src/tests/fixtures/raw_signature/es512.priv @@ -0,0 +1,8 @@ +-----BEGIN PRIVATE KEY----- +MIHuAgEAMBAGByqGSM49AgEGBSuBBAAjBIHWMIHTAgEBBEIBDCrjJaQ9kS2QVZHr +AoJMiCyk3YtvecNK913LsZ5alTlq01W13cEWVl3nprbCrCVzANiHWLjqUzfVW2oN +wT0rW5qhgYkDgYYABAHbhWCA1ywh5K74+Al75qoC2FLcqEmIJQoU4lNpy5lsPU59 +3LNjzmVUY8VTK8bK9SLnqhZC0sdijlqitmSOJg/VLwB9uYVTnwBmize3WEQmlEyz +nYJ0XdmCZYJcB4ke1aQKpHw1jNhHGSxEO9xn7+50v1EzEwRa0yM934mF3UxCV2c5 +nw== +-----END PRIVATE KEY----- diff --git a/internal/crypto/src/tests/openssl/mod.rs b/internal/crypto/src/tests/openssl/mod.rs index 27cb16350..1ce823fa2 100644 --- a/internal/crypto/src/tests/openssl/mod.rs +++ b/internal/crypto/src/tests/openssl/mod.rs @@ -12,4 +12,5 @@ // each license. mod ffi_mutex; +mod signers; mod validators; diff --git a/internal/crypto/src/tests/openssl/signers/ecdsa_signer.rs b/internal/crypto/src/tests/openssl/signers/ecdsa_signer.rs new file mode 100644 index 000000000..858418deb --- /dev/null +++ b/internal/crypto/src/tests/openssl/signers/ecdsa_signer.rs @@ -0,0 +1,176 @@ +// Copyright 2024 Adobe. All rights reserved. +// This file is licensed to you under the Apache License, +// Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0) +// or the MIT license (http://opensource.org/licenses/MIT), +// at your option. + +// Unless required by applicable law or agreed to in writing, +// this software is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR REPRESENTATIONS OF ANY KIND, either express or +// implied. See the LICENSE-MIT and LICENSE-APACHE files for the +// specific language governing permissions and limitations under +// each license. + +use openssl::x509::X509; + +use crate::{ + openssl::{signers::signer_from_cert_chain_and_private_key, validators::EcdsaValidator}, + raw_signature::{async_signer_from_cert_chain_and_private_key, RawSignatureValidator}, + SigningAlg, +}; + +#[test] +fn es256() { + let cert_chain = include_bytes!("../../fixtures/raw_signature/es256.pub"); + let private_key = include_bytes!("../../fixtures/raw_signature/es256.priv"); + + let signer = + signer_from_cert_chain_and_private_key(cert_chain, private_key, SigningAlg::Es256, None) + .unwrap(); + + let data = b"some sample content to sign"; + let signature = signer.sign(data).unwrap(); + + println!("signature len = {}", signature.len()); + assert!(signature.len() <= signer.reserve_size()); + + let cert = X509::from_pem(cert_chain).unwrap(); + let pub_key = cert.public_key().unwrap(); + let pub_key = pub_key.public_key_to_der().unwrap(); + + EcdsaValidator::Es256 + .validate(&signature, data, &pub_key) + .unwrap(); +} + +#[actix::test] +async fn es256_async() { + let cert_chain = include_bytes!("../../fixtures/raw_signature/es256.pub"); + let private_key = include_bytes!("../../fixtures/raw_signature/es256.priv"); + + let signer = async_signer_from_cert_chain_and_private_key( + cert_chain, + private_key, + SigningAlg::Es256, + None, + ) + .unwrap(); + + let data = b"some sample content to sign"; + let signature = signer.sign(data.to_vec()).await.unwrap(); + + println!("signature len = {}", signature.len()); + assert!(signature.len() <= signer.reserve_size()); + + let cert = X509::from_pem(cert_chain).unwrap(); + let pub_key = cert.public_key().unwrap(); + let pub_key = pub_key.public_key_to_der().unwrap(); + + EcdsaValidator::Es256 + .validate(&signature, data, &pub_key) + .unwrap(); +} + +#[test] +fn es384() { + let cert_chain = include_bytes!("../../fixtures/raw_signature/es384.pub"); + let private_key = include_bytes!("../../fixtures/raw_signature/es384.priv"); + + let signer = + signer_from_cert_chain_and_private_key(cert_chain, private_key, SigningAlg::Es384, None) + .unwrap(); + + let data = b"some sample content to sign"; + let signature = signer.sign(data).unwrap(); + + println!("signature len = {}", signature.len()); + assert!(signature.len() <= signer.reserve_size()); + + let cert = X509::from_pem(cert_chain).unwrap(); + let pub_key = cert.public_key().unwrap(); + let pub_key = pub_key.public_key_to_der().unwrap(); + + EcdsaValidator::Es384 + .validate(&signature, data, &pub_key) + .unwrap(); +} + +#[actix::test] +async fn es384_async() { + let cert_chain = include_bytes!("../../fixtures/raw_signature/es384.pub"); + let private_key = include_bytes!("../../fixtures/raw_signature/es384.priv"); + + let signer = async_signer_from_cert_chain_and_private_key( + cert_chain, + private_key, + SigningAlg::Es384, + None, + ) + .unwrap(); + + let data = b"some sample content to sign"; + let signature = signer.sign(data.to_vec()).await.unwrap(); + + println!("signature len = {}", signature.len()); + assert!(signature.len() <= signer.reserve_size()); + + let cert = X509::from_pem(cert_chain).unwrap(); + let pub_key = cert.public_key().unwrap(); + let pub_key = pub_key.public_key_to_der().unwrap(); + + EcdsaValidator::Es384 + .validate(&signature, data, &pub_key) + .unwrap(); +} + +#[test] +fn es512() { + let cert_chain = include_bytes!("../../fixtures/raw_signature/es512.pub"); + let private_key = include_bytes!("../../fixtures/raw_signature/es512.priv"); + + let signer = + signer_from_cert_chain_and_private_key(cert_chain, private_key, SigningAlg::Es512, None) + .unwrap(); + + let data = b"some sample content to sign"; + let signature = signer.sign(data).unwrap(); + + println!("signature len = {}", signature.len()); + assert!(signature.len() <= signer.reserve_size()); + + let cert = X509::from_pem(cert_chain).unwrap(); + let pub_key = cert.public_key().unwrap(); + let pub_key = pub_key.public_key_to_der().unwrap(); + + EcdsaValidator::Es512 + .validate(&signature, data, &pub_key) + .unwrap(); +} + +#[actix::test] +async fn es512_async() { + let cert_chain = include_bytes!("../../fixtures/raw_signature/es512.pub"); + let private_key = include_bytes!("../../fixtures/raw_signature/es512.priv"); + + let signer = async_signer_from_cert_chain_and_private_key( + cert_chain, + private_key, + SigningAlg::Es512, + None, + ) + .unwrap(); + + let data = b"some sample content to sign"; + let signature = signer.sign(data.to_vec()).await.unwrap(); + + println!("signature len = {}", signature.len()); + assert!(signature.len() <= signer.reserve_size()); + + let cert = X509::from_pem(cert_chain).unwrap(); + let pub_key = cert.public_key().unwrap(); + let pub_key = pub_key.public_key_to_der().unwrap(); + + EcdsaValidator::Es512 + .validate(&signature, data, &pub_key) + .unwrap(); +} diff --git a/internal/crypto/src/tests/openssl/signers/ed25519_signer.rs b/internal/crypto/src/tests/openssl/signers/ed25519_signer.rs new file mode 100644 index 000000000..d7a2de19f --- /dev/null +++ b/internal/crypto/src/tests/openssl/signers/ed25519_signer.rs @@ -0,0 +1,72 @@ +// Copyright 2024 Adobe. All rights reserved. +// This file is licensed to you under the Apache License, +// Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0) +// or the MIT license (http://opensource.org/licenses/MIT), +// at your option. + +// Unless required by applicable law or agreed to in writing, +// this software is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR REPRESENTATIONS OF ANY KIND, either express or +// implied. See the LICENSE-MIT and LICENSE-APACHE files for the +// specific language governing permissions and limitations under +// each license. + +use openssl::x509::X509; + +use crate::{ + openssl::{signers::signer_from_cert_chain_and_private_key, validators::Ed25519Validator}, + raw_signature::{async_signer_from_cert_chain_and_private_key, RawSignatureValidator}, + SigningAlg, +}; + +#[test] +fn ed25519() { + let cert_chain = include_bytes!("../../fixtures/raw_signature/ed25519.pub"); + let private_key = include_bytes!("../../fixtures/raw_signature/ed25519.priv"); + + let signer = + signer_from_cert_chain_and_private_key(cert_chain, private_key, SigningAlg::Ed25519, None) + .unwrap(); + + let data = b"some sample content to sign"; + let signature = signer.sign(data).unwrap(); + + println!("signature len = {}", signature.len()); + assert!(signature.len() <= signer.reserve_size()); + + let cert = X509::from_pem(cert_chain).unwrap(); + let pub_key = cert.public_key().unwrap(); + let pub_key = pub_key.public_key_to_der().unwrap(); + + Ed25519Validator {} + .validate(&signature, data, &pub_key) + .unwrap(); +} + +#[actix::test] +async fn ed25519_async() { + let cert_chain = include_bytes!("../../fixtures/raw_signature/ed25519.pub"); + let private_key = include_bytes!("../../fixtures/raw_signature/ed25519.priv"); + + let signer = async_signer_from_cert_chain_and_private_key( + cert_chain, + private_key, + SigningAlg::Ed25519, + None, + ) + .unwrap(); + + let data = b"some sample content to sign"; + let signature = signer.sign(data.to_vec()).await.unwrap(); + + println!("signature len = {}", signature.len()); + assert!(signature.len() <= signer.reserve_size()); + + let cert = X509::from_pem(cert_chain).unwrap(); + let pub_key = cert.public_key().unwrap(); + let pub_key = pub_key.public_key_to_der().unwrap(); + + Ed25519Validator {} + .validate(&signature, data, &pub_key) + .unwrap(); +} diff --git a/internal/crypto/src/tests/openssl/signers/mod.rs b/internal/crypto/src/tests/openssl/signers/mod.rs new file mode 100644 index 000000000..c6d556b09 --- /dev/null +++ b/internal/crypto/src/tests/openssl/signers/mod.rs @@ -0,0 +1,16 @@ +// Copyright 2024 Adobe. All rights reserved. +// This file is licensed to you under the Apache License, +// Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0) +// or the MIT license (http://opensource.org/licenses/MIT), +// at your option. + +// Unless required by applicable law or agreed to in writing, +// this software is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR REPRESENTATIONS OF ANY KIND, either express or +// implied. See the LICENSE-MIT and LICENSE-APACHE files for the +// specific language governing permissions and limitations under +// each license. + +mod ecdsa_signer; +mod ed25519_signer; +mod rsa_signer; diff --git a/internal/crypto/src/tests/openssl/signers/rsa_signer.rs b/internal/crypto/src/tests/openssl/signers/rsa_signer.rs new file mode 100644 index 000000000..74ae59f35 --- /dev/null +++ b/internal/crypto/src/tests/openssl/signers/rsa_signer.rs @@ -0,0 +1,176 @@ +// Copyright 2024 Adobe. All rights reserved. +// This file is licensed to you under the Apache License, +// Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0) +// or the MIT license (http://opensource.org/licenses/MIT), +// at your option. + +// Unless required by applicable law or agreed to in writing, +// this software is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR REPRESENTATIONS OF ANY KIND, either express or +// implied. See the LICENSE-MIT and LICENSE-APACHE files for the +// specific language governing permissions and limitations under +// each license. + +use openssl::x509::X509; + +use crate::{ + openssl::{signers::signer_from_cert_chain_and_private_key, validators::RsaValidator}, + raw_signature::{async_signer_from_cert_chain_and_private_key, RawSignatureValidator}, + SigningAlg, +}; + +#[test] +fn ps256() { + let cert_chain = include_bytes!("../../fixtures/raw_signature/ps256.pub"); + let private_key = include_bytes!("../../fixtures/raw_signature/ps256.priv"); + + let signer = + signer_from_cert_chain_and_private_key(cert_chain, private_key, SigningAlg::Ps256, None) + .unwrap(); + + let data = b"some sample content to sign"; + let signature = signer.sign(data).unwrap(); + + println!("signature len = {}", signature.len()); + assert!(signature.len() <= signer.reserve_size()); + + let cert = X509::from_pem(cert_chain).unwrap(); + let pub_key = cert.public_key().unwrap(); + let pub_key = pub_key.public_key_to_der().unwrap(); + + RsaValidator::Ps256 + .validate(&signature, data, &pub_key) + .unwrap(); +} + +#[actix::test] +async fn ps256_async() { + let cert_chain = include_bytes!("../../fixtures/raw_signature/ps256.pub"); + let private_key = include_bytes!("../../fixtures/raw_signature/ps256.priv"); + + let signer = async_signer_from_cert_chain_and_private_key( + cert_chain, + private_key, + SigningAlg::Ps256, + None, + ) + .unwrap(); + + let data = b"some sample content to sign"; + let signature = signer.sign(data.to_vec()).await.unwrap(); + + println!("signature len = {}", signature.len()); + assert!(signature.len() <= signer.reserve_size()); + + let cert = X509::from_pem(cert_chain).unwrap(); + let pub_key = cert.public_key().unwrap(); + let pub_key = pub_key.public_key_to_der().unwrap(); + + RsaValidator::Ps256 + .validate(&signature, data, &pub_key) + .unwrap(); +} + +#[test] +fn ps384() { + let cert_chain = include_bytes!("../../fixtures/raw_signature/ps384.pub"); + let private_key = include_bytes!("../../fixtures/raw_signature/ps384.priv"); + + let signer = + signer_from_cert_chain_and_private_key(cert_chain, private_key, SigningAlg::Ps384, None) + .unwrap(); + + let data = b"some sample content to sign"; + let signature = signer.sign(data).unwrap(); + + println!("signature len = {}", signature.len()); + assert!(signature.len() <= signer.reserve_size()); + + let cert = X509::from_pem(cert_chain).unwrap(); + let pub_key = cert.public_key().unwrap(); + let pub_key = pub_key.public_key_to_der().unwrap(); + + RsaValidator::Ps384 + .validate(&signature, data, &pub_key) + .unwrap(); +} + +#[actix::test] +async fn ps384_async() { + let cert_chain = include_bytes!("../../fixtures/raw_signature/ps384.pub"); + let private_key = include_bytes!("../../fixtures/raw_signature/ps384.priv"); + + let signer = async_signer_from_cert_chain_and_private_key( + cert_chain, + private_key, + SigningAlg::Ps384, + None, + ) + .unwrap(); + + let data = b"some sample content to sign"; + let signature = signer.sign(data.to_vec()).await.unwrap(); + + println!("signature len = {}", signature.len()); + assert!(signature.len() <= signer.reserve_size()); + + let cert = X509::from_pem(cert_chain).unwrap(); + let pub_key = cert.public_key().unwrap(); + let pub_key = pub_key.public_key_to_der().unwrap(); + + RsaValidator::Ps384 + .validate(&signature, data, &pub_key) + .unwrap(); +} + +#[test] +fn ps512() { + let cert_chain = include_bytes!("../../fixtures/raw_signature/ps512.pub"); + let private_key = include_bytes!("../../fixtures/raw_signature/ps512.priv"); + + let signer = + signer_from_cert_chain_and_private_key(cert_chain, private_key, SigningAlg::Ps512, None) + .unwrap(); + + let data = b"some sample content to sign"; + let signature = signer.sign(data).unwrap(); + + println!("signature len = {}", signature.len()); + assert!(signature.len() <= signer.reserve_size()); + + let cert = X509::from_pem(cert_chain).unwrap(); + let pub_key = cert.public_key().unwrap(); + let pub_key = pub_key.public_key_to_der().unwrap(); + + RsaValidator::Ps512 + .validate(&signature, data, &pub_key) + .unwrap(); +} + +#[actix::test] +async fn ps512_async() { + let cert_chain = include_bytes!("../../fixtures/raw_signature/ps512.pub"); + let private_key = include_bytes!("../../fixtures/raw_signature/ps512.priv"); + + let signer = async_signer_from_cert_chain_and_private_key( + cert_chain, + private_key, + SigningAlg::Ps512, + None, + ) + .unwrap(); + + let data = b"some sample content to sign"; + let signature = signer.sign(data.to_vec()).await.unwrap(); + + println!("signature len = {}", signature.len()); + assert!(signature.len() <= signer.reserve_size()); + + let cert = X509::from_pem(cert_chain).unwrap(); + let pub_key = cert.public_key().unwrap(); + let pub_key = pub_key.public_key_to_der().unwrap(); + + RsaValidator::Ps512 + .validate(&signature, data, &pub_key) + .unwrap(); +} diff --git a/internal/crypto/src/tests/webcrypto/mod.rs b/internal/crypto/src/tests/webcrypto/mod.rs index c1bbf2757..a2a612f0f 100644 --- a/internal/crypto/src/tests/webcrypto/mod.rs +++ b/internal/crypto/src/tests/webcrypto/mod.rs @@ -11,5 +11,6 @@ // specific language governing permissions and limitations under // each license. +mod signers; mod validators; mod window_or_worker; diff --git a/internal/crypto/src/tests/webcrypto/signers/ed25519_signer.rs b/internal/crypto/src/tests/webcrypto/signers/ed25519_signer.rs new file mode 100644 index 000000000..9770f6673 --- /dev/null +++ b/internal/crypto/src/tests/webcrypto/signers/ed25519_signer.rs @@ -0,0 +1,42 @@ +// Copyright 2024 Adobe. All rights reserved. +// This file is licensed to you under the Apache License, +// Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0) +// or the MIT license (http://opensource.org/licenses/MIT), +// at your option. + +// Unless required by applicable law or agreed to in writing, +// this software is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR REPRESENTATIONS OF ANY KIND, either express or +// implied. See the LICENSE-MIT and LICENSE-APACHE files for the +// specific language governing permissions and limitations under +// each license. + +use wasm_bindgen_test::wasm_bindgen_test; + +use crate::{ + raw_signature::{signer_from_cert_chain_and_private_key, RawSignatureValidator}, + webcrypto::validators::Ed25519Validator, + SigningAlg, +}; + +#[wasm_bindgen_test] +fn ed25519() { + let cert_chain = include_bytes!("../../fixtures/raw_signature/ed25519.pub"); + let private_key = include_bytes!("../../fixtures/raw_signature/ed25519.priv"); + + let signer = + signer_from_cert_chain_and_private_key(cert_chain, private_key, SigningAlg::Ed25519, None) + .unwrap(); + + let data = b"some sample content to sign"; + let signature = signer.sign(data).unwrap(); + + println!("signature len = {}", signature.len()); + assert!(signature.len() <= signer.reserve_size()); + + let pub_key = include_bytes!("../../fixtures/raw_signature/ed25519.pub_key"); + + Ed25519Validator {} + .validate(&signature, data, pub_key) + .unwrap(); +} diff --git a/internal/crypto/src/tests/webcrypto/signers/mod.rs b/internal/crypto/src/tests/webcrypto/signers/mod.rs new file mode 100644 index 000000000..577cd72b2 --- /dev/null +++ b/internal/crypto/src/tests/webcrypto/signers/mod.rs @@ -0,0 +1,14 @@ +// Copyright 2024 Adobe. All rights reserved. +// This file is licensed to you under the Apache License, +// Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0) +// or the MIT license (http://opensource.org/licenses/MIT), +// at your option. + +// Unless required by applicable law or agreed to in writing, +// this software is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR REPRESENTATIONS OF ANY KIND, either express or +// implied. See the LICENSE-MIT and LICENSE-APACHE files for the +// specific language governing permissions and limitations under +// each license. + +mod ed25519_signer; diff --git a/internal/crypto/src/webcrypto/mod.rs b/internal/crypto/src/webcrypto/mod.rs index fb51e2d32..de9ae2b80 100644 --- a/internal/crypto/src/webcrypto/mod.rs +++ b/internal/crypto/src/webcrypto/mod.rs @@ -25,6 +25,7 @@ pub use async_validators::{ AsyncRawSignatureValidator, }; +pub(crate) mod signers; pub mod validators; mod window_or_worker; diff --git a/internal/crypto/src/webcrypto/signers/ed25519_signer.rs b/internal/crypto/src/webcrypto/signers/ed25519_signer.rs new file mode 100644 index 000000000..a7d3871a4 --- /dev/null +++ b/internal/crypto/src/webcrypto/signers/ed25519_signer.rs @@ -0,0 +1,101 @@ +// Copyright 2024 Adobe. All rights reserved. +// This file is licensed to you under the Apache License, +// Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0) +// or the MIT license (http://opensource.org/licenses/MIT), +// at your option. + +// Unless required by applicable law or agreed to in writing, +// this software is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR REPRESENTATIONS OF ANY KIND, either express or +// implied. See the LICENSE-MIT and LICENSE-APACHE files for the +// specific language governing permissions and limitations under +// each license. + +use ed25519_dalek::{pkcs8::DecodePrivateKey, SigningKey}; +use x509_parser::{error::PEMError, pem::Pem}; + +use crate::{ + raw_signature::{RawSigner, RawSignerError}, + time_stamp::TimeStampProvider, + SigningAlg, +}; + +/// Implements `RawSigner` trait using `ed25519_dalek` crate's implementation of +/// Edwards Curve encryption. +pub struct Ed25519Signer { + #[allow(dead_code)] + cert_chain: Vec>, + cert_chain_len: usize, + + signing_key: SigningKey, + + time_stamp_service_url: Option, + time_stamp_size: usize, +} + +impl Ed25519Signer { + pub(crate) fn from_cert_chain_and_private_key( + cert_chain: &[u8], + private_key: &[u8], + time_stamp_service_url: Option, + ) -> Result { + let cert_chain = Pem::iter_from_buffer(cert_chain) + .map(|r| match r { + Ok(pem) => Ok(pem.contents), + Err(e) => Err(e), + }) + .collect::>, PEMError>>() + .map_err(|e| RawSignerError::InvalidSigningCredentials(e.to_string()))?; + + let cert_chain_len = cert_chain.len(); + + let private_key_pem = std::str::from_utf8(private_key).map_err(|e| { + RawSignerError::InvalidSigningCredentials(format!("invalid private key: {e}")) + })?; + + let signing_key = SigningKey::from_pkcs8_pem(private_key_pem).map_err(|e| { + RawSignerError::InvalidSigningCredentials(format!("invalid private key: {e}")) + })?; + + Ok(Ed25519Signer { + cert_chain, + cert_chain_len, + + signing_key, + + time_stamp_service_url, + time_stamp_size: 10000, + // TO DO: Call out to time stamp service to get actual time stamp and use that size? + }) + } +} + +impl RawSigner for Ed25519Signer { + fn sign(&self, data: &[u8]) -> Result, RawSignerError> { + use ed25519_dalek::Signer; + + Ok(self + .signing_key + .try_sign(data) + .map_err(|e| RawSignerError::InternalError(format!("signature error: {e}")))? + .to_vec()) + } + + fn alg(&self) -> SigningAlg { + SigningAlg::Ed25519 + } + + fn reserve_size(&self) -> usize { + 1024 + self.cert_chain_len + self.time_stamp_size + } + + fn cert_chain(&self) -> Result>, RawSignerError> { + Ok(self.cert_chain.clone()) + } +} + +impl TimeStampProvider for Ed25519Signer { + fn time_stamp_service_url(&self) -> Option { + self.time_stamp_service_url.clone() + } +} diff --git a/internal/crypto/src/webcrypto/signers/mod.rs b/internal/crypto/src/webcrypto/signers/mod.rs new file mode 100644 index 000000000..134f3d664 --- /dev/null +++ b/internal/crypto/src/webcrypto/signers/mod.rs @@ -0,0 +1,48 @@ +// Copyright 2024 Adobe. All rights reserved. +// This file is licensed to you under the Apache License, +// Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0) +// or the MIT license (http://opensource.org/licenses/MIT), +// at your option. + +// Unless required by applicable law or agreed to in writing, +// this software is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR REPRESENTATIONS OF ANY KIND, either express or +// implied. See the LICENSE-MIT and LICENSE-APACHE files for the +// specific language governing permissions and limitations under +// each license. + +use crate::{ + raw_signature::{RawSigner, RawSignerError}, + SigningAlg, +}; + +mod ed25519_signer; + +/// Return a built-in [`RawSigner`] instance using the provided signing +/// certificate and private key. +/// +/// Which signers are available may vary depending on the platform and which +/// crate features were enabled. +/// +/// Returns `None` if the signing algorithm is unsupported. May return an `Err` +/// response if the certificate chain or private key are invalid. +pub(crate) fn signer_from_cert_chain_and_private_key( + cert_chain: &[u8], + private_key: &[u8], + alg: SigningAlg, + time_stamp_service_url: Option, +) -> Result, RawSignerError> { + match alg { + SigningAlg::Ed25519 => Ok(Box::new( + ed25519_signer::Ed25519Signer::from_cert_chain_and_private_key( + cert_chain, + private_key, + time_stamp_service_url, + )?, + )), + + _ => Err(RawSignerError::InternalError(format!( + "unsupported algorithm: {alg}" + ))), + } +} diff --git a/sdk/Cargo.toml b/sdk/Cargo.toml index a5f2f490a..324ea93e2 100644 --- a/sdk/Cargo.toml +++ b/sdk/Cargo.toml @@ -28,7 +28,6 @@ rustdoc-args = ["--cfg", "docsrs"] [features] default = ["v1_api"] add_thumbnails = ["image"] -psxxx_ocsp_stapling_experimental = [] file_io = ["openssl_sign"] serialize_thumbnails = [] no_interleaved_io = ["file_io"] diff --git a/sdk/src/asset_handlers/c2pa_io.rs b/sdk/src/asset_handlers/c2pa_io.rs index 400122525..4dca3475e 100644 --- a/sdk/src/asset_handlers/c2pa_io.rs +++ b/sdk/src/asset_handlers/c2pa_io.rs @@ -146,13 +146,17 @@ pub mod tests { #![allow(clippy::expect_used)] #![allow(clippy::unwrap_used)] + use c2pa_crypto::SigningAlg; use c2pa_status_tracker::OneShotStatusTracker; use tempfile::tempdir; use super::{AssetIO, C2paIO, CAIReader, CAIWriter}; use crate::{ store::Store, - utils::test::{fixture_path, temp_dir_path, temp_signer}, + utils::{ + test::{fixture_path, temp_dir_path}, + test_signer::test_signer, + }, }; #[test] @@ -171,7 +175,7 @@ pub mod tests { let store = Store::load_from_asset(&temp_path, false, &mut OneShotStatusTracker::default()) .expect("loading store"); - let signer = temp_signer(); + let signer = test_signer(SigningAlg::Ps256); let manifest2 = store.to_jumbf(signer.as_ref()).expect("to_jumbf"); assert_eq!(&manifest, &manifest2); diff --git a/sdk/src/builder.rs b/sdk/src/builder.rs index beff52879..8ac8aa072 100644 --- a/sdk/src/builder.rs +++ b/sdk/src/builder.rs @@ -1083,6 +1083,7 @@ mod tests { #![allow(clippy::unwrap_used)] use std::io::Cursor; + use c2pa_crypto::SigningAlg; use serde_json::json; #[cfg(target_arch = "wasm32")] use wasm_bindgen_test::*; @@ -1092,7 +1093,7 @@ mod tests { assertions::BoxHash, asset_handlers::jpeg_io::JpegIO, hash_stream_by_alg, - utils::test::{temp_signer, write_jpeg_placeholder_stream}, + utils::{test::write_jpeg_placeholder_stream, test_signer::test_signer}, Reader, }; @@ -1305,7 +1306,7 @@ mod tests { let mut _builder = Builder::from_archive(&mut zipped).unwrap(); // sign and write to the output stream - let signer = temp_signer(); + let signer = test_signer(SigningAlg::Ps256); builder .sign(signer.as_ref(), format, &mut source, &mut dest) .unwrap(); @@ -1337,7 +1338,7 @@ mod tests { .unwrap(); // sign and write to the output stream - let signer = temp_signer(); + let signer = test_signer(SigningAlg::Ps256); builder.sign_file(signer.as_ref(), source, &dest).unwrap(); // read and validate the signed manifest store @@ -1389,7 +1390,7 @@ mod tests { .unwrap(); // sign and write to the output stream - let signer = temp_signer(); + let signer = test_signer(SigningAlg::Ps256); builder .sign(signer.as_ref(), format, &mut source, &mut dest) .unwrap(); @@ -1472,7 +1473,7 @@ mod tests { .unwrap(); // sign the ManifestStoreBuilder and write it to the output stream - let signer = temp_signer(); + let signer = test_signer(SigningAlg::Ps256); let manifest_data = builder .sign(signer.as_ref(), "image/jpeg", &mut source, &mut dest) .unwrap(); @@ -1496,7 +1497,7 @@ mod tests { const CLOUD_IMAGE: &[u8] = include_bytes!("../tests/fixtures/cloud.jpg"); let mut input_stream = Cursor::new(CLOUD_IMAGE); - let signer = temp_signer(); + let signer = test_signer(SigningAlg::Ps256); let mut builder = Builder::from_json(&simple_manifest()).unwrap(); @@ -1569,7 +1570,7 @@ mod tests { builder.add_assertion(labels::BOX_HASH, &box_hash).unwrap(); - let signer = crate::utils::test::temp_async_signer(); + let signer = crate::utils::test_signer::async_test_signer(SigningAlg::Ed25519); let manifest_bytes = builder .sign_box_hashed_embeddable_async(signer.as_ref(), "image/jpeg") @@ -1633,7 +1634,7 @@ mod tests { let mut builder = Builder::from_archive(&mut zipped).unwrap(); // sign the ManifestStoreBuilder and write it to the output stream - let signer = temp_signer(); + let signer = test_signer(SigningAlg::Ps256); let _manifest_data = builder .sign(signer.as_ref(), "image/jpeg", &mut source, &mut dest) .unwrap(); @@ -1809,7 +1810,7 @@ mod tests { // convert buffer to cursor with Read/Write/Seek capability let mut input = Cursor::new(image.to_vec()); - let signer = temp_signer(); + let signer = test_signer(SigningAlg::Ps256); // Embed a manifest using the signer. let mut output = Cursor::new(Vec::new()); builder diff --git a/sdk/src/callback_signer.rs b/sdk/src/callback_signer.rs index 494e0851a..52f952949 100644 --- a/sdk/src/callback_signer.rs +++ b/sdk/src/callback_signer.rs @@ -16,12 +16,10 @@ //! The `callback_signer` module provides a way to obtain a [`Signer`] or [`AsyncSigner`] //! using a callback and public signing certificates. +use async_trait::async_trait; use c2pa_crypto::SigningAlg; -use crate::{ - error::{Error, Result}, - AsyncSigner, Signer, -}; +use crate::{AsyncSigner, Error, Result, Signer}; /// Defines a callback function interface for a [`CallbackSigner`]. /// @@ -54,7 +52,6 @@ pub struct CallbackSigner { } unsafe impl Send for CallbackSigner {} - unsafe impl Sync for CallbackSigner {} impl CallbackSigner { @@ -66,6 +63,7 @@ impl CallbackSigner { { let certs = certs.into(); let reserve_size = 10000 + certs.len(); + Self { context: std::ptr::null(), callback: Box::new(callback), @@ -114,13 +112,14 @@ impl CallbackSigner { // Parse the PEM data to get the private key let pem = parse(private_key).map_err(|e| Error::OtherError(Box::new(e)))?; + // For Ed25519, the key is 32 bytes long, so we skip the first 16 bytes of the PEM data let key_bytes = &pem.contents()[16..]; let signing_key = SigningKey::try_from(key_bytes).map_err(|e| Error::OtherError(Box::new(e)))?; + // Sign the data let signature: Signature = signing_key.sign(data); - Ok(signature.to_bytes().to_vec()) } } @@ -162,11 +161,8 @@ impl Signer for CallbackSigner { } } -use async_trait::async_trait; - #[cfg_attr(target_arch = "wasm32", async_trait(?Send))] #[cfg_attr(not(target_arch = "wasm32"), async_trait)] -// I'm not sure if this is useful since the callback is still synchronous. impl AsyncSigner for CallbackSigner { async fn sign(&self, data: Vec) -> Result> { (self.callback)(self.context, &data) diff --git a/sdk/src/cose_sign.rs b/sdk/src/cose_sign.rs index 81dccd2f3..ddb4d15b5 100644 --- a/sdk/src/cose_sign.rs +++ b/sdk/src/cose_sign.rs @@ -35,7 +35,6 @@ use crate::{ cose_timestamp_countersign, cose_timestamp_countersign_async, make_cose_timestamp, }, trust_handler::TrustHandlerConfig, - utils::sig_utils::der_to_p1363, AsyncSigner, Error, Result, Signer, }; @@ -206,6 +205,63 @@ pub(crate) fn cose_sign(signer: &dyn Signer, data: &[u8], box_size: usize) -> Re Ok(c2pa_sig_data) } +fn der_to_p1363(data: &[u8], alg: SigningAlg) -> Result> { + // P1363 format: r | s + + let (_, p) = parse_ec_der_sig(data).map_err(|_err| Error::InvalidEcdsaSignature)?; + + let mut r = extfmt::Hexlify(p.r).to_string(); + let mut s = extfmt::Hexlify(p.s).to_string(); + + let sig_len: usize = match alg { + SigningAlg::Es256 => 64, + SigningAlg::Es384 => 96, + SigningAlg::Es512 => 132, + _ => return Err(Error::UnsupportedType), + }; + + // pad or truncate as needed + let rp = if r.len() > sig_len { + // truncate + let offset = r.len() - sig_len; + &r[offset..r.len()] + } else { + // pad + while r.len() != sig_len { + r.insert(0, '0'); + } + r.as_ref() + }; + + let sp = if s.len() > sig_len { + // truncate + let offset = s.len() - sig_len; + &s[offset..s.len()] + } else { + // pad + while s.len() != sig_len { + s.insert(0, '0'); + } + s.as_ref() + }; + + if rp.len() != sig_len || rp.len() != sp.len() { + return Err(Error::InvalidEcdsaSignature); + } + + // merge r and s strings + let mut new_sig = rp.to_string(); + new_sig.push_str(sp); + + // convert back from hex string to byte array + (0..new_sig.len()) + .step_by(2) + .map(|i| { + u8::from_str_radix(&new_sig[i..i + 2], 16).map_err(|_err| Error::InvalidEcdsaSignature) + }) + .collect() +} + #[async_generic(async_signature(signer: &dyn AsyncSigner, data: &[u8], alg: SigningAlg))] fn build_headers(signer: &dyn Signer, data: &[u8], alg: SigningAlg) -> Result<(Header, Header)> { let mut protected_h = match alg { @@ -357,9 +413,12 @@ fn pad_cose_sig(sign1: &mut CoseSign1, end_size: usize) -> Result> { #[cfg(test)] mod tests { #![allow(clippy::unwrap_used)] + use c2pa_crypto::SigningAlg; use super::sign_claim; - use crate::{claim::Claim, utils::test::temp_signer}; + #[cfg(not(target_arch = "wasm32"))] + use crate::utils::test_signer::async_test_signer; + use crate::{claim::Claim, utils::test_signer::test_signer, Result, Signer}; #[test] fn test_sign_claim() { @@ -368,7 +427,7 @@ mod tests { let claim_bytes = claim.data().unwrap(); - let signer = temp_signer(); + let signer = test_signer(SigningAlg::Ps256); let box_size = signer.reserve_size(); let cose_sign1 = sign_claim(&claim_bytes, signer.as_ref(), box_size).unwrap(); @@ -380,16 +439,16 @@ mod tests { #[cfg(feature = "openssl")] #[actix::test] async fn test_sign_claim_async() { - use crate::{ - cose_sign::sign_claim_async, openssl::AsyncSignerAdapter, AsyncSigner, SigningAlg, - }; + use c2pa_crypto::SigningAlg; + + use crate::{cose_sign::sign_claim_async, AsyncSigner}; let mut claim = Claim::new("extern_sign_test", Some("contentauth")); claim.build().unwrap(); let claim_bytes = claim.data().unwrap(); - let signer = AsyncSignerAdapter::new(SigningAlg::Ps256); + let signer = async_test_signer(SigningAlg::Ps256); let box_size = signer.reserve_size(); let cose_sign1 = sign_claim_async(&claim_bytes, &signer, box_size) @@ -407,8 +466,8 @@ mod tests { } } - impl crate::Signer for BogusSigner { - fn sign(&self, _data: &[u8]) -> crate::error::Result> { + impl Signer for BogusSigner { + fn sign(&self, _data: &[u8]) -> Result> { eprintln!("Canary, canary, please cause this deploy to fail!"); Ok(b"totally bogus signature".to_vec()) } @@ -417,7 +476,7 @@ mod tests { c2pa_crypto::SigningAlg::Ps256 } - fn certs(&self) -> crate::error::Result>> { + fn certs(&self) -> Result>> { let cert_vec: Vec = Vec::new(); let certs = vec![cert_vec]; Ok(certs) diff --git a/sdk/src/cose_validator.rs b/sdk/src/cose_validator.rs index 30f5767a1..19f01a6a7 100644 --- a/sdk/src/cose_validator.rs +++ b/sdk/src/cose_validator.rs @@ -1360,11 +1360,12 @@ fn gt_to_datetime( #[cfg(feature = "openssl_sign")] #[cfg(test)] pub mod tests { + use c2pa_crypto::SigningAlg; use c2pa_status_tracker::DetailedStatusTracker; use sha2::digest::generic_array::sequence::Shorten; use super::*; - use crate::{openssl::temp_signer, signer::ConfigurableSigner, Signer, SigningAlg}; + use crate::{utils::test_signer::test_signer, Signer}; #[test] #[cfg(feature = "file_io")] @@ -1393,39 +1394,31 @@ pub mod tests { #[test] #[cfg(feature = "openssl_sign")] fn test_cert_algorithms() { - let cert_dir = crate::utils::test::fixture_path("certs"); let th = crate::openssl::OpenSSLTrustHandlerConfig::new(); let mut validation_log = DetailedStatusTracker::default(); - let (_, cert_path) = temp_signer::get_ec_signer(&cert_dir, SigningAlg::Es256, None); - let es256_cert = std::fs::read(cert_path).unwrap(); + let es256_cert = include_bytes!("../tests/fixtures/certs/es256.pub"); + let es384_cert = include_bytes!("../tests/fixtures/certs/es384.pub"); + let es512_cert = include_bytes!("../tests/fixtures/certs/es512.pub"); + let rsa_pss256_cert = include_bytes!("../tests/fixtures/certs/ps256.pub"); - let (_, cert_path) = temp_signer::get_ec_signer(&cert_dir, SigningAlg::Es384, None); - let es384_cert = std::fs::read(cert_path).unwrap(); - - let (_, cert_path) = temp_signer::get_ec_signer(&cert_dir, SigningAlg::Es512, None); - let es512_cert = std::fs::read(cert_path).unwrap(); - - let (_, cert_path) = temp_signer::get_rsa_signer(&cert_dir, SigningAlg::Ps256, None); - let rsa_pss256_cert = std::fs::read(cert_path).unwrap(); - - if let Ok(signcert) = openssl::x509::X509::from_pem(&es256_cert) { + if let Ok(signcert) = openssl::x509::X509::from_pem(es256_cert) { let der_bytes = signcert.to_der().unwrap(); assert!(check_cert(&der_bytes, &th, &mut validation_log, None).is_ok()); } - if let Ok(signcert) = openssl::x509::X509::from_pem(&es384_cert) { + if let Ok(signcert) = openssl::x509::X509::from_pem(es384_cert) { let der_bytes = signcert.to_der().unwrap(); assert!(check_cert(&der_bytes, &th, &mut validation_log, None).is_ok()); } - if let Ok(signcert) = openssl::x509::X509::from_pem(&es512_cert) { + if let Ok(signcert) = openssl::x509::X509::from_pem(es512_cert) { let der_bytes = signcert.to_der().unwrap(); assert!(check_cert(&der_bytes, &th, &mut validation_log, None).is_ok()); } - if let Ok(signcert) = openssl::x509::X509::from_pem(&rsa_pss256_cert) { + if let Ok(signcert) = openssl::x509::X509::from_pem(rsa_pss256_cert) { let der_bytes = signcert.to_der().unwrap(); assert!(check_cert(&der_bytes, &th, &mut validation_log, None).is_ok()); } @@ -1442,7 +1435,7 @@ pub mod tests { let box_size = 10000; - let signer = crate::utils::test::temp_signer(); + let signer = test_signer(SigningAlg::Ps256); let cose_bytes = crate::cose_sign::sign_claim(&claim_bytes, signer.as_ref(), box_size).unwrap(); @@ -1456,6 +1449,10 @@ pub mod tests { #[test] #[cfg(feature = "openssl_sign")] fn test_stapled_ocsp() { + use c2pa_crypto::raw_signature::{ + signer_from_cert_chain_and_private_key, RawSigner, RawSignerError, + }; + let mut validation_log = DetailedStatusTracker::default(); let mut claim = crate::claim::Claim::new("ocsp_sign_test", Some("contentauth")); @@ -1467,13 +1464,9 @@ pub mod tests { let pem_key = include_bytes!("../tests/fixtures/certs/ps256.pem").to_vec(); let ocsp_rsp_data = include_bytes!("../tests/fixtures/ocsp_good.data"); - let signer = crate::openssl::RsaSigner::from_signcert_and_pkey( - &sign_cert, - &pem_key, - SigningAlg::Ps256, - None, - ) - .unwrap(); + let signer = + signer_from_cert_chain_and_private_key(&sign_cert, &pem_key, SigningAlg::Ps256, None) + .unwrap(); // create a test signer that supports stapling struct OcspSigner { @@ -1504,7 +1497,7 @@ pub mod tests { } let ocsp_signer = OcspSigner { - signer: Box::new(signer), + signer: Box::new(crate::signer::RawSignerWrapper(signer)), ocsp_rsp: ocsp_rsp_data.to_vec(), }; diff --git a/sdk/src/create_signer.rs b/sdk/src/create_signer.rs index 176cfdf07..67fb1887f 100644 --- a/sdk/src/create_signer.rs +++ b/sdk/src/create_signer.rs @@ -18,14 +18,9 @@ #[cfg(feature = "file_io")] use std::path::Path; -use c2pa_crypto::SigningAlg; +use c2pa_crypto::{raw_signature::signer_from_cert_chain_and_private_key, SigningAlg}; -use crate::{ - error::Result, - openssl::{EcSigner, EdSigner, RsaSigner}, - signer::ConfigurableSigner, - Signer, -}; +use crate::{error::Result, signer::RawSignerWrapper, Signer}; /// Creates a [`Signer`] instance using signing certificate and private key /// as byte slices. @@ -45,17 +40,9 @@ pub fn from_keys( alg: SigningAlg, tsa_url: Option, ) -> Result> { - Ok(match alg { - SigningAlg::Ps256 | SigningAlg::Ps384 | SigningAlg::Ps512 => Box::new( - RsaSigner::from_signcert_and_pkey(signcert, pkey, alg, tsa_url)?, - ), - SigningAlg::Es256 | SigningAlg::Es384 | SigningAlg::Es512 => Box::new( - EcSigner::from_signcert_and_pkey(signcert, pkey, alg, tsa_url)?, - ), - SigningAlg::Ed25519 => Box::new(EdSigner::from_signcert_and_pkey( - signcert, pkey, alg, tsa_url, - )?), - }) + Ok(Box::new(RawSignerWrapper( + signer_from_cert_chain_and_private_key(signcert, pkey, alg, tsa_url)?, + ))) } /// Creates a [`Signer`] instance using signing certificate and @@ -74,18 +61,8 @@ pub fn from_files>( alg: SigningAlg, tsa_url: Option, ) -> Result> { - Ok(match alg { - SigningAlg::Ps256 | SigningAlg::Ps384 | SigningAlg::Ps512 => Box::new( - RsaSigner::from_files(&signcert_path, &pkey_path, alg, tsa_url)?, - ), - SigningAlg::Es256 | SigningAlg::Es384 | SigningAlg::Es512 => Box::new( - EcSigner::from_files(&signcert_path, &pkey_path, alg, tsa_url)?, - ), - SigningAlg::Ed25519 => Box::new(EdSigner::from_files( - &signcert_path, - &pkey_path, - alg, - tsa_url, - )?), - }) + let cert_chain = std::fs::read(signcert_path)?; + let private_key = std::fs::read(pkey_path)?; + + from_keys(&cert_chain, &private_key, alg, tsa_url) } diff --git a/sdk/src/error.rs b/sdk/src/error.rs index d4ee87532..2e2f54b89 100644 --- a/sdk/src/error.rs +++ b/sdk/src/error.rs @@ -306,6 +306,9 @@ pub enum Error { #[error(transparent)] RawSignatureValidationError(#[from] c2pa_crypto::raw_signature::RawSignatureValidationError), + + #[error(transparent)] + RawSignerError(#[from] c2pa_crypto::raw_signature::RawSignerError), } /// A specialized `Result` type for C2PA toolkit operations. diff --git a/sdk/src/jumbf_io.rs b/sdk/src/jumbf_io.rs index 677ec9be7..7e11ae36e 100644 --- a/sdk/src/jumbf_io.rs +++ b/sdk/src/jumbf_io.rs @@ -349,10 +349,12 @@ pub mod tests { use std::io::Seek; + use c2pa_crypto::SigningAlg; + use super::*; use crate::{ asset_io::RemoteRefEmbedType, - utils::test::{create_test_store, temp_signer}, + utils::{test::create_test_store, test_signer::test_signer}, }; #[test] @@ -447,7 +449,7 @@ pub mod tests { fn test_jumbf(asset_type: &str, reader: &mut dyn CAIRead) { let mut writer = Cursor::new(Vec::new()); let store = create_test_store().unwrap(); - let signer = temp_signer(); + let signer = test_signer(SigningAlg::Ps256); let jumbf = store.to_jumbf(&*signer).unwrap(); save_jumbf_to_stream(asset_type, reader, &mut writer, &jumbf).unwrap(); writer.set_position(0); diff --git a/sdk/src/manifest.rs b/sdk/src/manifest.rs index 774798e6f..ebfa67153 100644 --- a/sdk/src/manifest.rs +++ b/sdk/src/manifest.rs @@ -1504,6 +1504,8 @@ pub(crate) mod tests { use std::io::Cursor; + #[cfg(any(feature = "file_io", target_arch = "wasm32"))] + use c2pa_crypto::SigningAlg; #[cfg(feature = "file_io")] use c2pa_status_tracker::{DetailedStatusTracker, StatusTracker}; #[cfg(feature = "file_io")] @@ -1520,7 +1522,8 @@ pub(crate) mod tests { ingredient::Ingredient, reader::Reader, store::Store, - utils::test::{temp_remote_signer, temp_signer, TEST_VC}, + utils::test::{temp_remote_signer, TEST_VC}, + utils::test_signer::{async_test_signer, test_signer}, Manifest, Result, }; #[cfg(feature = "file_io")] @@ -1601,7 +1604,7 @@ pub(crate) mod tests { let test_output = dir.path().join("wc_embed_test.jpg"); //embed a claim generated from this manifest - let signer = temp_signer(); + let signer = test_signer(SigningAlg::Ps256); let _store = manifest .embed(&source_path, &test_output, signer.as_ref()) @@ -1772,7 +1775,7 @@ pub(crate) mod tests { ) .expect("add_assertion"); - let signer = temp_signer(); + let signer = test_signer(SigningAlg::Ps256); let c2pa_data = manifest .embed(&output, &output, signer.as_ref()) @@ -1797,7 +1800,7 @@ pub(crate) mod tests { .expect("add_redaction"); //embed a claim in output2 - let signer = temp_signer(); + let signer = test_signer(SigningAlg::Ps256); let _store2 = manifest2 .embed(&output2, &output2, signer.as_ref()) .expect("embed"); @@ -1838,7 +1841,7 @@ pub(crate) mod tests { .add_assertion(&actions) .expect("add_assertion"); - let signer = temp_signer(); + let signer = test_signer(SigningAlg::Ps256); parent_manifest .embed(&parent_output, &parent_output, signer.as_ref()) .expect("embed"); @@ -1895,8 +1898,7 @@ pub(crate) mod tests { let temp_dir = tempdir().expect("temp dir"); let output = temp_fixture_path(&temp_dir, TEST_SMALL_JPEG); - let async_signer = - crate::openssl::temp_signer_async::AsyncSignerAdapter::new(crate::SigningAlg::Ps256); + let async_signer = async_test_signer(SigningAlg::Ps256); let mut manifest = test_manifest(); manifest @@ -1938,7 +1940,7 @@ pub(crate) mod tests { let temp_dir = tempdir().expect("temp dir"); let output = temp_fixture_path(&temp_dir, TEST_SMALL_JPEG); - let signer = temp_signer(); + let signer = test_signer(SigningAlg::Ps256); let mut manifest = test_manifest(); manifest.set_label("MyLabel"); @@ -1963,7 +1965,7 @@ pub(crate) mod tests { let fp = format!("file:/{}", sidecar.to_str().unwrap()); let url = url::Url::parse(&fp).unwrap(); - let signer = temp_signer(); + let signer = test_signer(SigningAlg::Ps256); let mut manifest = test_manifest(); manifest.set_label("MyLabel"); @@ -2104,7 +2106,8 @@ pub(crate) mod tests { )) .unwrap(); - let signer = temp_signer(); + let signer = test_signer(SigningAlg::Ps256); + let mut output = Cursor::new(Vec::new()); // Embed a manifest using the signer. manifest @@ -2126,7 +2129,7 @@ pub(crate) mod tests { #[cfg_attr(feature = "openssl_sign", actix::test)] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] async fn test_embed_from_memory_async() { - use crate::{assertions::User, utils::test::temp_async_signer}; + use crate::assertions::User; let image = include_bytes!("../tests/fixtures/earth_apollo17.jpg"); // convert buffer to cursor with Read/Write/Seek capability let mut stream = std::io::Cursor::new(image.to_vec()); @@ -2142,8 +2145,9 @@ pub(crate) mod tests { )) .unwrap(); - let signer = temp_async_signer(); + let signer = async_test_signer(SigningAlg::Ed25519); let mut output = Cursor::new(Vec::new()); + // Embed a manifest using the signer. manifest .embed_to_stream_async("jpeg", &mut stream, &mut output, signer.as_ref()) @@ -2171,7 +2175,7 @@ pub(crate) mod tests { let temp_dir = tempdir().expect("temp dir"); let output = temp_fixture_path(&temp_dir, TEST_SMALL_JPEG); - let signer = temp_signer(); + let signer = test_signer(SigningAlg::Ps256); let mut manifest = test_manifest(); let ingredient = @@ -2208,7 +2212,7 @@ pub(crate) mod tests { let fp = format!("file:/{}", sidecar.to_str().unwrap()); let url = url::Url::parse(&fp).unwrap(); - let signer = temp_signer(); + let signer = test_signer(SigningAlg::Ps256); let parent = Ingredient::from_file(fixture_path("XCA.jpg")).expect("getting parent"); let mut manifest = test_manifest(); @@ -2235,7 +2239,7 @@ pub(crate) mod tests { let temp_dir = tempdir().expect("temp dir"); let output = temp_fixture_path(&temp_dir, TEST_SMALL_JPEG); - let signer = temp_signer(); + let signer = test_signer(SigningAlg::Ps256); let mut manifest = test_manifest(); let thumb_data = vec![1, 2, 3]; @@ -2397,7 +2401,8 @@ pub(crate) mod tests { // convert buffer to cursor with Read/Write/Seek capability let mut input = std::io::Cursor::new(image.to_vec()); - let signer = temp_signer(); + let signer = test_signer(SigningAlg::Ps256); + // Embed a manifest using the signer. let mut output = Cursor::new(Vec::new()); manifest @@ -2464,7 +2469,8 @@ pub(crate) mod tests { let image = include_bytes!("../tests/fixtures/earth_apollo17.jpg"); - let signer = temp_signer(); + let signer = test_signer(SigningAlg::Ps256); + // Embed a manifest using the signer. let output_image = manifest .embed_from_memory("jpeg", image, signer.as_ref()) @@ -2529,7 +2535,7 @@ pub(crate) mod tests { let temp_dir = tempdir().expect("temp dir"); let output = temp_fixture_path(&temp_dir, TEST_SMALL_JPEG); - let signer = temp_signer(); + let signer = test_signer(SigningAlg::Ps256); let mut manifest = Manifest::from_json(MANIFEST_JSON).expect("from_json"); manifest.with_base_path(fixtures).expect("with_base"); @@ -2556,7 +2562,7 @@ pub(crate) mod tests { let temp_dir = tempdir().expect("temp dir"); let output = temp_fixture_path(&temp_dir, TEST_WEBP); - let signer = temp_signer(); + let signer = test_signer(SigningAlg::Ps256); let mut manifest = Manifest::from_json(MANIFEST_JSON).expect("from_json"); manifest.with_base_path(fixtures).expect("with_base"); @@ -2594,7 +2600,7 @@ pub(crate) mod tests { .is_ok()); assert!(manifest.thumbnail_ref().is_some()); - let signer = temp_signer(); + let signer = test_signer(SigningAlg::Ps256); manifest .embed(&output, &output, signer.as_ref()) .expect("embed"); @@ -2621,7 +2627,7 @@ pub(crate) mod tests { // verify there is no thumbnail assert!(manifest.thumbnail().is_none()); - let signer = temp_signer(); + let signer = test_signer(SigningAlg::Ps256); manifest .embed(&output, &output, signer.as_ref()) .expect("embed"); @@ -2650,9 +2656,11 @@ pub(crate) mod tests { let mut source = std::io::Cursor::new(vec![1, 2, 3]); let mut dest = std::io::Cursor::new(Vec::new()); - let signer = temp_signer(); + let signer = test_signer(SigningAlg::Ps256); + let result = manifest.embed_to_stream("image/jpeg", &mut source, &mut dest, signer.as_ref()); + assert!(result.is_err()); assert!(result .unwrap_err() @@ -2666,7 +2674,7 @@ pub(crate) mod tests { fn test_data_hash_embeddable_manifest() { let ap = fixture_path("cloud.jpg"); - let signer = temp_signer(); + let signer = test_signer(SigningAlg::Ps256); let mut manifest = Manifest::new("claim_generator"); @@ -2792,7 +2800,7 @@ pub(crate) mod tests { .add_labeled_assertion(crate::assertions::labels::BOX_HASH, &box_hash) .unwrap(); - let signer = temp_signer(); + let signer = test_signer(SigningAlg::Ps256); let embeddable = manifest .box_hash_embeddable_manifest(signer.as_ref(), None) diff --git a/sdk/src/openssl/ec_signer.rs b/sdk/src/openssl/ec_signer.rs deleted file mode 100644 index 136cf328e..000000000 --- a/sdk/src/openssl/ec_signer.rs +++ /dev/null @@ -1,171 +0,0 @@ -// Copyright 2022 Adobe. All rights reserved. -// This file is licensed to you under the Apache License, -// Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0) -// or the MIT license (http://opensource.org/licenses/MIT), -// at your option. - -// Unless required by applicable law or agreed to in writing, -// this software is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR REPRESENTATIONS OF ANY KIND, either express or -// implied. See the LICENSE-MIT and LICENSE-APACHE files for the -// specific language governing permissions and limitations under -// each license. - -use c2pa_crypto::{openssl::OpenSslMutex, SigningAlg}; -use openssl::{ - ec::EcKey, - hash::MessageDigest, - pkey::{PKey, Private}, - x509::X509, -}; - -use super::check_chain_order; -use crate::{ - error::{Error, Result}, - signer::ConfigurableSigner, - utils::sig_utils::der_to_p1363, - Signer, -}; - -/// Implements `Signer` trait using OpenSSL's implementation of -/// ECDSA encryption. -pub struct EcSigner { - signcerts: Vec, - pkey: EcKey, - - certs_size: usize, - timestamp_size: usize, - - alg: SigningAlg, - tsa_url: Option, -} - -impl ConfigurableSigner for EcSigner { - fn from_signcert_and_pkey( - signcert: &[u8], - pkey: &[u8], - alg: SigningAlg, - tsa_url: Option, - ) -> Result { - let _openssl = OpenSslMutex::acquire()?; - - let certs_size = signcert.len(); - let pkey = EcKey::private_key_from_pem(pkey).map_err(Error::OpenSslError)?; - let signcerts = X509::stack_from_pem(signcert).map_err(Error::OpenSslError)?; - - // make sure cert chains are in order - if !check_chain_order(&signcerts) { - return Err(Error::BadParam( - "certificate chain is not in correct order".to_string(), - )); - } - - Ok(EcSigner { - signcerts, - pkey, - certs_size, - timestamp_size: 10000, /* todo: call out to TSA to get actual timestamp and use that size */ - alg, - tsa_url, - }) - } -} - -impl Signer for EcSigner { - fn sign(&self, data: &[u8]) -> Result> { - let _openssl = OpenSslMutex::acquire()?; - - let key = PKey::from_ec_key(self.pkey.clone()).map_err(Error::OpenSslError)?; - - let mut signer = match self.alg { - SigningAlg::Es256 => openssl::sign::Signer::new(MessageDigest::sha256(), &key)?, - SigningAlg::Es384 => openssl::sign::Signer::new(MessageDigest::sha384(), &key)?, - SigningAlg::Es512 => openssl::sign::Signer::new(MessageDigest::sha512(), &key)?, - _ => return Err(Error::UnsupportedType), - }; - - signer.update(data).map_err(Error::OpenSslError)?; - let der_sig = signer.sign_to_vec().map_err(Error::OpenSslError)?; - - der_to_p1363(&der_sig, self.alg) - } - - fn alg(&self) -> SigningAlg { - self.alg - } - - fn certs(&self) -> Result>> { - let _openssl = OpenSslMutex::acquire()?; - - let mut certs: Vec> = Vec::new(); - - for c in &self.signcerts { - let cert = c.to_der().map_err(Error::OpenSslError)?; - certs.push(cert); - } - - Ok(certs) - } - - fn time_authority_url(&self) -> Option { - self.tsa_url.clone() - } - - fn reserve_size(&self) -> usize { - 1024 + self.certs_size + self.timestamp_size // the Cose_Sign1 contains complete certs and timestamps so account for size - } -} - -#[cfg(test)] -#[cfg(feature = "file_io")] -mod tests { - #![allow(clippy::unwrap_used)] - - use super::*; - use crate::{openssl::temp_signer, utils::test::fixture_path}; - - #[test] - fn es256_signer() { - let cert_dir = fixture_path("certs"); - - let (signer, _) = temp_signer::get_ec_signer(cert_dir, SigningAlg::Es256, None); - - let data = b"some sample content to sign"; - println!("data len = {}", data.len()); - - let signature = signer.sign(data).unwrap(); - println!("signature.len = {}", signature.len()); - assert!(signature.len() >= 64); - assert!(signature.len() <= signer.reserve_size()); - } - - #[test] - fn es384_signer() { - let cert_dir = fixture_path("certs"); - - let (signer, _) = temp_signer::get_ec_signer(cert_dir, SigningAlg::Es384, None); - - let data = b"some sample content to sign"; - println!("data len = {}", data.len()); - - let signature = signer.sign(data).unwrap(); - println!("signature.len = {}", signature.len()); - assert!(signature.len() >= 64); - assert!(signature.len() <= signer.reserve_size()); - } - - #[test] - fn es512_signer() { - let cert_dir = fixture_path("certs"); - - let (signer, _) = temp_signer::get_ec_signer(cert_dir, SigningAlg::Es512, None); - - let data = b"some sample content to sign"; - println!("data len = {}", data.len()); - - let signature = signer.sign(data).unwrap(); - println!("signature.len = {}", signature.len()); - assert!(signature.len() >= 64); - assert!(signature.len() <= signer.reserve_size()); - } -} diff --git a/sdk/src/openssl/ed_signer.rs b/sdk/src/openssl/ed_signer.rs deleted file mode 100644 index 21202eebf..000000000 --- a/sdk/src/openssl/ed_signer.rs +++ /dev/null @@ -1,130 +0,0 @@ -// Copyright 2022 Adobe. All rights reserved. -// This file is licensed to you under the Apache License, -// Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0) -// or the MIT license (http://opensource.org/licenses/MIT), -// at your option. - -// Unless required by applicable law or agreed to in writing, -// this software is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR REPRESENTATIONS OF ANY KIND, either express or -// implied. See the LICENSE-MIT and LICENSE-APACHE files for the -// specific language governing permissions and limitations under -// each license. - -use c2pa_crypto::{openssl::OpenSslMutex, SigningAlg}; -use openssl::{ - pkey::{PKey, Private}, - x509::X509, -}; - -use super::check_chain_order; -use crate::{signer::ConfigurableSigner, Error, Result, Signer}; - -/// Implements `Signer` trait using OpenSSL's implementation of -/// Edwards Curve encryption. -pub struct EdSigner { - signcerts: Vec, - pkey: PKey, - - certs_size: usize, - timestamp_size: usize, - - alg: SigningAlg, - tsa_url: Option, -} - -impl ConfigurableSigner for EdSigner { - fn from_signcert_and_pkey( - signcert: &[u8], - pkey: &[u8], - alg: SigningAlg, - tsa_url: Option, - ) -> Result { - let _openssl = OpenSslMutex::acquire()?; - - let certs_size = signcert.len(); - let signcerts = X509::stack_from_pem(signcert).map_err(Error::OpenSslError)?; - let pkey = PKey::private_key_from_pem(pkey).map_err(Error::OpenSslError)?; - - if alg != SigningAlg::Ed25519 { - return Err(Error::UnsupportedType); // only ed25519 is supported by C2PA - } - - // make sure cert chains are in order - if !check_chain_order(&signcerts) { - return Err(Error::BadParam( - "certificate chain is not in correct order".to_string(), - )); - } - - Ok(EdSigner { - signcerts, - pkey, - certs_size, - timestamp_size: 10000, /* todo: call out to TSA to get actual timestamp and use that size */ - alg, - tsa_url, - }) - } -} - -impl Signer for EdSigner { - fn sign(&self, data: &[u8]) -> Result> { - let _openssl = OpenSslMutex::acquire()?; - - let mut signer = - openssl::sign::Signer::new_without_digest(&self.pkey).map_err(Error::OpenSslError)?; - - let signed_data = signer.sign_oneshot_to_vec(data)?; - - Ok(signed_data) - } - - fn alg(&self) -> SigningAlg { - self.alg - } - - fn certs(&self) -> Result>> { - let _openssl = OpenSslMutex::acquire()?; - - let mut certs: Vec> = Vec::new(); - - for c in &self.signcerts { - let cert = c.to_der().map_err(Error::OpenSslError)?; - certs.push(cert); - } - - Ok(certs) - } - - fn time_authority_url(&self) -> Option { - self.tsa_url.clone() - } - - fn reserve_size(&self) -> usize { - 1024 + self.certs_size + self.timestamp_size // the Cose_Sign1 contains complete certs and timestamps so account for size - } -} - -#[cfg(test)] -#[cfg(feature = "file_io")] -mod tests { - #![allow(clippy::unwrap_used)] - use super::*; - use crate::{openssl::temp_signer, utils::test::fixture_path}; - - #[test] - fn ed25519_signer() { - let cert_dir = fixture_path("certs"); - - let (signer, _) = temp_signer::get_ed_signer(cert_dir, SigningAlg::Ed25519, None); - - let data = b"some sample content to sign"; - println!("data len = {}", data.len()); - - let signature = signer.sign(data).unwrap(); - println!("signature.len = {}", signature.len()); - assert!(signature.len() >= 64); - assert!(signature.len() <= signer.reserve_size()); - } -} diff --git a/sdk/src/openssl/mod.rs b/sdk/src/openssl/mod.rs index 13dbaeb83..43c7b4a8f 100644 --- a/sdk/src/openssl/mod.rs +++ b/sdk/src/openssl/mod.rs @@ -11,94 +11,10 @@ // specific language governing permissions and limitations under // each license. -#[cfg(feature = "openssl_sign")] -mod rsa_signer; -#[cfg(feature = "openssl_sign")] -pub(crate) use rsa_signer::RsaSigner; - -#[cfg(feature = "openssl_sign")] -mod ec_signer; -#[cfg(feature = "openssl_sign")] -pub(crate) use ec_signer::EcSigner; - -#[cfg(feature = "openssl_sign")] -mod ed_signer; -#[cfg(feature = "openssl_sign")] -pub(crate) use ed_signer::EdSigner; - #[cfg(feature = "openssl")] mod openssl_trust_handler; -#[cfg(test)] -pub(crate) mod temp_signer; #[cfg(feature = "openssl")] pub(crate) use openssl_trust_handler::verify_trust; #[cfg(feature = "openssl")] pub(crate) use openssl_trust_handler::OpenSSLTrustHandlerConfig; - -#[cfg(test)] -pub(crate) mod temp_signer_async; - -#[cfg(feature = "openssl")] -use openssl::x509::X509; -#[cfg(test)] -#[allow(unused_imports)] -#[cfg(feature = "openssl")] -pub(crate) use temp_signer_async::AsyncSignerAdapter; - -#[cfg(feature = "openssl")] -fn check_chain_order(certs: &[X509]) -> bool { - // IMPORTANT: ffi_mutex::acquire() should have been called by calling fn. Please - // don't make this pub or pub(crate) without finding a way to ensure that - // precondition. - - { - if certs.len() > 1 { - for (i, c) in certs.iter().enumerate() { - if let Some(next_c) = certs.get(i + 1) { - if let Ok(pkey) = next_c.public_key() { - if let Ok(verified) = c.verify(&pkey) { - if !verified { - return false; - } - } else { - return false; - } - } else { - return false; - } - } - } - } - true - } -} - -#[cfg(not(feature = "openssl"))] -fn check_chain_order(certs: &[X509]) -> bool { - true -} - -#[cfg(feature = "openssl")] -#[allow(dead_code)] -fn check_chain_order_der(cert_ders: &[Vec]) -> bool { - // IMPORTANT: ffi_mutex::acquire() should have been called by calling fn. Please - // don't make this pub or pub(crate) without finding a way to ensure that - // precondition. - - let mut certs: Vec = Vec::new(); - for cert_der in cert_ders { - if let Ok(cert) = X509::from_der(cert_der) { - certs.push(cert); - } else { - return false; - } - } - - check_chain_order(&certs) -} - -#[cfg(not(feature = "openssl"))] -fn check_chain_order_der(cert_ders: &[Vec]) -> bool { - true -} diff --git a/sdk/src/openssl/openssl_trust_handler.rs b/sdk/src/openssl/openssl_trust_handler.rs index 9d5ae56b9..bfaabae35 100644 --- a/sdk/src/openssl/openssl_trust_handler.rs +++ b/sdk/src/openssl/openssl_trust_handler.rs @@ -302,28 +302,23 @@ pub mod tests { use c2pa_crypto::SigningAlg; use super::*; - use crate::{ - openssl::temp_signer::{self}, - Signer, - }; + use crate::{utils::test_signer::test_signer, Signer}; #[test] fn test_trust_store() { - let cert_dir = crate::utils::test::fixture_path("certs"); - let mut th = OpenSSLTrustHandlerConfig::new(); th.clear(); th.load_default_trust().unwrap(); // test all the certs - let (ps256, _) = temp_signer::get_rsa_signer(&cert_dir, SigningAlg::Ps256, None); - let (ps384, _) = temp_signer::get_rsa_signer(&cert_dir, SigningAlg::Ps384, None); - let (ps512, _) = temp_signer::get_rsa_signer(&cert_dir, SigningAlg::Ps512, None); - let (es256, _) = temp_signer::get_ec_signer(&cert_dir, SigningAlg::Es256, None); - let (es384, _) = temp_signer::get_ec_signer(&cert_dir, SigningAlg::Es384, None); - let (es512, _) = temp_signer::get_ec_signer(&cert_dir, SigningAlg::Es512, None); - let (ed25519, _) = temp_signer::get_ed_signer(&cert_dir, SigningAlg::Ed25519, None); + let ps256 = test_signer(SigningAlg::Ps256); + let ps384 = test_signer(SigningAlg::Ps384); + let ps512 = test_signer(SigningAlg::Ps512); + let es256 = test_signer(SigningAlg::Es256); + let es384 = test_signer(SigningAlg::Es384); + let es512 = test_signer(SigningAlg::Es512); + let ed25519 = test_signer(SigningAlg::Ed25519); let ps256_certs = ps256.certs().unwrap(); let ps384_certs = ps384.certs().unwrap(); @@ -344,7 +339,6 @@ pub mod tests { #[test] fn test_broken_trust_chain() { - let cert_dir = crate::utils::test::fixture_path("certs"); let ta = include_bytes!("../../tests/fixtures/certs/trust/test_cert_root_bundle.pem"); let mut th = OpenSSLTrustHandlerConfig::new(); @@ -355,13 +349,13 @@ pub mod tests { th.load_trust_anchors_from_data(&mut reader).unwrap(); // test all the certs - let (ps256, _) = temp_signer::get_rsa_signer(&cert_dir, SigningAlg::Ps256, None); - let (ps384, _) = temp_signer::get_rsa_signer(&cert_dir, SigningAlg::Ps384, None); - let (ps512, _) = temp_signer::get_rsa_signer(&cert_dir, SigningAlg::Ps512, None); - let (es256, _) = temp_signer::get_ec_signer(&cert_dir, SigningAlg::Es256, None); - let (es384, _) = temp_signer::get_ec_signer(&cert_dir, SigningAlg::Es384, None); - let (es512, _) = temp_signer::get_ec_signer(&cert_dir, SigningAlg::Es512, None); - let (ed25519, _) = temp_signer::get_ed_signer(&cert_dir, SigningAlg::Ed25519, None); + let ps256 = test_signer(SigningAlg::Ps256); + let ps384 = test_signer(SigningAlg::Ps384); + let ps512 = test_signer(SigningAlg::Ps512); + let es256 = test_signer(SigningAlg::Es256); + let es384 = test_signer(SigningAlg::Es384); + let es512 = test_signer(SigningAlg::Es512); + let ed25519 = test_signer(SigningAlg::Ed25519); let ps256_certs = ps256.certs().unwrap(); let ps384_certs = ps384.certs().unwrap(); @@ -383,8 +377,6 @@ pub mod tests { #[test] fn test_allowed_list() { - let cert_dir = crate::utils::test::fixture_path("certs"); - let mut th = OpenSSLTrustHandlerConfig::new(); th.clear(); @@ -397,13 +389,13 @@ pub mod tests { th.load_allowed_list(&mut allowed_list).unwrap(); // test all the certs - let (ps256, _) = temp_signer::get_rsa_signer(&cert_dir, SigningAlg::Ps256, None); - let (ps384, _) = temp_signer::get_rsa_signer(&cert_dir, SigningAlg::Ps384, None); - let (ps512, _) = temp_signer::get_rsa_signer(&cert_dir, SigningAlg::Ps512, None); - let (es256, _) = temp_signer::get_ec_signer(&cert_dir, SigningAlg::Es256, None); - let (es384, _) = temp_signer::get_ec_signer(&cert_dir, SigningAlg::Es384, None); - let (es512, _) = temp_signer::get_ec_signer(&cert_dir, SigningAlg::Es512, None); - let (ed25519, _) = temp_signer::get_ed_signer(&cert_dir, SigningAlg::Ed25519, None); + let ps256 = test_signer(SigningAlg::Ps256); + let ps384 = test_signer(SigningAlg::Ps384); + let ps512 = test_signer(SigningAlg::Ps512); + let es256 = test_signer(SigningAlg::Es256); + let es384 = test_signer(SigningAlg::Es384); + let es512 = test_signer(SigningAlg::Es512); + let ed25519 = test_signer(SigningAlg::Ed25519); let ps256_certs = ps256.certs().unwrap(); let ps384_certs = ps384.certs().unwrap(); @@ -424,8 +416,6 @@ pub mod tests { #[test] fn test_allowed_list_hashes() { - let cert_dir = crate::utils::test::fixture_path("certs"); - let mut th = OpenSSLTrustHandlerConfig::new(); th.clear(); @@ -438,13 +428,13 @@ pub mod tests { th.load_allowed_list(&mut allowed_list).unwrap(); // test all the certs - let (ps256, _) = temp_signer::get_rsa_signer(&cert_dir, SigningAlg::Ps256, None); - let (ps384, _) = temp_signer::get_rsa_signer(&cert_dir, SigningAlg::Ps384, None); - let (ps512, _) = temp_signer::get_rsa_signer(&cert_dir, SigningAlg::Ps512, None); - let (es256, _) = temp_signer::get_ec_signer(&cert_dir, SigningAlg::Es256, None); - let (es384, _) = temp_signer::get_ec_signer(&cert_dir, SigningAlg::Es384, None); - let (es512, _) = temp_signer::get_ec_signer(&cert_dir, SigningAlg::Es512, None); - let (ed25519, _) = temp_signer::get_ed_signer(&cert_dir, SigningAlg::Ed25519, None); + let ps256 = test_signer(SigningAlg::Ps256); + let ps384 = test_signer(SigningAlg::Ps384); + let ps512 = test_signer(SigningAlg::Ps512); + let es256 = test_signer(SigningAlg::Es256); + let es384 = test_signer(SigningAlg::Es384); + let es512 = test_signer(SigningAlg::Es512); + let ed25519 = test_signer(SigningAlg::Ed25519); let ps256_certs = ps256.certs().unwrap(); let ps384_certs = ps384.certs().unwrap(); diff --git a/sdk/src/openssl/rsa_signer.rs b/sdk/src/openssl/rsa_signer.rs deleted file mode 100644 index ce19a5004..000000000 --- a/sdk/src/openssl/rsa_signer.rs +++ /dev/null @@ -1,303 +0,0 @@ -// Copyright 2022 Adobe. All rights reserved. -// This file is licensed to you under the Apache License, -// Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0) -// or the MIT license (http://opensource.org/licenses/MIT), -// at your option. - -// Unless required by applicable law or agreed to in writing, -// this software is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR REPRESENTATIONS OF ANY KIND, either express or -// implied. See the LICENSE-MIT and LICENSE-APACHE files for the -// specific language governing permissions and limitations under -// each license. - -use std::cell::Cell; - -use c2pa_crypto::{ - ocsp::OcspResponse, openssl::OpenSslMutex, time_stamp::TimeStampProvider, SigningAlg, -}; -use openssl::{ - hash::MessageDigest, - pkey::{PKey, Private}, - rsa::{Rsa, RsaPrivateKeyBuilder}, - x509::X509, -}; - -use super::check_chain_order; -use crate::{signer::ConfigurableSigner, Error, Result, Signer}; - -/// Implements `Signer` trait using OpenSSL's implementation of -/// SHA256 + RSA encryption. -pub struct RsaSigner { - signcerts: Vec, - pkey: PKey, - - certs_size: usize, - timestamp_size: usize, - ocsp_size: Cell, - - alg: SigningAlg, - tsa_url: Option, - ocsp_rsp: Cell, -} - -impl RsaSigner { - // Sample of OCSP stapling while signing. This code is only for demo purposes and not for - // production use since there is no caching in the SDK and fetching is expensive. This is behind the - // feature flag 'psxxx_ocsp_stapling_experimental' - fn update_ocsp(&self) { - // IMPORTANT: ffi_mutex::acquire() should have been called by calling fn. Please - // don't make this pub or pub(crate) without finding a way to ensure that - // precondition. - - // do we need an update - let now = chrono::offset::Utc::now(); - - // is it time for an OCSP update - let ocsp_data = self.ocsp_rsp.take(); - let next_update = ocsp_data.next_update; - self.ocsp_rsp.set(ocsp_data); - if now > next_update { - #[cfg(feature = "psxxx_ocsp_stapling_experimental")] - { - if let Ok(certs) = self.certs_internal() { - if let Some(ocsp_rsp) = c2pa_crypto::ocsp::fetch_ocsp_response(&certs) { - self.ocsp_size.set(ocsp_rsp.len()); - let mut validation_log = - c2pa_status_tracker::DetailedStatusTracker::default(); - if let Ok(ocsp_response) = - OcspResponse::from_der_checked(&ocsp_rsp, None, &mut validation_log) - { - self.ocsp_rsp.set(ocsp_response); - } - } - } - } - } - } - - fn certs_internal(&self) -> Result>> { - // IMPORTANT: ffi_mutex::acquire() should have been called by calling fn. Please - // don't make this pub or pub(crate) without finding a way to ensure that - // precondition. - - let mut certs: Vec> = Vec::new(); - - for c in &self.signcerts { - let cert = c.to_der().map_err(wrap_openssl_err)?; - certs.push(cert); - } - - Ok(certs) - } -} - -impl ConfigurableSigner for RsaSigner { - fn from_signcert_and_pkey( - signcert: &[u8], - pkey: &[u8], - alg: SigningAlg, - tsa_url: Option, - ) -> Result { - let _openssl = OpenSslMutex::acquire()?; - - let signcerts = X509::stack_from_pem(signcert).map_err(wrap_openssl_err)?; - let rsa = Rsa::private_key_from_pem(pkey).map_err(wrap_openssl_err)?; - - // make sure cert chains are in order - if !check_chain_order(&signcerts) { - return Err(Error::BadParam( - "certificate chain is not in correct order".to_string(), - )); - } - - // rebuild RSA keys to eliminate incompatible values - let n = rsa.n().to_owned().map_err(wrap_openssl_err)?; - let e = rsa.e().to_owned().map_err(wrap_openssl_err)?; - let d = rsa.d().to_owned().map_err(wrap_openssl_err)?; - let po = rsa.p(); - let qo = rsa.q(); - let dmp1o = rsa.dmp1(); - let dmq1o = rsa.dmq1(); - let iqmpo = rsa.iqmp(); - let mut builder = RsaPrivateKeyBuilder::new(n, e, d).map_err(wrap_openssl_err)?; - - if let Some(p) = po { - if let Some(q) = qo { - builder = builder - .set_factors(p.to_owned()?, q.to_owned()?) - .map_err(wrap_openssl_err)?; - } - } - - if let Some(dmp1) = dmp1o { - if let Some(dmq1) = dmq1o { - if let Some(iqmp) = iqmpo { - builder = builder - .set_crt_params(dmp1.to_owned()?, dmq1.to_owned()?, iqmp.to_owned()?) - .map_err(wrap_openssl_err)?; - } - } - } - - let new_rsa = builder.build(); - - let pkey = PKey::from_rsa(new_rsa).map_err(wrap_openssl_err)?; - - let signer = RsaSigner { - signcerts, - pkey, - certs_size: signcert.len(), - timestamp_size: 10000, /* todo: call out to TSA to get actual timestamp and use that size */ - ocsp_size: Cell::new(0), - alg, - tsa_url, - ocsp_rsp: Cell::new(OcspResponse::default()), - }; - - // get OCSP if possible - signer.update_ocsp(); - - Ok(signer) - } -} - -impl Signer for RsaSigner { - fn sign(&self, data: &[u8]) -> Result> { - let mut signer = match self.alg { - SigningAlg::Ps256 => { - let mut signer = openssl::sign::Signer::new(MessageDigest::sha256(), &self.pkey) - .map_err(wrap_openssl_err)?; - - signer.set_rsa_padding(openssl::rsa::Padding::PKCS1_PSS)?; // use C2PA recommended padding - signer.set_rsa_mgf1_md(MessageDigest::sha256())?; - signer.set_rsa_pss_saltlen(openssl::sign::RsaPssSaltlen::DIGEST_LENGTH)?; - signer - } - SigningAlg::Ps384 => { - let mut signer = openssl::sign::Signer::new(MessageDigest::sha384(), &self.pkey) - .map_err(wrap_openssl_err)?; - - signer.set_rsa_padding(openssl::rsa::Padding::PKCS1_PSS)?; // use C2PA recommended padding - signer.set_rsa_mgf1_md(MessageDigest::sha384())?; - signer.set_rsa_pss_saltlen(openssl::sign::RsaPssSaltlen::DIGEST_LENGTH)?; - signer - } - SigningAlg::Ps512 => { - let mut signer = openssl::sign::Signer::new(MessageDigest::sha512(), &self.pkey) - .map_err(wrap_openssl_err)?; - - signer.set_rsa_padding(openssl::rsa::Padding::PKCS1_PSS)?; // use C2PA recommended padding - signer.set_rsa_mgf1_md(MessageDigest::sha512())?; - signer.set_rsa_pss_saltlen(openssl::sign::RsaPssSaltlen::DIGEST_LENGTH)?; - signer - } - // "rs256" => openssl::sign::Signer::new(MessageDigest::sha256(), &self.pkey) - // .map_err(wrap_openssl_err)?, - // "rs384" => openssl::sign::Signer::new(MessageDigest::sha384(), &self.pkey) - // .map_err(wrap_openssl_err)?, - // "rs512" => openssl::sign::Signer::new(MessageDigest::sha512(), &self.pkey) - // .map_err(wrap_openssl_err)?, - _ => return Err(Error::UnsupportedType), - }; - - let signed_data = signer.sign_oneshot_to_vec(data)?; - - // println!("sig: {}", Hexlify(&signed_data)); - - Ok(signed_data) - } - - fn reserve_size(&self) -> usize { - 1024 + self.certs_size + self.timestamp_size + self.ocsp_size.get() // the Cose_Sign1 contains complete certs, timestamps and ocsp so account for size - } - - fn certs(&self) -> Result>> { - let _openssl = OpenSslMutex::acquire()?; - self.certs_internal() - } - - fn alg(&self) -> SigningAlg { - self.alg - } - - fn ocsp_val(&self) -> Option> { - let _openssl = OpenSslMutex::acquire().ok()?; - - // update OCSP if needed - self.update_ocsp(); - - let ocsp_data = self.ocsp_rsp.take(); - let ocsp_rsp = ocsp_data.ocsp_der.clone(); - self.ocsp_rsp.set(ocsp_data); - if !ocsp_rsp.is_empty() { - Some(ocsp_rsp) - } else { - None - } - } -} - -impl TimeStampProvider for RsaSigner { - fn time_stamp_service_url(&self) -> Option { - self.tsa_url.clone() - } -} - -fn wrap_openssl_err(err: openssl::error::ErrorStack) -> Error { - Error::OpenSslError(err) -} - -#[allow(unused_imports)] -#[allow(clippy::unwrap_used)] -#[cfg(test)] -mod tests { - - use super::*; - use crate::{ - utils::test::{fixture_path, temp_signer}, - Signer, SigningAlg, - }; - - #[test] - fn signer_from_files() { - let signer = temp_signer(); - let data = b"some sample content to sign"; - - let signature = signer.sign(data).unwrap(); - println!("signature len = {}", signature.len()); - assert!(signature.len() <= signer.reserve_size()); - } - - #[test] - fn sign_ps256() { - let cert_bytes = include_bytes!("../../tests/fixtures/temp_cert.data"); - let key_bytes = include_bytes!("../../tests/fixtures/temp_priv_key.data"); - - let signer = - RsaSigner::from_signcert_and_pkey(cert_bytes, key_bytes, SigningAlg::Ps256, None) - .unwrap(); - - let data = b"some sample content to sign"; - - let signature = signer.sign(data).unwrap(); - println!("signature len = {}", signature.len()); - assert!(signature.len() <= signer.reserve_size()); - } - - // #[test] - // fn sign_rs256() { - // let cert_bytes = include_bytes!("../../tests/fixtures/temp_cert.data"); - // let key_bytes = include_bytes!("../../tests/fixtures/temp_priv_key.data"); - - // let signer = - // RsaSigner::from_signcert_and_pkey(cert_bytes, key_bytes, "rs256".to_string(), None) - // .unwrap(); - - // let data = b"some sample content to sign"; - - // let signature = signer.sign(data).unwrap(); - // println!("signature len = {}", signature.len()); - // assert!(signature.len() <= signer.reserve_size()); - // } -} diff --git a/sdk/src/openssl/temp_signer.rs b/sdk/src/openssl/temp_signer.rs deleted file mode 100644 index 411615cdf..000000000 --- a/sdk/src/openssl/temp_signer.rs +++ /dev/null @@ -1,184 +0,0 @@ -// Copyright 2022 Adobe. All rights reserved. -// This file is licensed to you under the Apache License, -// Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0) -// or the MIT license (http://opensource.org/licenses/MIT), -// at your option. - -// Unless required by applicable law or agreed to in writing, -// this software is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR REPRESENTATIONS OF ANY KIND, either express or -// implied. See the LICENSE-MIT and LICENSE-APACHE files for the -// specific language governing permissions and limitations under -// each license. - -#![deny(missing_docs)] - -//! Temporary signing instances for testing purposes. -//! -//! This module contains functions to create self-signed certificates -//! and provision [`Signer`] instances for each of the supported signature -//! formats. -//! -//! Private-key and signing certificate pairs are created in a directory -//! provided by the caller. It is recommended to use a temporary directory -//! that is deleted upon completion of the test. (We recommend using -//! the [tempfile](https://crates.io/crates/tempfile) crate.) -//! -//! This module should be used only for testing purposes. - -// Since this module is intended for testing purposes, all of -// its functions are allowed to panic. -#![allow(clippy::panic)] -#![allow(clippy::unwrap_used)] - -#[cfg(feature = "file_io")] -use std::path::{Path, PathBuf}; - -#[cfg(feature = "file_io")] -use c2pa_crypto::SigningAlg; - -#[cfg(feature = "file_io")] -use crate::{ - openssl::{EcSigner, EdSigner, RsaSigner}, - signer::ConfigurableSigner, -}; - -/// Create an OpenSSL ES256 signer that can be used for testing purposes. -/// -/// # Arguments -/// -/// * `path` - A directory (which must already exist) to receive the temporary -/// private key / certificate pair. -/// * `alg` - A format for signing. Must be one of the `SigningAlg::Es*` variants. -/// * `tsa_url` - Optional URL for a timestamp authority. -/// -/// # Returns -/// -/// Returns a tuple of `(signer, sign_cert_path)` where `signer` is -/// the [`Signer`] instance and `sign_cert_path` is the path to the -/// signing certificate. -/// -/// # Panics -/// -/// Can panic if unable to invoke OpenSSL executable properly. -#[cfg(feature = "file_io")] -pub fn get_ec_signer>( - path: P, - alg: SigningAlg, - tsa_url: Option, -) -> (EcSigner, PathBuf) { - match alg { - SigningAlg::Es256 | SigningAlg::Es384 | SigningAlg::Es512 => (), - _ => { - panic!("Unknown EC signer alg {alg:#?}"); - } - } - - let mut sign_cert_path = path.as_ref().to_path_buf(); - sign_cert_path.push(alg.to_string()); - sign_cert_path.set_extension("pub"); - - let mut pem_key_path = path.as_ref().to_path_buf(); - pem_key_path.push(alg.to_string()); - pem_key_path.set_extension("pem"); - - ( - EcSigner::from_files(&sign_cert_path, &pem_key_path, alg, tsa_url).unwrap(), - sign_cert_path, - ) -} - -/// Create an OpenSSL ES256 signer that can be used for testing purposes. -/// -/// # Arguments -/// -/// * `path` - A directory (which must already exist) to look for -/// private key / certificate pair. -/// * `alg` - A format for signing. Must be `ed25519`. -/// * `tsa_url` - Optional URL for a timestamp authority. -/// -/// # Returns -/// -/// Returns a tuple of `(signer, sign_cert_path)` where `signer` is -/// the [`Signer`] instance and `sign_cert_path` is the path to the -/// signing certificate. -/// -/// # Panics -/// -/// Can panic if unable to invoke OpenSSL executable properly. -#[cfg(feature = "file_io")] -pub fn get_ed_signer>( - path: P, - alg: SigningAlg, - tsa_url: Option, -) -> (EdSigner, PathBuf) { - if alg != SigningAlg::Ed25519 { - panic!("Unknown ED signer alg {alg:#?}"); - } - - let mut sign_cert_path = path.as_ref().to_path_buf(); - sign_cert_path.push(alg.to_string()); - sign_cert_path.set_extension("pub"); - - let mut pem_key_path = path.as_ref().to_path_buf(); - pem_key_path.push(alg.to_string()); - pem_key_path.set_extension("pem"); - - ( - EdSigner::from_files(&sign_cert_path, &pem_key_path, alg, tsa_url).unwrap(), - sign_cert_path, - ) -} - -/// Create an OpenSSL SHA+RSA signer that can be used for testing purposes. -/// -/// # Arguments -/// -/// * `path` - A directory (which must already exist) to receive the temporary -/// private key / certificate pair. -/// * `alg` - A format for signing. Must be one of the `SignerAlg::Ps*` options. -/// * `tsa_url` - Optional URL for a timestamp authority. -/// -/// # Returns -/// -/// Returns a tuple of `(signer, sign_cert_path)` where `signer` is -/// the [`Signer`] instance and `sign_cert_path` is the path to the -/// signing certificate. -/// -/// # Panics -/// -/// Can panic if unable to invoke OpenSSL executable properly. -#[cfg(feature = "file_io")] -pub fn get_rsa_signer>( - path: P, - alg: SigningAlg, - tsa_url: Option, -) -> (RsaSigner, PathBuf) { - match alg { - SigningAlg::Ps256 | SigningAlg::Ps384 | SigningAlg::Ps512 => (), - _ => { - panic!("Unknown RSA signer alg {alg:#?}"); - } - } - - let mut sign_cert_path = path.as_ref().to_path_buf(); - sign_cert_path.push(alg.to_string()); - sign_cert_path.set_extension("pub"); - - let mut pem_key_path = path.as_ref().to_path_buf(); - pem_key_path.push(alg.to_string()); - pem_key_path.set_extension("pem"); - - if !sign_cert_path.exists() || !pem_key_path.exists() { - panic!( - "path found: {}, {}", - sign_cert_path.display(), - pem_key_path.display() - ); - } - - ( - RsaSigner::from_files(&sign_cert_path, &pem_key_path, alg, tsa_url).unwrap(), - sign_cert_path, - ) -} diff --git a/sdk/src/openssl/temp_signer_async.rs b/sdk/src/openssl/temp_signer_async.rs deleted file mode 100644 index 4dc81fa2a..000000000 --- a/sdk/src/openssl/temp_signer_async.rs +++ /dev/null @@ -1,101 +0,0 @@ -// Copyright 2022 Adobe. All rights reserved. -// This file is licensed to you under the Apache License, -// Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0) -// or the MIT license (http://opensource.org/licenses/MIT), -// at your option. - -// Unless required by applicable law or agreed to in writing, -// this software is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR REPRESENTATIONS OF ANY KIND, either express or -// implied. See the LICENSE-MIT and LICENSE-APACHE files for the -// specific language governing permissions and limitations under -// each license. - -#![deny(missing_docs)] - -//! Temporary async signing instances for testing purposes. -//! -//! This is only a demonstration async Signer that is used to test -//! the asynchronous signing of claims. -//! This module should be used only for testing purposes. - -#[cfg(feature = "openssl_sign")] -use c2pa_crypto::SigningAlg; - -#[cfg(feature = "openssl_sign")] -fn get_local_signer(alg: SigningAlg) -> Box { - let cert_dir = crate::utils::test::fixture_path("certs"); - - match alg { - SigningAlg::Ps256 | SigningAlg::Ps384 | SigningAlg::Ps512 => { - let (s, _k) = super::temp_signer::get_rsa_signer(&cert_dir, alg, None); - Box::new(s) - } - SigningAlg::Es256 | SigningAlg::Es384 | SigningAlg::Es512 => { - let (s, _k) = super::temp_signer::get_ec_signer(&cert_dir, alg, None); - Box::new(s) - } - SigningAlg::Ed25519 => { - let (s, _k) = super::temp_signer::get_ed_signer(&cert_dir, alg, None); - Box::new(s) - } - } -} - -#[cfg(feature = "openssl_sign")] -pub struct AsyncSignerAdapter { - alg: SigningAlg, - certs: Vec>, - reserve_size: usize, - tsa_url: Option, - ocsp_val: Option>, -} - -#[cfg(feature = "openssl_sign")] -impl AsyncSignerAdapter { - pub fn new(alg: SigningAlg) -> Self { - let signer = get_local_signer(alg); - - AsyncSignerAdapter { - alg, - certs: signer.certs().unwrap_or_default(), - reserve_size: signer.reserve_size(), - tsa_url: signer.time_authority_url(), - ocsp_val: signer.ocsp_val(), - } - } -} - -#[cfg(test)] -#[cfg(feature = "openssl_sign")] -#[async_trait::async_trait] -impl crate::AsyncSigner for AsyncSignerAdapter { - async fn sign(&self, data: Vec) -> crate::error::Result> { - let signer = get_local_signer(self.alg); - signer.sign(&data) - } - - fn alg(&self) -> SigningAlg { - self.alg - } - - fn certs(&self) -> crate::Result>> { - let mut output: Vec> = Vec::new(); - for v in &self.certs { - output.push(v.clone()); - } - Ok(output) - } - - fn reserve_size(&self) -> usize { - self.reserve_size - } - - fn time_authority_url(&self) -> Option { - self.tsa_url.clone() - } - - async fn ocsp_val(&self) -> Option> { - self.ocsp_val.clone() - } -} diff --git a/sdk/src/resource_store.rs b/sdk/src/resource_store.rs index 6d6eff8f4..c5229d23b 100644 --- a/sdk/src/resource_store.rs +++ b/sdk/src/resource_store.rs @@ -404,8 +404,10 @@ mod tests { use std::io::Cursor; + use c2pa_crypto::SigningAlg; + use super::*; - use crate::{utils::test::temp_signer, Builder, Reader}; + use crate::{utils::test_signer::test_signer, Builder, Reader}; #[test] #[cfg(feature = "openssl_sign")] @@ -451,7 +453,8 @@ mod tests { let image = include_bytes!("../tests/fixtures/earth_apollo17.jpg"); - let signer = temp_signer(); + let signer = test_signer(SigningAlg::Ps256); + // Embed a manifest using the signer. let mut output_image = Cursor::new(Vec::new()); builder diff --git a/sdk/src/signer.rs b/sdk/src/signer.rs index cc42fa37a..72c37b436 100644 --- a/sdk/src/signer.rs +++ b/sdk/src/signer.rs @@ -12,7 +12,7 @@ // each license. use async_trait::async_trait; -use c2pa_crypto::SigningAlg; +use c2pa_crypto::{raw_signature::RawSigner, SigningAlg}; use crate::{DynamicAssertion, Result}; @@ -107,10 +107,8 @@ pub(crate) trait ConfigurableSigner: Signer + Sized { alg: SigningAlg, tsa_url: Option, ) -> Result { - use crate::Error; - - let signcert = std::fs::read(signcert_path).map_err(Error::IoError)?; - let pkey = std::fs::read(pkey_path).map_err(Error::IoError)?; + let signcert = std::fs::read(signcert_path).map_err(crate::Error::IoError)?; + let pkey = std::fs::read(pkey_path).map_err(crate::Error::IoError)?; Self::from_signcert_and_pkey(&signcert, &pkey, alg, tsa_url) } @@ -300,7 +298,7 @@ pub trait RemoteSigner: Sync { fn reserve_size(&self) -> usize; } -impl Signer for Box { +impl Signer for Box { fn sign(&self, data: &[u8]) -> Result> { (**self).sign(data) } @@ -328,4 +326,161 @@ impl Signer for Box { fn dynamic_assertions(&self) -> Vec> { (**self).dynamic_assertions() } + + fn time_authority_url(&self) -> Option { + (**self).time_authority_url() + } + + fn timestamp_request_headers(&self) -> Option> { + (**self).timestamp_request_headers() + } + + fn timestamp_request_body(&self, message: &[u8]) -> Result> { + (**self).timestamp_request_body(message) + } + + fn send_timestamp_request(&self, message: &[u8]) -> Option>> { + (**self).send_timestamp_request(message) + } +} + +#[cfg(not(target_arch = "wasm32"))] +#[async_trait] +impl AsyncSigner for Box { + async fn sign(&self, data: Vec) -> Result> { + (**self).sign(data).await + } + + fn alg(&self) -> SigningAlg { + (**self).alg() + } + + fn certs(&self) -> Result>> { + (**self).certs() + } + + fn reserve_size(&self) -> usize { + (**self).reserve_size() + } + + fn time_authority_url(&self) -> Option { + (**self).time_authority_url() + } + + fn timestamp_request_headers(&self) -> Option> { + (**self).timestamp_request_headers() + } + + fn timestamp_request_body(&self, message: &[u8]) -> Result> { + (**self).timestamp_request_body(message) + } + + async fn send_timestamp_request(&self, message: &[u8]) -> Option>> { + (**self).send_timestamp_request(message).await + } + + async fn ocsp_val(&self) -> Option> { + (**self).ocsp_val().await + } + + fn direct_cose_handling(&self) -> bool { + (**self).direct_cose_handling() + } + + fn dynamic_assertions(&self) -> Vec> { + (**self).dynamic_assertions() + } +} + +#[cfg(target_arch = "wasm32")] +#[async_trait(?Send)] +impl AsyncSigner for Box { + async fn sign(&self, data: Vec) -> Result> { + (**self).sign(data).await + } + + fn alg(&self) -> SigningAlg { + (**self).alg() + } + + fn certs(&self) -> Result>> { + (**self).certs() + } + + fn reserve_size(&self) -> usize { + (**self).reserve_size() + } + + fn time_authority_url(&self) -> Option { + (**self).time_authority_url() + } + + fn timestamp_request_headers(&self) -> Option> { + (**self).timestamp_request_headers() + } + + fn timestamp_request_body(&self, message: &[u8]) -> Result> { + (**self).timestamp_request_body(message) + } + + async fn send_timestamp_request(&self, message: &[u8]) -> Option>> { + (**self).send_timestamp_request(message).await + } + + async fn ocsp_val(&self) -> Option> { + (**self).ocsp_val().await + } + + fn direct_cose_handling(&self) -> bool { + (**self).direct_cose_handling() + } + + fn dynamic_assertions(&self) -> Vec> { + (**self).dynamic_assertions() + } +} + +#[cfg_attr(target_arch = "wasm32", allow(dead_code))] +pub(crate) struct RawSignerWrapper(pub(crate) Box); + +impl Signer for RawSignerWrapper { + fn sign(&self, data: &[u8]) -> Result> { + self.0.sign(data).map_err(|e| e.into()) + } + + fn alg(&self) -> SigningAlg { + self.0.alg() + } + + fn certs(&self) -> Result>> { + self.0.cert_chain().map_err(|e| e.into()) + } + + fn reserve_size(&self) -> usize { + self.0.reserve_size() + } + + fn ocsp_val(&self) -> Option> { + self.0.ocsp_response() + } + + fn time_authority_url(&self) -> Option { + self.0.time_stamp_service_url() + } + + fn timestamp_request_headers(&self) -> Option> { + self.0.time_stamp_request_headers() + } + + fn timestamp_request_body(&self, message: &[u8]) -> Result> { + self.0 + .time_stamp_request_body(message) + .map_err(|e| e.into()) + } + + fn send_timestamp_request(&self, message: &[u8]) -> Option>> { + self.0 + .send_time_stamp_request(message) + .map(|r| r.map_err(|e| e.into())) + } } diff --git a/sdk/src/store.rs b/sdk/src/store.rs index a560a0970..31d56a5e0 100644 --- a/sdk/src/store.rs +++ b/sdk/src/store.rs @@ -510,7 +510,8 @@ impl Store { } else { if signer.direct_cose_handling() { // Let the signer do all the COSE processing and return the structured COSE data. - return signer.sign(claim_bytes.clone()).await; // do not verify remote signers (we never did) + return signer.sign(claim_bytes.clone()).await; + // do not verify remote signers (we never did) } else { cose_sign_async(signer, &claim_bytes, box_size).await } @@ -3644,9 +3645,10 @@ pub mod tests { hash_utils::Hasher, patch::patch_file, test::{ - create_test_claim, fixture_path, temp_dir_path, temp_fixture_path, temp_signer, + create_test_claim, fixture_path, temp_dir_path, temp_fixture_path, write_jpeg_placeholder_file, }, + test_signer::{async_test_signer, test_signer}, }, }; @@ -3697,7 +3699,7 @@ pub mod tests { create_capture_claim(&mut claim_capture).unwrap(); // Do we generate JUMBF? - let signer = temp_signer(); + let signer = test_signer(SigningAlg::Ps256); // Test generate JUMBF // Get labels for label test @@ -3810,7 +3812,7 @@ pub mod tests { create_capture_claim(&mut claim_capture).unwrap(); // Do we generate JUMBF? - let signer = temp_signer(); + let signer = test_signer(SigningAlg::Ps256); // Move the claim to claims list. Note this is not real, the claims would have to be signed in between commits store.commit_claim(claim1).unwrap(); @@ -3850,7 +3852,7 @@ pub mod tests { struct BadSigner {} - impl crate::Signer for BadSigner { + impl Signer for BadSigner { fn sign(&self, _data: &[u8]) -> Result> { Ok(b"not a valid signature".to_vec()) } @@ -3895,7 +3897,9 @@ pub mod tests { #[test] #[cfg(feature = "file_io")] fn test_sign_with_expired_cert() { - use crate::{openssl::RsaSigner, signer::ConfigurableSigner, SigningAlg}; + use c2pa_crypto::SigningAlg; + + use crate::create_signer; // test adding to actual image let ap = fixture_path("earth_apollo17.jpg"); @@ -3909,7 +3913,7 @@ pub mod tests { let signcert_path = fixture_path("rsa-pss256_key-expired.pub"); let pkey_path = fixture_path("rsa-pss256-expired.pem"); let signer = - RsaSigner::from_files(signcert_path, pkey_path, SigningAlg::Ps256, None).unwrap(); + create_signer::from_files(signcert_path, pkey_path, SigningAlg::Ps256, None).unwrap(); store.commit_claim(claim).unwrap(); @@ -3955,7 +3959,7 @@ pub mod tests { #[actix::test] async fn test_jumbf_generation_async() { - let signer = crate::openssl::temp_signer_async::AsyncSignerAdapter::new(SigningAlg::Ps256); + let signer = async_test_signer(SigningAlg::Ps256); // test adding to actual image let ap = fixture_path("earth_apollo17.jpg"); @@ -4080,7 +4084,7 @@ pub mod tests { create_capture_claim(&mut claim_capture).unwrap(); // Do we generate JUMBF? - let signer = temp_signer(); + let signer = test_signer(SigningAlg::Ps256); // Move the claim to claims list. Note this is not real, the claims would have to be signed in between commits store.commit_claim(claim1).unwrap(); @@ -4176,7 +4180,7 @@ pub mod tests { create_capture_claim(&mut claim_capture).unwrap(); // Do we generate JUMBF? - let signer = temp_signer(); + let signer = test_signer(SigningAlg::Ps256); // Move the claim to claims list. Note this is not real, the claims would have to be signed in between commmits store.commit_claim(claim1).unwrap(); @@ -4249,7 +4253,7 @@ pub mod tests { create_capture_claim(&mut claim_capture).unwrap(); // Do we generate JUMBF? - let signer = temp_signer(); + let signer = test_signer(SigningAlg::Ps256); // Move the claim to claims list. Note this is not real, the claims would have to be signed in between commmits store.commit_claim(claim1).unwrap(); @@ -4323,7 +4327,7 @@ pub mod tests { create_capture_claim(&mut claim_capture).unwrap(); // Do we generate JUMBF? - let signer = temp_signer(); + let signer = test_signer(SigningAlg::Ps256); // Move the claim to claims list. Note this is not real, the claims would have to be signed in between commits store.commit_claim(claim1).unwrap(); @@ -4397,7 +4401,7 @@ pub mod tests { create_capture_claim(&mut claim_capture).unwrap(); // Do we generate JUMBF? - let signer = temp_signer(); + let signer = test_signer(SigningAlg::Ps256); // Move the claim to claims list. Note this is not real, the claims would have to be signed in between commits store.commit_claim(claim1).unwrap(); @@ -4471,7 +4475,7 @@ pub mod tests { create_capture_claim(&mut claim_capture).unwrap(); // Do we generate JUMBF? - let signer = temp_signer(); + let signer = test_signer(SigningAlg::Ps256); // Move the claim to claims list. Note this is not real, the claims would have to be signed in between commits store.commit_claim(claim1).unwrap(); @@ -4537,7 +4541,7 @@ pub mod tests { let claim1 = create_test_claim().unwrap(); // Do we generate JUMBF? - let signer = temp_signer(); + let signer = test_signer(SigningAlg::Ps256); // Move the claim to claims list. Note this is not real, the claims would have to be signed in between commits store.commit_claim(claim1).unwrap(); @@ -4581,7 +4585,7 @@ pub mod tests { let claim1 = create_test_claim().unwrap(); // Do we generate JUMBF? - let signer = temp_signer(); + let signer = test_signer(SigningAlg::Ps256); // Move the claim to claims list. Note this is not real, the claims would have to be signed in between commits store.commit_claim(claim1).unwrap(); @@ -4625,7 +4629,7 @@ pub mod tests { let claim1 = create_test_claim().unwrap(); // Do we generate JUMBF? - let signer = temp_signer(); + let signer = test_signer(SigningAlg::Ps256); // Move the claim to claims list. Note this is not real, the claims would have to be signed in between commits store.commit_claim(claim1).unwrap(); @@ -4751,7 +4755,7 @@ pub mod tests { fn test_verifiable_credentials() { use crate::utils::test::create_test_store; - let signer = temp_signer(); + let signer = test_signer(SigningAlg::Ps256); // test adding to actual image let ap = fixture_path("earth_apollo17.jpg"); @@ -4789,7 +4793,7 @@ pub mod tests { fn test_data_box_creation() { use crate::utils::test::create_test_store; - let signer = temp_signer(); + let signer = test_signer(SigningAlg::Ps256); // test adding to actual image let ap = fixture_path("earth_apollo17.jpg"); @@ -4844,7 +4848,7 @@ pub mod tests { fn test_update_manifest() { use crate::{hashed_uri::HashedUri, utils::test::create_test_store}; - let signer = temp_signer(); + let signer = test_signer(SigningAlg::Ps256); // test adding to actual image let ap = fixture_path("earth_apollo17.jpg"); @@ -5019,7 +5023,7 @@ pub mod tests { // Create a new claim. let claim1 = create_test_claim().unwrap(); - let signer = temp_signer(); + let signer = test_signer(SigningAlg::Ps256); // Move the claim to claims list. store.commit_claim(claim1).unwrap(); @@ -5049,7 +5053,7 @@ pub mod tests { // Create a new claim. let claim1 = create_test_claim().unwrap(); - let signer = temp_signer(); + let signer = test_signer(SigningAlg::Ps256); let result: Vec = Vec::new(); let mut output_stream = Cursor::new(result); @@ -5111,7 +5115,7 @@ pub mod tests { claim.set_external_manifest(); // Do we generate JUMBF? - let signer = temp_signer(); + let signer = test_signer(SigningAlg::Ps256); store.commit_claim(claim).unwrap(); @@ -5148,7 +5152,7 @@ pub mod tests { let mut claim = create_test_claim().unwrap(); // Do we generate JUMBF? - let signer = temp_signer(); + let signer = test_signer(SigningAlg::Ps256); // start with base url let fp = format!("file:/{}", sidecar.to_str().unwrap()); @@ -5216,7 +5220,7 @@ pub mod tests { let mut claim = create_test_claim().unwrap(); // Do we generate JUMBF? - let signer = temp_signer(); + let signer = test_signer(SigningAlg::Ps256); // start with base url let fp = format!("file:/{}", sidecar.to_str().unwrap()); @@ -5268,7 +5272,7 @@ pub mod tests { let mut claim = create_test_claim().unwrap(); // Do we generate JUMBF? - let signer = temp_signer(); + let signer = test_signer(SigningAlg::Ps256); // start with base url let fp = format!("file:/{}", sidecar.to_str().unwrap()); @@ -5324,7 +5328,7 @@ pub mod tests { // Create a new claim. let claim1 = create_test_claim().unwrap(); - let signer = temp_signer(); + let signer = test_signer(SigningAlg::Ps256); store.commit_claim(claim1).unwrap(); @@ -5378,7 +5382,7 @@ pub mod tests { create_capture_claim(&mut claim_capture).unwrap(); // Do we generate JUMBF? - let signer = temp_signer(); + let signer = test_signer(SigningAlg::Ps256); // Move the claim to claims list. Note this is not real, the claims would have to be signed in between commits store.commit_claim(claim1).unwrap(); @@ -5448,7 +5452,7 @@ pub mod tests { store.commit_claim(claim).unwrap(); // Do we generate JUMBF? - let signer = crate::openssl::temp_signer_async::AsyncSignerAdapter::new(SigningAlg::Ps256); + let signer = async_test_signer(SigningAlg::Ps256); // get the embeddable manifest let em = store @@ -5534,7 +5538,7 @@ pub mod tests { store.commit_claim(claim).unwrap(); // Do we generate JUMBF? - let signer = temp_signer(); + let signer = test_signer(SigningAlg::Ps256); // get the embeddable manifest let em = store @@ -5597,12 +5601,12 @@ pub mod tests { #[cfg(feature = "file_io")] async fn test_datahash_embeddable_manifest_async() { // test adding to actual image - use std::io::SeekFrom; + let ap = fixture_path("cloud.jpg"); // Do we generate JUMBF? - let signer = crate::openssl::temp_signer_async::AsyncSignerAdapter::new(SigningAlg::Ps256); + let signer = async_test_signer(SigningAlg::Ps256); // Create claims store. let mut store = Store::new(); @@ -5671,7 +5675,7 @@ pub mod tests { let ap = fixture_path("cloud.jpg"); // Do we generate JUMBF? - let signer = temp_signer(); + let signer = test_signer(SigningAlg::Ps256); // Create claims store. let mut store = Store::new(); @@ -5742,7 +5746,7 @@ pub mod tests { let mut hasher = Hasher::SHA256(Sha256::new()); // Do we generate JUMBF? - let signer = temp_signer(); + let signer = test_signer(SigningAlg::Ps256); // Create claims store. let mut store = Store::new(); @@ -5848,7 +5852,7 @@ pub mod tests { fn test_placed_manifest() { use crate::jumbf::labels::to_normalized_uri; - let signer = temp_signer(); + let signer = test_signer(SigningAlg::Ps256); // test adding to actual image let ap = fixture_path("C.jpg"); @@ -5968,7 +5972,7 @@ pub mod tests { impl DynamicSigner { fn new() -> Self { - let signer = temp_signer(); + let signer = test_signer(SigningAlg::Ps256); DynamicSigner { alg: signer.alg(), certs: signer.certs().unwrap_or_default(), @@ -5982,7 +5986,7 @@ pub mod tests { #[async_trait::async_trait] impl crate::AsyncSigner for DynamicSigner { async fn sign(&self, data: Vec) -> crate::error::Result> { - let signer = temp_signer(); + let signer = test_signer(SigningAlg::Ps256); signer.sign(&data) } @@ -6095,7 +6099,7 @@ pub mod tests { store.commit_claim(claim).unwrap(); // Do we generate JUMBF? - let signer = temp_signer(); + let signer = test_signer(SigningAlg::Ps256); // add manifest based on let new_output_path = output_path.join(init_dir.file_name().unwrap()); diff --git a/sdk/src/utils/mod.rs b/sdk/src/utils/mod.rs index e63b3a037..5c2887a31 100644 --- a/sdk/src/utils/mod.rs +++ b/sdk/src/utils/mod.rs @@ -19,7 +19,6 @@ pub(crate) mod merkle; pub(crate) mod mime; #[allow(dead_code)] // for wasm build pub(crate) mod patch; -pub(crate) mod sig_utils; #[cfg(feature = "add_thumbnails")] pub(crate) mod thumbnail; pub(crate) mod time_it; @@ -29,3 +28,6 @@ pub(crate) mod xmp_inmemory_utils; #[cfg(test)] #[allow(dead_code)] // for wasm build pub mod test; + +#[cfg(test)] +pub(crate) mod test_signer; diff --git a/sdk/src/utils/sig_utils.rs b/sdk/src/utils/sig_utils.rs deleted file mode 100644 index c5ef223a4..000000000 --- a/sdk/src/utils/sig_utils.rs +++ /dev/null @@ -1,73 +0,0 @@ -// Copyright 2024 Adobe. All rights reserved. -// This file is licensed to you under the Apache License, -// Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0) -// or the MIT license (http://opensource.org/licenses/MIT), -// at your option. - -// Unless required by applicable law or agreed to in writing, -// this software is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR REPRESENTATIONS OF ANY KIND, either express or -// implied. See the LICENSE-MIT and LICENSE-APACHE files for the -// specific language governing permissions and limitations under -// each license. - -use c2pa_crypto::{p1363::parse_ec_der_sig, SigningAlg}; - -use crate::{Error, Result}; - -pub(crate) fn der_to_p1363(data: &[u8], alg: SigningAlg) -> Result> { - // P1363 format: r | s - - let (_, p) = parse_ec_der_sig(data).map_err(|_err| Error::InvalidEcdsaSignature)?; - - let mut r = extfmt::Hexlify(p.r).to_string(); - let mut s = extfmt::Hexlify(p.s).to_string(); - - let sig_len: usize = match alg { - SigningAlg::Es256 => 64, - SigningAlg::Es384 => 96, - SigningAlg::Es512 => 132, - _ => return Err(Error::UnsupportedType), - }; - - // pad or truncate as needed - let rp = if r.len() > sig_len { - // truncate - let offset = r.len() - sig_len; - &r[offset..r.len()] - } else { - // pad - while r.len() != sig_len { - r.insert(0, '0'); - } - r.as_ref() - }; - - let sp = if s.len() > sig_len { - // truncate - let offset = s.len() - sig_len; - &s[offset..s.len()] - } else { - // pad - while s.len() != sig_len { - s.insert(0, '0'); - } - s.as_ref() - }; - - if rp.len() != sig_len || rp.len() != sp.len() { - return Err(Error::InvalidEcdsaSignature); - } - - // merge r and s strings - let mut new_sig = rp.to_string(); - new_sig.push_str(sp); - - // convert back from hex string to byte array - (0..new_sig.len()) - .step_by(2) - .map(|i| { - u8::from_str_radix(&new_sig[i..i + 2], 16).map_err(|_err| Error::InvalidEcdsaSignature) - }) - .collect() -} diff --git a/sdk/src/utils/test.rs b/sdk/src/utils/test.rs index 485dfec82..bfa6f9176 100644 --- a/sdk/src/utils/test.rs +++ b/sdk/src/utils/test.rs @@ -23,8 +23,6 @@ use std::{ use c2pa_crypto::SigningAlg; use tempfile::TempDir; -#[cfg(feature = "file_io")] -use crate::create_signer; use crate::{ assertions::{labels, Action, Actions, Ingredient, ReviewRating, SchemaDotOrg, Thumbnail}, asset_io::CAIReadWrite, @@ -33,12 +31,7 @@ use crate::{ jumbf_io::get_assetio_handler, salt::DefaultSalt, store::Store, - RemoteSigner, Result, Signer, -}; -#[cfg(feature = "openssl_sign")] -use crate::{ - openssl::{AsyncSignerAdapter, RsaSigner}, - signer::ConfigurableSigner, + AsyncSigner, RemoteSigner, Result, }; pub const TEST_SMALL_JPEG: &str = "earth_apollo17.jpg"; @@ -212,7 +205,7 @@ pub fn temp_fixture_path(temp_dir: &TempDir, file_name: &str) -> PathBuf { /// Can panic if the certs cannot be read. (This function should only /// be used as part of testing infrastructure.) #[cfg(feature = "file_io")] -pub fn temp_signer_file() -> RsaSigner { +pub fn temp_signer_file() -> Box { #![allow(clippy::expect_used)] let mut sign_cert_path = fixture_path("certs"); sign_cert_path.push("ps256"); @@ -222,7 +215,7 @@ pub fn temp_signer_file() -> RsaSigner { pem_key_path.push("ps256"); pem_key_path.set_extension("pem"); - RsaSigner::from_files(&sign_cert_path, &pem_key_path, SigningAlg::Ps256, None) + crate::create_signer::from_files(&sign_cert_path, &pem_key_path, SigningAlg::Ps256, None) .expect("get_temp_signer") } @@ -311,7 +304,7 @@ pub(crate) struct AsyncTestGoodSigner {} #[cfg_attr(target_arch = "wasm32", async_trait::async_trait(?Send))] #[cfg_attr(not(target_arch = "wasm32"), async_trait::async_trait)] -impl crate::AsyncSigner for AsyncTestGoodSigner { +impl AsyncSigner for AsyncTestGoodSigner { async fn sign(&self, _data: Vec) -> Result> { Ok(b"not a valid signature".to_vec()) } @@ -336,75 +329,6 @@ impl crate::AsyncSigner for AsyncTestGoodSigner { } } -/// Create a [`Signer`] instance that can be used for testing purposes using ps256 alg. -/// -/// # Returns -/// -/// Returns a boxed [`Signer`] instance. -#[cfg(test)] -pub(crate) fn temp_signer() -> Box { - #[cfg(feature = "openssl_sign")] - { - #![allow(clippy::expect_used)] - let sign_cert = include_bytes!("../../tests/fixtures/certs/ps256.pub").to_vec(); - let pem_key = include_bytes!("../../tests/fixtures/certs/ps256.pem").to_vec(); - - let signer = - RsaSigner::from_signcert_and_pkey(&sign_cert, &pem_key, SigningAlg::Ps256, None) - .expect("get_temp_signer"); - - Box::new(signer) - } - - // todo: the will be a RustTLS signer shortly - #[cfg(not(feature = "openssl_sign"))] - { - Box::new(TestGoodSigner {}) - } -} - -#[cfg(any(target_arch = "wasm32", feature = "openssl_sign"))] -pub fn temp_async_signer() -> Box { - #[cfg(feature = "openssl_sign")] - { - Box::new(AsyncSignerAdapter::new(SigningAlg::Es256)) - } - - #[cfg(target_arch = "wasm32")] - { - let sign_cert = include_str!("../../tests/fixtures/certs/es256.pub"); - let pem_key = include_str!("../../tests/fixtures/certs/es256.pem"); - let signer = WebCryptoSigner::new("es256", sign_cert, pem_key); - Box::new(signer) - } -} - -/// Create a [`Signer`] instance for a specific algorithm that can be used for testing purposes. -/// -/// # Returns -/// -/// Returns a boxed [`Signer`] instance. -/// -/// # Panics -/// -/// Can panic if the certs cannot be read. (This function should only -/// be used as part of testing infrastructure.) -#[cfg(feature = "file_io")] -pub fn temp_signer_with_alg(alg: SigningAlg) -> Box { - #![allow(clippy::expect_used)] - // sign and embed into the target file - let mut sign_cert_path = fixture_path("certs"); - sign_cert_path.push(alg.to_string()); - sign_cert_path.set_extension("pub"); - - let mut pem_key_path = fixture_path("certs"); - pem_key_path.push(alg.to_string()); - pem_key_path.set_extension("pem"); - - create_signer::from_files(sign_cert_path.clone(), pem_key_path, alg, None) - .expect("get_temp_signer_with_alg") -} - struct TempRemoteSigner {} #[cfg_attr(target_arch = "wasm32", async_trait::async_trait(?Send))] @@ -413,8 +337,7 @@ impl crate::signer::RemoteSigner for TempRemoteSigner { async fn sign_remote(&self, claim_bytes: &[u8]) -> crate::error::Result> { #[cfg(feature = "openssl_sign")] { - let signer = - crate::openssl::temp_signer_async::AsyncSignerAdapter::new(SigningAlg::Ps256); + let signer = crate::utils::test_signer::async_test_signer(SigningAlg::Ps256); // this would happen on some remote server crate::cose_sign::cose_sign_async(&signer, claim_bytes, self.reserve_size()).await @@ -559,17 +482,17 @@ struct TempAsyncRemoteSigner { #[cfg_attr(target_arch = "wasm32", async_trait::async_trait(?Send))] #[cfg_attr(not(target_arch = "wasm32"), async_trait::async_trait)] -impl crate::signer::AsyncSigner for TempAsyncRemoteSigner { +impl AsyncSigner for TempAsyncRemoteSigner { // this will not be called but requires an implementation async fn sign(&self, claim_bytes: Vec) -> Result> { #[cfg(feature = "openssl_sign")] { - let signer = - crate::openssl::temp_signer_async::AsyncSignerAdapter::new(SigningAlg::Ps256); + let signer = crate::utils::test_signer::async_test_signer(SigningAlg::Ps256); // this would happen on some remote server crate::cose_sign::cose_sign_async(&signer, &claim_bytes, self.reserve_size()).await } + #[cfg(target_arch = "wasm32")] { let signer = crate::wasm::rsa_wasm_signer::RsaWasmSignerAsync::new(); diff --git a/sdk/src/utils/test_signer.rs b/sdk/src/utils/test_signer.rs new file mode 100644 index 000000000..c9d32a99d --- /dev/null +++ b/sdk/src/utils/test_signer.rs @@ -0,0 +1,146 @@ +// Copyright 2022 Adobe. All rights reserved. +// This file is licensed to you under the Apache License, +// Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0) +// or the MIT license (http://opensource.org/licenses/MIT), +// at your option. + +// Unless required by applicable law or agreed to in writing, +// this software is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR REPRESENTATIONS OF ANY KIND, either express or +// implied. See the LICENSE-MIT and LICENSE-APACHE files for the +// specific language governing permissions and limitations under +// each license. + +#![allow(clippy::unwrap_used)] // This mod is only used in test code. + +use async_trait::async_trait; +use c2pa_crypto::{ + raw_signature::{ + async_signer_from_cert_chain_and_private_key, signer_from_cert_chain_and_private_key, + AsyncRawSigner, + }, + SigningAlg, +}; + +use crate::{signer::RawSignerWrapper, AsyncSigner, Result, Signer}; + +/// Creates a [`Signer`] instance for testing purposes using test credentials. +pub(crate) fn test_signer(alg: SigningAlg) -> Box { + let (cert_chain, private_key) = cert_chain_and_private_key_for_alg(alg); + + Box::new(RawSignerWrapper( + signer_from_cert_chain_and_private_key(&cert_chain, &private_key, alg, None).unwrap(), + )) +} + +/// Creates an [`AsyncSigner`] instance for testing purposes using test credentials. +#[cfg(not(target_arch = "wasm32"))] +pub(crate) fn async_test_signer(alg: SigningAlg) -> Box { + let (cert_chain, private_key) = cert_chain_and_private_key_for_alg(alg); + + Box::new(AsyncRawSignerWrapper( + async_signer_from_cert_chain_and_private_key(&cert_chain, &private_key, alg, None).unwrap(), + )) +} + +/// Creates an [`AsyncSigner`] instance for testing purposes using test credentials. +#[cfg(target_arch = "wasm32")] +pub(crate) fn async_test_signer(alg: SigningAlg) -> Box { + let (cert_chain, private_key) = cert_chain_and_private_key_for_alg(alg); + + Box::new(AsyncRawSignerWrapper( + async_signer_from_cert_chain_and_private_key(&cert_chain, &private_key, alg, None).unwrap(), + )) +} + +fn cert_chain_and_private_key_for_alg(alg: SigningAlg) -> (Vec, Vec) { + match alg { + SigningAlg::Ps256 => ( + include_bytes!("../../tests/fixtures/certs/ps256.pub").to_vec(), + include_bytes!("../../tests/fixtures/certs/ps256.pem").to_vec(), + ), + + SigningAlg::Ps384 => ( + include_bytes!("../../tests/fixtures/certs/ps384.pub").to_vec(), + include_bytes!("../../tests/fixtures/certs/ps384.pem").to_vec(), + ), + + SigningAlg::Ps512 => ( + include_bytes!("../../tests/fixtures/certs/ps512.pub").to_vec(), + include_bytes!("../../tests/fixtures/certs/ps512.pem").to_vec(), + ), + + SigningAlg::Es256 => ( + include_bytes!("../../tests/fixtures/certs/es256.pub").to_vec(), + include_bytes!("../../tests/fixtures/certs/es256.pem").to_vec(), + ), + + SigningAlg::Es384 => ( + include_bytes!("../../tests/fixtures/certs/es384.pub").to_vec(), + include_bytes!("../../tests/fixtures/certs/es384.pem").to_vec(), + ), + + SigningAlg::Es512 => ( + include_bytes!("../../tests/fixtures/certs/es512.pub").to_vec(), + include_bytes!("../../tests/fixtures/certs/es512.pem").to_vec(), + ), + + SigningAlg::Ed25519 => ( + include_bytes!("../../tests/fixtures/certs/ed25519.pub").to_vec(), + include_bytes!("../../tests/fixtures/certs/ed25519.pem").to_vec(), + ), + } +} + +#[cfg(not(target_arch = "wasm32"))] +struct AsyncRawSignerWrapper(Box); + +#[allow(dead_code)] // TEMPORARY: Not used on WASM +#[cfg(target_arch = "wasm32")] +struct AsyncRawSignerWrapper(Box); + +#[allow(dead_code)] // TEMPORARY: Not used on WASM +#[cfg_attr(target_arch = "wasm32", async_trait(?Send))] +#[cfg_attr(not(target_arch = "wasm32"), async_trait)] +impl AsyncSigner for AsyncRawSignerWrapper { + async fn sign(&self, data: Vec) -> Result> { + self.0.sign(data).await.map_err(|e| e.into()) + } + + fn alg(&self) -> SigningAlg { + self.0.alg() + } + + fn certs(&self) -> Result>> { + self.0.cert_chain().map_err(|e| e.into()) + } + + fn reserve_size(&self) -> usize { + self.0.reserve_size() + } + + async fn ocsp_val(&self) -> Option> { + self.0.ocsp_response().await + } + + fn time_authority_url(&self) -> Option { + self.0.time_stamp_service_url() + } + + fn timestamp_request_headers(&self) -> Option> { + self.0.time_stamp_request_headers() + } + + fn timestamp_request_body(&self, message: &[u8]) -> Result> { + self.0 + .time_stamp_request_body(message) + .map_err(|e| e.into()) + } + + async fn send_timestamp_request(&self, message: &[u8]) -> Option>> { + self.0 + .send_time_stamp_request(message) + .await + .map(|r| r.map_err(|e| e.into())) + } +} diff --git a/sdk/src/wasm/rsa_wasm_signer.rs b/sdk/src/wasm/rsa_wasm_signer.rs index cb1cda0fa..4e3320539 100644 --- a/sdk/src/wasm/rsa_wasm_signer.rs +++ b/sdk/src/wasm/rsa_wasm_signer.rs @@ -311,10 +311,7 @@ mod tests { }; use super::*; - use crate::{ - utils::test::{fixture_path, temp_signer}, - Signer, - }; + use crate::{utils::test::fixture_path, Signer}; #[test] fn sign_ps256() { diff --git a/sdk/tests/common/test_signer.rs b/sdk/tests/common/test_signer.rs index c3bd1a2c1..f2ee408f6 100644 --- a/sdk/tests/common/test_signer.rs +++ b/sdk/tests/common/test_signer.rs @@ -12,7 +12,7 @@ // each license. use c2pa::CallbackSigner; -use c2pa_crypto::SigningAlg; +use c2pa_crypto::{raw_signature::RawSignerError, SigningAlg}; const CERTS: &[u8] = include_bytes!("../../tests/fixtures/certs/ed25519.pub"); const PRIVATE_KEY: &[u8] = include_bytes!("../../tests/fixtures/certs/ed25519.pem"); @@ -29,12 +29,13 @@ fn ed_sign(data: &[u8], private_key: &[u8]) -> c2pa::Result> { // Parse the PEM data to get the private key let pem = parse(private_key).map_err(|e| c2pa::Error::OtherError(Box::new(e)))?; + // For Ed25519, the key is 32 bytes long, so we skip the first 16 bytes of the PEM data let key_bytes = &pem.contents()[16..]; - let signing_key = - SigningKey::try_from(key_bytes).map_err(|e| c2pa::Error::OtherError(Box::new(e)))?; + let signing_key = SigningKey::try_from(key_bytes) + .map_err(|e| RawSignerError::InternalError(e.to_string()))?; + // Sign the data let signature: Signature = signing_key.sign(data); - Ok(signature.to_bytes().to_vec()) } diff --git a/sdk/tests/v2_api_integration.rs b/sdk/tests/v2_api_integration.rs index cbeebd0cc..09d6e1b19 100644 --- a/sdk/tests/v2_api_integration.rs +++ b/sdk/tests/v2_api_integration.rs @@ -15,7 +15,6 @@ // Isolate from wasm by wrapping in module. #[cfg(not(target_arch = "wasm32"))] // wasm doesn't support ed25519 yet mod integration_v2 { - use std::io::{Cursor, Seek}; use anyhow::Result; @@ -181,13 +180,14 @@ mod integration_v2 { // Parse the PEM data to get the private key let pem = parse(private_key).map_err(|e| c2pa::Error::OtherError(Box::new(e)))?; + // For Ed25519, the key is 32 bytes long, so we skip the first 16 bytes of the PEM data let key_bytes = &pem.contents()[16..]; let signing_key = SigningKey::try_from(key_bytes).map_err(|e| c2pa::Error::OtherError(Box::new(e)))?; + // Sign the data let signature: Signature = signing_key.sign(data); - Ok(signature.to_bytes().to_vec()) } } From bb3d66e7de96bd0cad568b61ef082ce1db77bdb5 Mon Sep 17 00:00:00 2001 From: Eric Scouten Date: Tue, 10 Dec 2024 17:24:12 -0800 Subject: [PATCH 02/29] chore: Update Cargo.lock and remove from .gitignore --- .gitignore | 2 -- Cargo.lock | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index cfcbfa31b..a43edfdfa 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,5 @@ /target/ -Cargo.lock - **/*.rs.bk .DS_Store diff --git a/Cargo.lock b/Cargo.lock index f392c0d7a..d3302233d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -775,6 +775,7 @@ dependencies = [ name = "c2pa-crypto" version = "0.1.2" dependencies = [ + "actix", "async-generic", "async-trait", "base64 0.22.1", @@ -783,6 +784,7 @@ dependencies = [ "c2pa-status-tracker", "chrono", "ciborium", + "const-hex", "coset", "ecdsa", "ed25519-dalek", @@ -994,6 +996,19 @@ dependencies = [ "web-sys", ] +[[package]] +name = "const-hex" +version = "1.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b0485bab839b018a8f1723fc5391819fea5f8f0f32288ef8a735fd096b6160c" +dependencies = [ + "cfg-if", + "cpufeatures", + "hex", + "proptest", + "serde", +] + [[package]] name = "const-oid" version = "0.9.6" @@ -1361,6 +1376,7 @@ dependencies = [ "ed25519", "serde", "sha2", + "signature", "subtle", "zeroize", ] @@ -3215,6 +3231,22 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "proptest" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4c2511913b88df1637da85cc8d96ec8e43a3f8bb8ccb71ee1ac240d6f3df58d" +dependencies = [ + "bitflags 2.6.0", + "lazy_static", + "num-traits", + "rand", + "rand_chacha", + "rand_xorshift", + "regex-syntax", + "unarray", +] + [[package]] name = "quote" version = "1.0.37" @@ -3269,6 +3301,15 @@ dependencies = [ "zerocopy 0.8.12", ] +[[package]] +name = "rand_xorshift" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d25bf25ec5ae4a3f1b92f929810509a2f53d7dca2f50b794ff57e3face536c8f" +dependencies = [ + "rand_core 0.6.4", +] + [[package]] name = "range-set" version = "0.0.11" @@ -4387,6 +4428,12 @@ version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971" +[[package]] +name = "unarray" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94" + [[package]] name = "unicode-ident" version = "1.0.14" From 60b8ab540c3a40db822b56d47e0306c27b481858 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 10 Dec 2024 17:46:46 -0800 Subject: [PATCH 03/29] update: update zip requirement from 0.6.6 to 2.2.1 in /sdk (#698) * update: update zip requirement from 0.6.6 to 2.2.1 in /sdk --- updated-dependencies: - dependency-name: zip dependency-type: direct:production ... Signed-off-by: dependabot[bot] * Update to use zip's new SimpleFileOptions type * Allow PR titles generated by Dependabot * Bump memchr to 2.7.4 * Update Cargo.lock --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Eric Scouten --- .github/workflows/pr_title.yml | 5 +++ Cargo.lock | 72 +++++++++++++++++++++++++++------- make_test_images/Cargo.toml | 2 +- sdk/Cargo.toml | 4 +- sdk/src/builder.rs | 4 +- 5 files changed, 68 insertions(+), 19 deletions(-) diff --git a/.github/workflows/pr_title.yml b/.github/workflows/pr_title.yml index 1942ae6f6..6af082ed1 100644 --- a/.github/workflows/pr_title.yml +++ b/.github/workflows/pr_title.yml @@ -90,6 +90,11 @@ jobs: exit 0; fi + if echo "$PR_TITLE" | grep -E '^update: update '; then + echo "Exception / OK: Dependabot update pattern" + exit 0; + fi + echo "Installing commitlint-rs. Please wait 30-40 seconds ..." cargo install --quiet commitlint-rs set -e diff --git a/Cargo.lock b/Cargo.lock index d3302233d..9e53a7d2b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -164,6 +164,15 @@ version = "1.0.94" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c1fd03a028ef38ba2276dce7e33fcd6369c158a1bca17946c4b1b701891c1ff7" +[[package]] +name = "arbitrary" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dde20b3d026af13f561bdd0f15edf01fc734f0dafcedbaf42bba506a9517f223" +dependencies = [ + "derive_arbitrary", +] + [[package]] name = "arrayvec" version = "0.7.6" @@ -191,7 +200,7 @@ dependencies = [ "nom", "num-traits", "rusticata-macros", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -206,7 +215,7 @@ dependencies = [ "nom", "num-traits", "rusticata-macros", - "thiserror", + "thiserror 1.0.69", "time", ] @@ -756,7 +765,7 @@ dependencies = [ "sha2", "spki", "tempfile", - "thiserror", + "thiserror 1.0.69", "tokio", "treeline", "ureq", @@ -805,7 +814,7 @@ dependencies = [ "sha1", "sha2", "spki", - "thiserror", + "thiserror 1.0.69", "ureq", "url", "wasm-bindgen", @@ -1265,6 +1274,17 @@ dependencies = [ "serde", ] +[[package]] +name = "derive_arbitrary" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30542c1ad912e0e3d22a1935c290e12e8a29d704a420177a31faad4a601a0800" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.90", +] + [[package]] name = "difflib" version = "0.4.0" @@ -2381,7 +2401,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a32280817bc6e0dbd9aa2abfe52b8fe7405bebc33995649525ecc13ececc3b59" dependencies = [ "nom", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -2673,7 +2693,7 @@ dependencies = [ "num-rational", "serde", "serde_json", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -2988,7 +3008,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "879952a81a83930934cbf1786752d6dedc3b1f29e8f8fb2ad1d0a36f377cf442" dependencies = [ "memchr", - "thiserror", + "thiserror 1.0.69", "ucd-trie", ] @@ -3415,7 +3435,7 @@ checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" dependencies = [ "getrandom", "libredox", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -4193,7 +4213,16 @@ version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" dependencies = [ - "thiserror-impl", + "thiserror-impl 1.0.69", +] + +[[package]] +name = "thiserror" +version = "2.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fec2a1820ebd077e2b90c4df007bebf344cd394098a13c563957d0afc83ea47" +dependencies = [ + "thiserror-impl 2.0.6", ] [[package]] @@ -4207,6 +4236,17 @@ dependencies = [ "syn 2.0.90", ] +[[package]] +name = "thiserror-impl" +version = "2.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d65750cab40f4ff1929fb1ba509e9914eb756131cef4210da8d5d700d26f6312" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.90", +] + [[package]] name = "time" version = "0.3.37" @@ -4892,7 +4932,7 @@ dependencies = [ "ring 0.16.20", "signature", "spki", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -4908,7 +4948,7 @@ dependencies = [ "nom", "oid-registry", "rusticata-macros", - "thiserror", + "thiserror 1.0.69", "time", ] @@ -5028,13 +5068,17 @@ dependencies = [ [[package]] name = "zip" -version = "0.6.6" +version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "760394e246e4c28189f19d488c058bf16f564016aefac5d32bb1f3b51d5e9261" +checksum = "99d52293fc86ea7cf13971b3bb81eb21683636e7ae24c729cdaf1b7c4157a352" dependencies = [ - "byteorder", + "arbitrary", "crc32fast", "crossbeam-utils", + "displaydoc", + "indexmap 2.7.0", + "memchr", + "thiserror 2.0.6", ] [[package]] diff --git a/make_test_images/Cargo.toml b/make_test_images/Cargo.toml index d1e9599ce..01aefa05d 100644 --- a/make_test_images/Cargo.toml +++ b/make_test_images/Cargo.toml @@ -20,7 +20,7 @@ image = { version = "0.25.2", default-features = false, features = [ "jpeg", "png", ] } -memchr = "2.7.1" +memchr = "2.7.4" nom = "7.1.3" regex = "1.5.6" serde = "1.0.197" diff --git a/sdk/Cargo.toml b/sdk/Cargo.toml index 324ea93e2..a1f1827cc 100644 --- a/sdk/Cargo.toml +++ b/sdk/Cargo.toml @@ -99,7 +99,7 @@ jfifdump = "0.5.1" log = "0.4.8" lopdf = { version = "0.31.0", optional = true } lazy_static = "1.4.0" -memchr = "2.7.1" +memchr = "2.7.4" mp4 = "0.14.0" pem = "3.0.2" png_pong = "0.9.1" @@ -127,7 +127,7 @@ url = "2.5.3" uuid = { version = "1.10.0", features = ["serde", "v4", "js"] } x509-parser = "0.16.0" x509-certificate = "0.21.0" -zip = { version = "0.6.6", default-features = false } +zip = { version = "2.2.1", default-features = false } [target.'cfg(not(target_arch = "wasm32"))'.dependencies] ureq = "2.4.0" diff --git a/sdk/src/builder.rs b/sdk/src/builder.rs index 8ac8aa072..5e84ffdfe 100644 --- a/sdk/src/builder.rs +++ b/sdk/src/builder.rs @@ -24,7 +24,7 @@ use schemars::JsonSchema; use serde::{de::DeserializeOwned, Deserialize, Serialize}; use serde_with::skip_serializing_none; use uuid::Uuid; -use zip::{write::FileOptions, ZipArchive, ZipWriter}; +use zip::{write::SimpleFileOptions, ZipArchive, ZipWriter}; use crate::{ assertion::AssertionDecodeError, @@ -453,7 +453,7 @@ impl Builder { { let mut zip = ZipWriter::new(stream); let options = - FileOptions::default().compression_method(zip::CompressionMethod::Stored); + SimpleFileOptions::default().compression_method(zip::CompressionMethod::Stored); // write a version file zip.start_file("version.txt", options) .map_err(|e| Error::OtherError(Box::new(e)))?; From 380e2011eb2726cecba377ca3faf3f60f3bdd231 Mon Sep 17 00:00:00 2001 From: Kornel Date: Wed, 11 Dec 2024 01:56:00 +0000 Subject: [PATCH 04/29] fix: Verbose assertions for `is_none()` (#704) --- internal/crypto/src/tests/ocsp.rs | 2 +- sdk/examples/v2api.rs | 2 +- sdk/src/asset_handlers/gif_io.rs | 2 +- sdk/src/asset_handlers/mp3_io.rs | 2 +- sdk/src/asset_handlers/pdf.rs | 2 +- sdk/src/asset_handlers/pdf_io.rs | 2 +- sdk/src/builder.rs | 12 ++++---- sdk/src/ingredient.rs | 46 +++++++++++++++---------------- sdk/src/jumbf/labels.rs | 2 +- sdk/src/manifest.rs | 18 ++++++------ sdk/src/manifest_store.rs | 12 ++++---- sdk/src/store.rs | 2 +- sdk/tests/v2_api_integration.rs | 2 +- 13 files changed, 53 insertions(+), 53 deletions(-) diff --git a/internal/crypto/src/tests/ocsp.rs b/internal/crypto/src/tests/ocsp.rs index f67a2e7bf..2167161cd 100644 --- a/internal/crypto/src/tests/ocsp.rs +++ b/internal/crypto/src/tests/ocsp.rs @@ -30,7 +30,7 @@ fn good() { let ocsp_data = OcspResponse::from_der_checked(rsp_data, Some(test_time), &mut validation_log).unwrap(); - assert!(ocsp_data.revoked_at.is_none()); + assert_eq!(ocsp_data.revoked_at, None); assert!(ocsp_data.ocsp_certs.is_some()); } diff --git a/sdk/examples/v2api.rs b/sdk/examples/v2api.rs index ac2dd503e..540292a6d 100644 --- a/sdk/examples/v2api.rs +++ b/sdk/examples/v2api.rs @@ -151,7 +151,7 @@ fn main() -> Result<()> { } println!("{}", reader.json()); - assert!(reader.validation_status().is_none()); + assert_eq!(reader.validation_status(), None); assert_eq!(reader.active_manifest().unwrap().title().unwrap(), title); Ok(()) diff --git a/sdk/src/asset_handlers/gif_io.rs b/sdk/src/asset_handlers/gif_io.rs index b1c165418..8c5bba258 100644 --- a/sdk/src/asset_handlers/gif_io.rs +++ b/sdk/src/asset_handlers/gif_io.rs @@ -1459,7 +1459,7 @@ mod tests { let gif_io = GifIO {}; - assert!(gif_io.read_xmp(&mut stream).is_none()); + assert_eq!(gif_io.read_xmp(&mut stream), None); let mut output_stream1 = Cursor::new(Vec::with_capacity(SAMPLE1.len())); gif_io.embed_reference_to_stream( diff --git a/sdk/src/asset_handlers/mp3_io.rs b/sdk/src/asset_handlers/mp3_io.rs index 371f9e6c0..0fd28f955 100644 --- a/sdk/src/asset_handlers/mp3_io.rs +++ b/sdk/src/asset_handlers/mp3_io.rs @@ -592,7 +592,7 @@ pub mod tests { let mp3_io = Mp3IO::new("mp3"); let mut stream = File::open(fixture_path("sample1.mp3"))?; - assert!(mp3_io.read_xmp(&mut stream).is_none()); + assert_eq!(mp3_io.read_xmp(&mut stream), None); stream.rewind()?; let mut output_stream1 = Cursor::new(Vec::new()); diff --git a/sdk/src/asset_handlers/pdf.rs b/sdk/src/asset_handlers/pdf.rs index 96d290c89..370b1ee96 100644 --- a/sdk/src/asset_handlers/pdf.rs +++ b/sdk/src/asset_handlers/pdf.rs @@ -740,7 +740,7 @@ mod tests { #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn test_read_xmp_on_pdf_with_none() { let pdf = Pdf::from_bytes(include_bytes!("../../tests/fixtures/basic-no-xmp.pdf")).unwrap(); - assert!(pdf.read_xmp().is_none()); + assert_eq!(pdf.read_xmp(), None); } #[cfg_attr(not(target_arch = "wasm32"), test)] diff --git a/sdk/src/asset_handlers/pdf_io.rs b/sdk/src/asset_handlers/pdf_io.rs index a56e35fb2..0210b611a 100644 --- a/sdk/src/asset_handlers/pdf_io.rs +++ b/sdk/src/asset_handlers/pdf_io.rs @@ -199,7 +199,7 @@ pub mod tests { mock_pdf.expect_read_xmp().returning(|| None); let pdf_io = PdfIO::new("pdf"); - assert!(pdf_io.read_xmp_from_pdf(mock_pdf).is_none()); + assert_eq!(pdf_io.read_xmp_from_pdf(mock_pdf), None); } #[test] diff --git a/sdk/src/builder.rs b/sdk/src/builder.rs index 5e84ffdfe..130db0cd0 100644 --- a/sdk/src/builder.rs +++ b/sdk/src/builder.rs @@ -1316,7 +1316,7 @@ mod tests { let manifest_store = Reader::from_stream(format, &mut dest).expect("from_bytes"); println!("{}", manifest_store); - assert!(manifest_store.validation_status().is_none()); + assert_eq!(manifest_store.validation_status(), None); assert!(manifest_store.active_manifest().is_some()); let manifest = manifest_store.active_manifest().unwrap(); assert_eq!(manifest.title().unwrap(), "Test_Manifest"); @@ -1345,7 +1345,7 @@ mod tests { let manifest_store = Reader::from_file(&dest).expect("from_bytes"); println!("{}", manifest_store); - assert!(manifest_store.validation_status().is_none()); + assert_eq!(manifest_store.validation_status(), None); assert_eq!( manifest_store.active_manifest().unwrap().title().unwrap(), "Test_Manifest" @@ -1402,7 +1402,7 @@ mod tests { println!("{}", manifest_store); if format != "c2pa" { // c2pa files will not validate since they have no associated asset - assert!(manifest_store.validation_status().is_none()); + assert_eq!(manifest_store.validation_status(), None); } assert_eq!( manifest_store.active_manifest().unwrap().title().unwrap(), @@ -1489,7 +1489,7 @@ mod tests { .expect("from_bytes"); println!("{}", reader.json()); - assert!(reader.validation_status().is_none()); + assert_eq!(reader.validation_status(), None); } #[test] @@ -1548,7 +1548,7 @@ mod tests { let reader = crate::Reader::from_stream("image/jpeg", output_stream).unwrap(); println!("{reader}"); #[cfg(not(target_arch = "wasm32"))] // skip this until we get wasm async signing working - assert!(reader.validation_status().is_none()); + assert_eq!(reader.validation_status(), None); } #[cfg_attr(not(target_arch = "wasm32"), actix::test)] @@ -1644,7 +1644,7 @@ mod tests { let reader = Reader::from_stream("image/jpeg", &mut dest).expect("from_bytes"); //println!("{}", reader); - assert!(reader.validation_status().is_none()); + assert_eq!(reader.validation_status(), None); assert_eq!( reader .active_manifest() diff --git a/sdk/src/ingredient.rs b/sdk/src/ingredient.rs index 4702e7f26..a677a5ff4 100644 --- a/sdk/src/ingredient.rs +++ b/sdk/src/ingredient.rs @@ -1530,13 +1530,13 @@ mod tests { assert_eq!(&ingredient.title, title); assert_eq!(ingredient.format(), format); assert!(ingredient.manifest_data().is_some()); - assert!(ingredient.metadata().is_none()); + assert_eq!(ingredient.metadata(), None); #[cfg(target_arch = "wasm32")] web_sys::console::debug_2( &"ingredient_from_memory_async:".into(), &ingredient.to_string().into(), ); - assert!(ingredient.validation_status().is_none()); + assert_eq!(ingredient.validation_status(), None); } #[cfg_attr(not(target_arch = "wasm32"), test)] @@ -1553,8 +1553,8 @@ mod tests { assert_eq!(&ingredient.title, title); assert_eq!(ingredient.format(), format); assert!(ingredient.manifest_data().is_some()); - assert!(ingredient.metadata().is_none()); - assert!(ingredient.validation_status().is_none()); + assert_eq!(ingredient.metadata(), None); + assert_eq!(ingredient.validation_status(), None); } #[cfg_attr(not(target_arch = "wasm32"), actix::test)] @@ -1574,7 +1574,7 @@ mod tests { #[cfg(feature = "add_thumbnails")] assert!(ingredient.thumbnail().is_some()); assert!(ingredient.manifest_data().is_some()); - assert!(ingredient.metadata().is_none()); + assert_eq!(ingredient.metadata(), None); assert!(ingredient.validation_status().is_some()); assert_eq!( ingredient.validation_status().unwrap()[0].code(), @@ -1597,7 +1597,7 @@ mod tests { assert!(ingredient.provenance().is_some()); assert!(ingredient.provenance().unwrap().starts_with("https:")); assert!(ingredient.manifest_data().is_some()); - assert!(ingredient.validation_status().is_none()); + assert_eq!(ingredient.validation_status(), None); } #[allow(dead_code)] @@ -1619,7 +1619,7 @@ mod tests { .url() .unwrap() .starts_with("http")); - assert!(ingredient.manifest_data().is_none()); + assert_eq!(ingredient.manifest_data(), None); } #[cfg_attr(not(target_arch = "wasm32"), actix::test)] @@ -1640,7 +1640,7 @@ mod tests { &"ingredient_from_memory_async:".into(), &ingredient.to_string().into(), ); - assert!(ingredient.validation_status().is_none()); + assert_eq!(ingredient.validation_status(), None); assert!(ingredient.manifest_data().is_some()); assert!(ingredient.provenance().is_some()); } @@ -1685,7 +1685,7 @@ mod tests_file_io { assert!(ingredient.thumbnail().is_some()); assert_eq!(ingredient.thumbnail().unwrap().0, format); } else { - assert!(ingredient.thumbnail().is_none()); + assert_eq!(ingredient.thumbnail(), None); } } @@ -1701,8 +1701,8 @@ mod tests_file_io { println!("ingredient = {ingredient}"); assert_eq!(ingredient.title(), "Purple Square.psd"); assert_eq!(ingredient.format(), "image/vnd.adobe.photoshop"); - assert!(ingredient.thumbnail().is_none()); // should always be none - assert!(ingredient.manifest_data().is_none()); + assert_eq!(ingredient.thumbnail(), None); // should always be none + assert_eq!(ingredient.manifest_data(), None); } #[test] @@ -1722,7 +1722,7 @@ mod tests_file_io { .identifier .starts_with("self#jumbf=")); assert!(ingredient.manifest_data().is_some()); - assert!(ingredient.metadata().is_none()); + assert_eq!(ingredient.metadata(), None); } #[test] @@ -1736,9 +1736,9 @@ mod tests_file_io { assert_eq!(&ingredient.title, NO_MANIFEST_JPEG); assert_eq!(ingredient.format(), "image/jpeg"); test_thumbnail(&ingredient, "image/jpeg"); - assert!(ingredient.provenance().is_none()); - assert!(ingredient.manifest_data().is_none()); - assert!(ingredient.metadata().is_none()); + assert_eq!(ingredient.provenance(), None); + assert_eq!(ingredient.manifest_data(), None); + assert_eq!(ingredient.metadata(), None); assert!(ingredient.instance_id().starts_with("xmp.iid:")); #[cfg(feature = "add_thumbnails")] assert!(ingredient @@ -1774,8 +1774,8 @@ mod tests_file_io { assert_eq!(ingredient.format(), "image/jpeg"); assert_eq!(ingredient.hash(), Some("1234568abcdef")); assert_eq!(ingredient.thumbnail_ref().unwrap().format, "image/foo"); // always generated - assert!(ingredient.manifest_data().is_none()); - assert!(ingredient.metadata().is_none()); + assert_eq!(ingredient.manifest_data(), None); + assert_eq!(ingredient.metadata(), None); } #[test] @@ -1788,8 +1788,8 @@ mod tests_file_io { println!("ingredient = {ingredient}"); assert_eq!(ingredient.title(), "libpng-test.png"); test_thumbnail(&ingredient, "image/png"); - assert!(ingredient.provenance().is_none()); - assert!(ingredient.manifest_data.is_none()); + assert_eq!(ingredient.provenance(), None); + assert_eq!(ingredient.manifest_data, None); } #[test] @@ -1824,7 +1824,7 @@ mod tests_file_io { assert_eq!(ingredient.format(), "image/jpeg"); test_thumbnail(&ingredient, "image/jpeg"); assert!(ingredient.provenance().is_some()); - assert!(ingredient.manifest_data().is_none()); + assert_eq!(ingredient.manifest_data(), None); assert!(ingredient.validation_status().is_some()); assert_eq!( ingredient.validation_status().unwrap()[0].code(), @@ -1838,7 +1838,7 @@ mod tests_file_io { let ap = fixture_path("CIE-sig-CA.jpg"); let ingredient = Ingredient::from_file(ap).expect("from_file"); // println!("ingredient = {ingredient}"); - assert!(ingredient.validation_status().is_none()); + assert_eq!(ingredient.validation_status(), None); assert!(ingredient.manifest_data().is_some()); } @@ -1890,11 +1890,11 @@ mod tests_file_io { let mut ingredient = Ingredient::new("title", "format", "instance_id"); ingredient.resources.set_base_path(folder); - assert!(ingredient.thumbnail_ref().is_none()); + assert_eq!(ingredient.thumbnail_ref(), None); // assert!(ingredient // .set_manifest_data_ref(ResourceRef::new("image/jpg", "foo")) // .is_err()); - assert!(ingredient.manifest_data_ref().is_none()); + assert_eq!(ingredient.manifest_data_ref(), None); // verify we can set a reference assert!(ingredient .set_thumbnail_ref(ResourceRef::new("image/jpg", "C.jpg")) diff --git a/sdk/src/jumbf/labels.rs b/sdk/src/jumbf/labels.rs index 335915f13..4af28319b 100644 --- a/sdk/src/jumbf/labels.rs +++ b/sdk/src/jumbf/labels.rs @@ -258,7 +258,7 @@ pub mod tests { Some(assertion.to_string()), assertion_label_from_uri(&assertion_uri) ); - assert_eq!(None, assertion_label_from_uri(&absolute_uri)); + assert_eq!(assertion_label_from_uri(&absolute_uri), None); let assertion_relative = to_relative_uri(&assertion_uri); diff --git a/sdk/src/manifest.rs b/sdk/src/manifest.rs index ebfa67153..f6024690e 100644 --- a/sdk/src/manifest.rs +++ b/sdk/src/manifest.rs @@ -1615,7 +1615,7 @@ pub(crate) mod tests { if cfg!(feature = "add_thumbnails") { assert!(manifest.thumbnail().is_some()); } else { - assert!(manifest.thumbnail().is_none()); + assert_eq!(manifest.thumbnail(), None); } let ingredient = Ingredient::from_file(&test_output).expect("load_from_asset"); assert!(ingredient.active_manifest().is_some()); @@ -1819,7 +1819,7 @@ pub(crate) mod tests { let redacted_uri = &claim2.redactions().unwrap()[0]; let claim1 = store3.get_claim(&claim1_label).unwrap(); - assert!(claim1.get_claim_assertion(redacted_uri, 0).is_none()); + assert_eq!(claim1.get_claim_assertion(redacted_uri, 0), None); } #[test] @@ -2593,7 +2593,7 @@ pub(crate) mod tests { assert!(manifest .set_thumbnail_ref(ResourceRef::new("image/jpg", "foo")) .is_err()); - assert!(manifest.thumbnail_ref().is_none()); + assert_eq!(manifest.thumbnail_ref(), None); // verify we can set a references that do exist assert!(manifest .set_thumbnail_ref(ResourceRef::new("image/jpeg", "C.jpg")) @@ -2625,7 +2625,7 @@ pub(crate) mod tests { // verify there is a thumbnail ref assert!(manifest.thumbnail_ref().is_some()); // verify there is no thumbnail - assert!(manifest.thumbnail().is_none()); + assert_eq!(manifest.thumbnail(), None); let signer = test_signer(SigningAlg::Ps256); manifest @@ -2635,8 +2635,8 @@ pub(crate) mod tests { let manifest_store = Reader::from_file(&output).expect("from_file"); println!("{manifest_store}"); let active_manifest = manifest_store.active_manifest().unwrap(); - assert!(active_manifest.thumbnail_ref().is_none()); - assert!(active_manifest.thumbnail().is_none()); + assert_eq!(active_manifest.thumbnail_ref(), None); + assert_eq!(active_manifest.thumbnail(), None); } #[test] @@ -2723,7 +2723,7 @@ pub(crate) mod tests { let manifest_store = Reader::from_file(&output).expect("from_file"); println!("{manifest_store}"); - assert!(manifest_store.validation_status().is_none()); + assert_eq!(manifest_store.validation_status(), None); } #[cfg(all(feature = "file_io", feature = "openssl_sign"))] @@ -2782,7 +2782,7 @@ pub(crate) mod tests { let manifest_store = Reader::from_file(&output).expect("from_file"); println!("{manifest_store}"); - assert!(manifest_store.validation_status().is_none()); + assert_eq!(manifest_store.validation_status(), None); } #[test] @@ -2815,6 +2815,6 @@ pub(crate) mod tests { .unwrap(); println!("{reader}"); assert!(reader.active_manifest().is_some()); - assert!(reader.validation_status().is_none()); + assert_eq!(reader.validation_status(), None); } } diff --git a/sdk/src/manifest_store.rs b/sdk/src/manifest_store.rs index 5ac0d989f..3c072e632 100644 --- a/sdk/src/manifest_store.rs +++ b/sdk/src/manifest_store.rs @@ -628,7 +628,7 @@ mod tests { assert!(manifest_store.active_label().is_some()); assert!(manifest_store.get_active().is_some()); assert!(!manifest_store.manifests().is_empty()); - assert!(manifest_store.validation_status().is_none()); + assert_eq!(manifest_store.validation_status(), None); let manifest = manifest_store.get_active().unwrap(); assert!(!manifest.ingredients().is_empty()); assert_eq!(manifest.issuer().unwrap(), "C2PA Test Signing Cert"); @@ -650,7 +650,7 @@ mod tests { assert!(manifest_store.active_label().is_some()); assert!(manifest_store.get_active().is_some()); assert!(!manifest_store.manifests().is_empty()); - assert!(manifest_store.validation_status().is_none()); + assert_eq!(manifest_store.validation_status(), None); let manifest = manifest_store.get_active().unwrap(); assert!(!manifest.ingredients().is_empty()); assert_eq!(manifest.issuer().unwrap(), "C2PA Test Signing Cert"); @@ -668,7 +668,7 @@ mod tests { assert!(manifest_store.active_label().is_some()); assert!(manifest_store.get_active().is_some()); assert!(!manifest_store.manifests().is_empty()); - assert!(manifest_store.validation_status().is_none()); + assert_eq!(manifest_store.validation_status(), None); let manifest = manifest_store.get_active().unwrap(); assert!(!manifest.ingredients().is_empty()); assert_eq!(manifest.issuer().unwrap(), "C2PA Test Signing Cert"); @@ -691,7 +691,7 @@ mod tests { .await .unwrap(); assert!(!manifest_store.manifests().is_empty()); - assert!(manifest_store.validation_status().is_none()); + assert_eq!(manifest_store.validation_status(), None); println!("{manifest_store}"); } @@ -710,7 +710,7 @@ mod tests { assert!(manifest_store.active_label().is_some()); assert!(manifest_store.get_active().is_some()); assert!(!manifest_store.manifests().is_empty()); - assert!(manifest_store.validation_status().is_none()); + assert_eq!(manifest_store.validation_status(), None); let manifest = manifest_store.get_active().unwrap(); assert!(!manifest.ingredients().is_empty()); assert_eq!(manifest.issuer().unwrap(), "C2PA Test Signing Cert"); @@ -729,7 +729,7 @@ mod tests { assert!(manifest_store.active_label().is_some()); assert!(manifest_store.get_active().is_some()); assert!(!manifest_store.manifests().is_empty()); - assert!(manifest_store.validation_status().is_none()); + assert_eq!(manifest_store.validation_status(), None); let manifest = manifest_store.get_active().unwrap(); assert!(!manifest.ingredients().is_empty()); assert_eq!(manifest.issuer().unwrap(), "C2PA Test Signing Cert"); diff --git a/sdk/src/store.rs b/sdk/src/store.rs index 31d56a5e0..82a3fb26c 100644 --- a/sdk/src/store.rs +++ b/sdk/src/store.rs @@ -3954,7 +3954,7 @@ pub mod tests { // original data should not be in file anymore check for first 1k let buf = fs::read(&op).unwrap(); - assert!(memmem::find(&buf, &original_jumbf[0..1024]).is_none()); + assert_eq!(memmem::find(&buf, &original_jumbf[0..1024]), None); } #[actix::test] diff --git a/sdk/tests/v2_api_integration.rs b/sdk/tests/v2_api_integration.rs index 09d6e1b19..768166cd5 100644 --- a/sdk/tests/v2_api_integration.rs +++ b/sdk/tests/v2_api_integration.rs @@ -168,7 +168,7 @@ mod integration_v2 { } println!("{}", reader.json()); - assert!(reader.validation_status().is_none()); + assert_eq!(reader.validation_status(), None); assert_eq!(reader.active_manifest().unwrap().title().unwrap(), title); Ok(()) From 1da8358d8d6c9ca29c469fa5161b9b00e3778faa Mon Sep 17 00:00:00 2001 From: Eric Scouten Date: Tue, 10 Dec 2024 19:26:05 -0800 Subject: [PATCH 05/29] chore: Fix c2patool CI configuration (#759) --- .commitlintrc.yml | 1 + .github/workflows/nightly.yml | 6 ++++-- .github/workflows/pr_title.yml | 1 + cli/rustfmt.toml | 16 ---------------- 4 files changed, 6 insertions(+), 18 deletions(-) delete mode 100644 cli/rustfmt.toml diff --git a/.commitlintrc.yml b/.commitlintrc.yml index a0b1e4587..09c1eb3e1 100644 --- a/.commitlintrc.yml +++ b/.commitlintrc.yml @@ -24,6 +24,7 @@ rules: - export_schema - make_test_images - sdk + - c2patool # Scope may be empty # (NOTE: Disabled for now while we work around diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 5aadfbe5b..d0df02853 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -147,9 +147,11 @@ jobs: echo Will add nightly suffix $NIGHTLY_SUFFIX sed -i "s/^version = \"\\(.*\\)\"/version = \"\\1$NIGHTLY_SUFFIX\"/" sdk/Cargo.toml - + sed -i "s/path = \"..\/sdk\", version = \"\\(.*\\)\"/path = \"..\/sdk\", version = \"\\1$NIGHTLY_SUFFIX\"/" cli/Cargo.toml + cargo update -w - git add -f Cargo.lock + git add Cargo.lock + find . -name 'Cargo.toml' | xargs git add echo echo Proposed changes: diff --git a/.github/workflows/pr_title.yml b/.github/workflows/pr_title.yml index 6af082ed1..41bee1386 100644 --- a/.github/workflows/pr_title.yml +++ b/.github/workflows/pr_title.yml @@ -42,6 +42,7 @@ jobs: # these exact names: # # * sdk (The primary C2PA Rust SDK) + # * c2patool # * export_schema # * make_test_images # diff --git a/cli/rustfmt.toml b/cli/rustfmt.toml deleted file mode 100644 index 1807a36a9..000000000 --- a/cli/rustfmt.toml +++ /dev/null @@ -1,16 +0,0 @@ -# IMPORTANT: PR validation uses nightly version of -# rustfmt. - -# Invoke by using: -# -# rustup toolchain add nightly -# cargo +nightly fmt - -blank_lines_upper_bound = 1 -edition = "2018" -format_code_in_doc_comments = true -group_imports = "StdExternalCrate" -hex_literal_case = "Lower" -imports_granularity = "Crate" -reorder_impl_items = true -unstable_features = true From 5d305852cbb5a0d789dea2ac92210e93d45bb91b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 10 Dec 2024 19:32:24 -0800 Subject: [PATCH 06/29] chore: bump MarcoIeni/release-plz-action from 0.5.85 to 0.5.86 (#720) Bumps [MarcoIeni/release-plz-action](https://github.com/marcoieni/release-plz-action) from 0.5.85 to 0.5.86. - [Release notes](https://github.com/marcoieni/release-plz-action/releases) - [Commits](https://github.com/marcoieni/release-plz-action/compare/v0.5.85...v0.5.86) --- updated-dependencies: - dependency-name: MarcoIeni/release-plz-action dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index ea301ae25..1bfd653df 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -25,7 +25,7 @@ jobs: uses: dtolnay/rust-toolchain@stable - name: Run release-plz - uses: MarcoIeni/release-plz-action@v0.5.85 + uses: MarcoIeni/release-plz-action@v0.5.86 env: GITHUB_TOKEN: ${{ secrets.RELEASE_PLZ_TOKEN }} CARGO_REGISTRY_TOKEN: ${{ secrets.CRATES_IO_SECRET }} From 91ebac92cc3bc72f4cf455718c2c3a9c524d96a8 Mon Sep 17 00:00:00 2001 From: Eric Scouten Date: Tue, 10 Dec 2024 19:34:34 -0800 Subject: [PATCH 07/29] chore: Adapt for the myriad Dependabot PR title patterns (argh!) --- .github/workflows/pr_title.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/pr_title.yml b/.github/workflows/pr_title.yml index 41bee1386..f18696113 100644 --- a/.github/workflows/pr_title.yml +++ b/.github/workflows/pr_title.yml @@ -96,6 +96,11 @@ jobs: exit 0; fi + if echo "$PR_TITLE" | grep -E '^update: bump '; then + echo "Exception / OK: Dependabot update pattern" + exit 0; + fi + echo "Installing commitlint-rs. Please wait 30-40 seconds ..." cargo install --quiet commitlint-rs set -e From 93dcd7cb65300735ad8c4a352075315d22562129 Mon Sep 17 00:00:00 2001 From: Eric Scouten Date: Wed, 11 Dec 2024 08:56:46 -0800 Subject: [PATCH 08/29] chore: Remove version edit warning in c2patool Cargo.toml --- cli/Cargo.toml | 3 --- 1 file changed, 3 deletions(-) diff --git a/cli/Cargo.toml b/cli/Cargo.toml index 2ee5ea9e9..d6ee7c45a 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -2,9 +2,6 @@ name = "c2patool" default-run = "c2patool" -# Please do not manually edit `version`. Version updates will be generated -# automatically when c2patool is published. Remember to use (MINOR) or (MAJOR) -# tags in the PR title to trigger non-patch updates as needed. version = "0.9.12" description = "Tool for displaying and creating C2PA manifests." From e746a19a84b43ce3205bb24c4a6049d82c8bca3a Mon Sep 17 00:00:00 2001 From: Eric Scouten Date: Wed, 11 Dec 2024 08:57:39 -0800 Subject: [PATCH 09/29] chore: Update cli/CHANGELOG.md preamble --- cli/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cli/CHANGELOG.md b/cli/CHANGELOG.md index 2b4e5cf7c..67410d583 100644 --- a/cli/CHANGELOG.md +++ b/cli/CHANGELOG.md @@ -4,7 +4,7 @@ All changes to this project are documented in this file. This project adheres to [Semantic Versioning](https://semver.org), except that – as is typical in the Rust community – the minimum supported Rust version may be increased without a major version increase. -Since version 0.9.13, the format of this changelog is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). +Since version 0.10.0, the format of this changelog is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ## 0.9.12 _18 October 2024_ From 04e125c9925dfde97cab7c1976e3482792dadaed Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 11 Dec 2024 11:05:38 -0800 Subject: [PATCH 10/29] update: bump mockall requirement from 0.11.2 to 0.13.1 in /sdk (#685) update: update mockall requirement from 0.11.2 to 0.13.1 in /sdk Updates the requirements on [mockall](https://github.com/asomers/mockall) to permit the latest version. - [Changelog](https://github.com/asomers/mockall/blob/master/CHANGELOG.md) - [Commits](https://github.com/asomers/mockall/compare/v0.11.2...v0.13.1) --- updated-dependencies: - dependency-name: mockall dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Eric Scouten --- sdk/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/Cargo.toml b/sdk/Cargo.toml index a1f1827cc..d5177bd6e 100644 --- a/sdk/Cargo.toml +++ b/sdk/Cargo.toml @@ -161,7 +161,7 @@ web-sys = { version = "0.3.58", features = [ [dev-dependencies] anyhow = "1.0.40" -mockall = "0.11.2" +mockall = "0.13.1" c2pa = { path = ".", features = [ "unstable_api", ] } # allow integration tests to use the new API From 99c29f4164e47dd4ea2e0f26df3ad2e5b8739293 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 11 Dec 2024 11:16:52 -0800 Subject: [PATCH 11/29] update: bump asn1-rs from 0.5.2 to 0.6.2 (#724) Bumps [asn1-rs](https://github.com/rusticata/asn1-rs) from 0.5.2 to 0.6.2. - [Release notes](https://github.com/rusticata/asn1-rs/releases) - [Changelog](https://github.com/rusticata/asn1-rs/blob/master/CHANGELOG.md) - [Commits](https://github.com/rusticata/asn1-rs/compare/asn1-rs-0.5.2...asn1-rs-0.6.2) --- updated-dependencies: - dependency-name: asn1-rs dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 130 ++++++------------------------------------------- sdk/Cargo.toml | 2 +- 2 files changed, 16 insertions(+), 116 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9e53a7d2b..f797072d1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -188,29 +188,14 @@ dependencies = [ "term", ] -[[package]] -name = "asn1-rs" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f6fd5ddaf0351dff5b8da21b2fb4ff8e08ddd02857f0bf69c47639106c0fff0" -dependencies = [ - "asn1-rs-derive 0.4.0", - "asn1-rs-impl 0.1.0", - "displaydoc", - "nom", - "num-traits", - "rusticata-macros", - "thiserror 1.0.69", -] - [[package]] name = "asn1-rs" version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5493c3bedbacf7fd7382c6346bbd66687d12bbaad3a89a2d2c303ee6cf20b048" dependencies = [ - "asn1-rs-derive 0.5.1", - "asn1-rs-impl 0.2.0", + "asn1-rs-derive", + "asn1-rs-impl", "displaydoc", "nom", "num-traits", @@ -219,18 +204,6 @@ dependencies = [ "time", ] -[[package]] -name = "asn1-rs-derive" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "726535892e8eae7e70657b4c8ea93d26b8553afb1ce617caee529ef96d7dee6c" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", - "synstructure 0.12.6", -] - [[package]] name = "asn1-rs-derive" version = "0.5.1" @@ -240,18 +213,7 @@ dependencies = [ "proc-macro2", "quote", "syn 2.0.90", - "synstructure 0.13.1", -] - -[[package]] -name = "asn1-rs-impl" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2777730b2039ac0f95f093556e61b6d26cebed5393ca6f152717777cec3a42ed" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", + "synstructure", ] [[package]] @@ -285,7 +247,7 @@ dependencies = [ "bstr", "doc-comment", "libc", - "predicates 3.1.2", + "predicates", "predicates-core", "predicates-tree", "wait-timeout", @@ -703,7 +665,7 @@ version = "0.39.0" dependencies = [ "actix", "anyhow", - "asn1-rs 0.5.2", + "asn1-rs", "async-generic", "async-recursion", "async-trait", @@ -738,7 +700,7 @@ dependencies = [ "log", "lopdf", "memchr", - "mockall 0.11.4", + "mockall", "mp4", "openssl", "pem 3.0.4", @@ -843,10 +805,10 @@ dependencies = [ "glob", "httpmock", "log", - "mockall 0.13.1", + "mockall", "openssl", "pem 3.0.4", - "predicates 3.1.2", + "predicates", "reqwest", "serde", "serde_derive", @@ -1256,7 +1218,7 @@ version = "9.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5cd0a5c643689626bec213c4d8bd4d96acc8ffdb4ad4bb6bc16abf27d5f4b553" dependencies = [ - "asn1-rs 0.6.2", + "asn1-rs", "displaydoc", "nom", "num-bigint", @@ -2328,15 +2290,6 @@ version = "1.70.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" -[[package]] -name = "itertools" -version = "0.10.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" -dependencies = [ - "either", -] - [[package]] name = "itertools" version = "0.11.0" @@ -2629,21 +2582,6 @@ dependencies = [ "windows-sys 0.52.0", ] -[[package]] -name = "mockall" -version = "0.11.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c84490118f2ee2d74570d114f3d0493cbf02790df303d2707606c3e14e07c96" -dependencies = [ - "cfg-if", - "downcast", - "fragile", - "lazy_static", - "mockall_derive 0.11.4", - "predicates 2.1.5", - "predicates-tree", -] - [[package]] name = "mockall" version = "0.13.1" @@ -2653,23 +2591,11 @@ dependencies = [ "cfg-if", "downcast", "fragile", - "mockall_derive 0.13.1", - "predicates 3.1.2", + "mockall_derive", + "predicates", "predicates-tree", ] -[[package]] -name = "mockall_derive" -version = "0.11.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22ce75669015c4f47b289fd4d4f56e894e4c96003ffdf3ac51313126f94c6cbb" -dependencies = [ - "cfg-if", - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "mockall_derive" version = "0.13.1" @@ -2825,7 +2751,7 @@ version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8d8034d9489cdaf79228eb9f6a3b8d7bb32ba00d6645ebd48eef4077ceb5bd9" dependencies = [ - "asn1-rs 0.6.2", + "asn1-rs", ] [[package]] @@ -3189,20 +3115,6 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" -[[package]] -name = "predicates" -version = "2.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59230a63c37f3e18569bdb90e4a89cbf5bf8b06fea0b84e65ea10cc4df47addd" -dependencies = [ - "difflib", - "float-cmp", - "itertools 0.10.5", - "normalize-line-endings", - "predicates-core", - "regex", -] - [[package]] name = "predicates" version = "3.1.2" @@ -4127,18 +4039,6 @@ dependencies = [ "futures-core", ] -[[package]] -name = "synstructure" -version = "0.12.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", - "unicode-xid", -] - [[package]] name = "synstructure" version = "0.13.1" @@ -4941,7 +4841,7 @@ version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fcbc162f30700d6f3f82a24bf7cc62ffe7caea42c0b2cba8bf7f3ae50cf51f69" dependencies = [ - "asn1-rs 0.6.2", + "asn1-rs", "data-encoding", "der-parser", "lazy_static", @@ -4973,7 +4873,7 @@ dependencies = [ "proc-macro2", "quote", "syn 2.0.90", - "synstructure 0.13.1", + "synstructure", ] [[package]] @@ -5035,7 +4935,7 @@ dependencies = [ "proc-macro2", "quote", "syn 2.0.90", - "synstructure 0.13.1", + "synstructure", ] [[package]] diff --git a/sdk/Cargo.toml b/sdk/Cargo.toml index d5177bd6e..ae1a05401 100644 --- a/sdk/Cargo.toml +++ b/sdk/Cargo.toml @@ -63,7 +63,7 @@ required-features = ["unstable_api"] crate-type = ["lib"] [dependencies] -asn1-rs = "0.5.2" +asn1-rs = "0.6.2" async-generic = "1.1" async-recursion = "1.1.1" async-trait = { version = "0.1.77" } From cd47a94e46c593865f8975ddf920b2a4b66a2ae9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 11 Dec 2024 12:33:38 -0800 Subject: [PATCH 12/29] update: bump chrono from 0.4.38 to 0.4.39 (#763) Bumps [chrono](https://github.com/chronotope/chrono) from 0.4.38 to 0.4.39. - [Release notes](https://github.com/chronotope/chrono/releases) - [Changelog](https://github.com/chronotope/chrono/blob/main/CHANGELOG.md) - [Commits](https://github.com/chronotope/chrono/compare/v0.4.38...v0.4.39) --- updated-dependencies: - dependency-name: chrono dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- internal/crypto/Cargo.toml | 4 ++-- sdk/Cargo.toml | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f797072d1..5cc776310 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -839,9 +839,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.38" +version = "0.4.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" +checksum = "7e36cc9d416881d2e24f9a963be5fb1cd90966419ac844274161d10488b3e825" dependencies = [ "android-tzdata", "iana-time-zone", diff --git a/internal/crypto/Cargo.toml b/internal/crypto/Cargo.toml index 3137466a3..0a264ad33 100644 --- a/internal/crypto/Cargo.toml +++ b/internal/crypto/Cargo.toml @@ -63,12 +63,12 @@ url = "2.5.3" normal = ["openssl"] # TEMPORARY: Remove after openssl transition complete. [dependencies.chrono] -version = "0.4.38" +version = "0.4.39" default-features = false features = ["wasmbind"] [target.'cfg(not(target_arch = "wasm32"))'.dependencies.chrono] -version = "0.4.38" +version = "0.4.39" default-features = false features = ["now", "wasmbind"] diff --git a/sdk/Cargo.toml b/sdk/Cargo.toml index ae1a05401..eb2082649 100644 --- a/sdk/Cargo.toml +++ b/sdk/Cargo.toml @@ -74,7 +74,7 @@ byteorder = { version = "1.4.3", default-features = false } byteordered = "0.6.0" c2pa-crypto = { path = "../internal/crypto", version = "0.1.2" } c2pa-status-tracker = { path = "../internal/status-tracker", version = "0.1.0" } -chrono = { version = "0.4.38", default-features = false, features = [ +chrono = { version = "0.4.39", default-features = false, features = [ "serde", "wasmbind", ] } From 02ee889defd14b82dbd0a6b0c23f1b57d9a1fe90 Mon Sep 17 00:00:00 2001 From: Eric Scouten Date: Wed, 11 Dec 2024 13:34:02 -0800 Subject: [PATCH 13/29] chore: release (#761) --- CHANGELOG.md | 30 ++++++++ Cargo.lock | 144 +++++++++++++++++------------------ cli/CHANGELOG.md | 20 +++++ cli/Cargo.toml | 4 +- internal/crypto/CHANGELOG.md | 18 +++++ internal/crypto/Cargo.toml | 2 +- sdk/Cargo.toml | 4 +- 7 files changed, 144 insertions(+), 78 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d6ee3dd3a..5f96cb8b7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,36 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm Since version 0.36.2, the format of this changelog is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). +Note that this changelog is for the primary `c2pa` crate; there are several other projects hosted within this repo and they each have their own changelog. + +## [0.40.0](https://github.com/contentauth/c2pa-rs/compare/c2pa-v0.39.0...c2pa-v0.40.0) +_11 December 2024_ + +### Added + +* Add `RawSigner` trait to `c2pa-crypto` (derived from `c2pa::Signer`) (#716) +* Move time stamp code into c2pa-crypto (#696) +* Adds ValidationState support (#701) +* Introduce `DynamicAssertion` trait (#566) + +### Fixed + +* Verbose assertions for `is_none()` (#704) +* Remove `c2pa::Signer` dependency on `c2pa_crypto::TimeStampProvider` (#718) +* Add support for MP3 without ID3 header (#652) +* Treat Unicode-3.0 license as approved; unpin related dependencies (#693) +* Remote manifest fetch test was not using full path (#675) +* Fix #624 (edge cases when combining the box hashes) (#625) +* Fix #672, Callback is unsound (#674) +* Support "remote_manifest_fetch" verify setting (#667) + +### Updated dependencies + +* Bump chrono from 0.4.38 to 0.4.39 (#763) +* Bump asn1-rs from 0.5.2 to 0.6.2 (#724) +* Bump mockall requirement from 0.11.2 to 0.13.1 in /sdk (#685) +* Update zip requirement from 0.6.6 to 2.2.1 in /sdk (#698) + ## [0.39.0](https://github.com/contentauth/c2pa-rs/compare/c2pa-v0.38.0...c2pa-v0.39.0) _13 November 2024_ diff --git a/Cargo.lock b/Cargo.lock index 5cc776310..6a4b1d70c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -611,9 +611,9 @@ dependencies = [ [[package]] name = "bstr" -version = "1.11.0" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a68f1f47cdf0ec8ee4b941b2eee2a80cb796db73118c0dd09ac63fbe405be22" +checksum = "786a307d683a5bf92e6fd5fd69a7eb613751668d1d8d67d802846dfe367c62c8" dependencies = [ "memchr", "regex-automata", @@ -661,7 +661,7 @@ checksum = "325918d6fe32f23b19878fe4b34794ae41fc19ddbe53b10571a4874d44ffd39b" [[package]] name = "c2pa" -version = "0.39.0" +version = "0.40.0" dependencies = [ "actix", "anyhow", @@ -744,7 +744,7 @@ dependencies = [ [[package]] name = "c2pa-crypto" -version = "0.1.2" +version = "0.2.0" dependencies = [ "actix", "async-generic", @@ -794,7 +794,7 @@ version = "0.1.0" [[package]] name = "c2patool" -version = "0.9.12" +version = "0.10.0" dependencies = [ "anyhow", "assert_cmd", @@ -824,9 +824,9 @@ version = "0.1.1" [[package]] name = "cc" -version = "1.2.2" +version = "1.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f34d93e62b03caf570cccc334cbc6c2fceca82f39211051345108adcba3eebdc" +checksum = "27f657647bcff5394bf56c7317665bbf790a137a50eaaa5c6bfbb9e27a518f2d" dependencies = [ "shlex", ] @@ -1501,15 +1501,15 @@ dependencies = [ [[package]] name = "fastrand" -version = "2.2.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "486f806e73c5707928240ddc295403b1b93c96a02038563881c4a2fd84b81ac4" +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" [[package]] name = "fdeflate" -version = "0.3.6" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07c6f4c64c1d33a3111c4466f7365ebdcc37c5bd1ea0d62aae2e3d722aacbedb" +checksum = "1e6853b52649d4ac5c0bd02320cddc5ba956bdb407c4b75a2c6b75bf51500f8c" dependencies = [ "simd-adler32", ] @@ -2328,9 +2328,9 @@ checksum = "f5d4a7da358eff58addd2877a45865158f0d78c911d43a5784ceb7bbf52833b0" [[package]] name = "js-sys" -version = "0.3.74" +version = "0.3.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a865e038f7f6ed956f788f0d7d60c541fff74c7bd74272c5d4cf15c63743e705" +checksum = "6717b6b5b077764fb5966237269cb3c64edddde4b14ce42647430a78ced9e7b7" dependencies = [ "once_cell", "wasm-bindgen", @@ -2359,9 +2359,9 @@ dependencies = [ [[package]] name = "konst" -version = "0.3.14" +version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b65f00fb3910881e52bf0850ae2a82aea411488a557e1c02820ceaa60963dce3" +checksum = "298ddf99f06a97c1ecd0e910932662b7842855046234b0d0376d35d93add087f" dependencies = [ "const_panic", "konst_kernel", @@ -2370,9 +2370,9 @@ dependencies = [ [[package]] name = "konst_kernel" -version = "0.3.12" +version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "599c1232f55c72c7fc378335a3efe1c878c92720838c8e6a4fd87784ef7764de" +checksum = "e4b1eb7788f3824c629b1116a7a9060d6e898c358ebff59070093d51103dcc3c" dependencies = [ "typewit", ] @@ -2434,9 +2434,9 @@ checksum = "db13adb97ab515a3691f56e4dbab09283d0b86cb45abd991d8634a9d6f501760" [[package]] name = "libc" -version = "0.2.167" +version = "0.2.168" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09d6582e104315a817dff97f75133544b2e094ee22447d2acf4a74e189ba06fc" +checksum = "5aaeb2981e0606ca11d79718f8bb01164f1d6ed75080182d3abf017e6d244b6d" [[package]] name = "libm" @@ -2929,20 +2929,20 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pest" -version = "2.7.14" +version = "2.7.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "879952a81a83930934cbf1786752d6dedc3b1f29e8f8fb2ad1d0a36f377cf442" +checksum = "8b7cafe60d6cf8e62e1b9b2ea516a089c008945bb5a275416789e7db0bc199dc" dependencies = [ "memchr", - "thiserror 1.0.69", + "thiserror 2.0.6", "ucd-trie", ] [[package]] name = "pest_derive" -version = "2.7.14" +version = "2.7.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d214365f632b123a47fd913301e14c946c61d1c183ee245fa76eb752e59a02dd" +checksum = "816518421cfc6887a0d62bf441b6ffb4536fcc926395a69e1a85852d4363f57e" dependencies = [ "pest", "pest_generator", @@ -2950,9 +2950,9 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.7.14" +version = "2.7.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb55586734301717aea2ac313f50b2eb8f60d2fc3dc01d190eefa2e625f60c4e" +checksum = "7d1396fd3a870fc7838768d171b4616d5c91f6cc25e377b673d714567d99377b" dependencies = [ "pest", "pest_meta", @@ -2963,9 +2963,9 @@ dependencies = [ [[package]] name = "pest_meta" -version = "2.7.14" +version = "2.7.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b75da2a70cf4d9cb76833c990ac9cd3923c9a8905a8929789ce347c84564d03d" +checksum = "e1e58089ea25d717bfd31fb534e4f3afcc2cc569c70de3e239778991ea3b7dea" dependencies = [ "once_cell", "pest", @@ -3055,9 +3055,9 @@ checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" [[package]] name = "png" -version = "0.17.14" +version = "0.17.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52f9d46a34a05a6a57566bc2bfae066ef07585a6e3fa30fbbdff5936380623f0" +checksum = "b67582bd5b65bdff614270e2ea89a1cf15bef71245cc1e5f7ea126977144211d" dependencies = [ "bitflags 1.3.2", "crc32fast", @@ -3230,7 +3230,7 @@ version = "0.9.0-beta.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a98fa0b8309344136abe6244130311e76997e546f76fae8054422a7539b43df7" dependencies = [ - "zerocopy 0.8.12", + "zerocopy 0.8.13", ] [[package]] @@ -3332,9 +3332,9 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.5.7" +version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f" +checksum = "03a862b389f93e68874fbf580b9de08dd02facb9a788ebadaf4a3fd33cf58834" dependencies = [ "bitflags 2.6.0", ] @@ -3538,22 +3538,22 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.41" +version = "0.38.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7f649912bc1495e167a6edee79151c84b1bad49748cb4f1f1167f459f6224f6" +checksum = "f93dc38ecbab2eb790ff964bb77fa94faf256fd3e73285fd7ba0903b76bedb85" dependencies = [ "bitflags 2.6.0", "errno", "libc", "linux-raw-sys", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] name = "rustls" -version = "0.23.19" +version = "0.23.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "934b404430bb06b3fae2cba809eb45a1ab1aecd64491213d7c3301b88393f8d1" +checksum = "5065c3f250cbd332cd894be57c40fa52387247659b14a2d6041d121547903b1b" dependencies = [ "log", "once_cell", @@ -3701,9 +3701,9 @@ checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" [[package]] name = "serde" -version = "1.0.215" +version = "1.0.216" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6513c1ad0b11a9376da888e3e0baa0077f1aed55c17f50e7b2397136129fb88f" +checksum = "0b9781016e935a97e8beecf0c933758c97a5520d32930e460142b4cd80c6338e" dependencies = [ "serde_derive", ] @@ -3749,9 +3749,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.215" +version = "1.0.216" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0" +checksum = "46f859dbbf73865c6627ed570e78961cd3ac92407a2d117204c49232485da55e" dependencies = [ "proc-macro2", "quote", @@ -4248,9 +4248,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.12" +version = "0.7.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61e7c3654c13bcd040d4a03abee2c75b1d14a37b423cf5a813ceae1cc903ec6a" +checksum = "d7fcaa8d55a2bdd6b83ace262b016eca0d79ee02818c5c1bcdf0305114081078" dependencies = [ "bytes", "futures-core", @@ -4349,9 +4349,9 @@ checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] name = "typewit" -version = "1.10.1" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d51dbd25812f740f45e2a9769f84711982e000483b13b73a8a1852e092abac8c" +checksum = "cb77c29baba9e4d3a6182d51fa75e3215c7fd1dab8f4ea9d107c716878e55fc0" dependencies = [ "typewit_proc_macros", ] @@ -4400,9 +4400,9 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "ureq" -version = "2.12.0" +version = "2.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3193f92e105038f98ae68af40c008e3c94f2f046926e0f95e6c835dc6459bac8" +checksum = "02d1a66277ed75f640d608235660df48c8e3c19f3b4edb6a263315626cc3c01d" dependencies = [ "base64 0.22.1", "flate2", @@ -4508,9 +4508,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.97" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d15e63b4482863c109d70a7b8706c1e364eb6ea449b201a76c5b89cedcec2d5c" +checksum = "a474f6281d1d70c17ae7aa6a613c87fce69a127e2624002df63dcb39d6cf6396" dependencies = [ "cfg-if", "once_cell", @@ -4519,13 +4519,12 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.97" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d36ef12e3aaca16ddd3f67922bc63e48e953f126de60bd33ccc0101ef9998cd" +checksum = "5f89bb38646b4f81674e8f5c3fb81b562be1fd936d84320f3264486418519c79" dependencies = [ "bumpalo", "log", - "once_cell", "proc-macro2", "quote", "syn 2.0.90", @@ -4534,9 +4533,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.47" +version = "0.4.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dfaf8f50e5f293737ee323940c7d8b08a66a95a419223d9f41610ca08b0833d" +checksum = "38176d9b44ea84e9184eff0bc34cc167ed044f816accfe5922e54d84cf48eca2" dependencies = [ "cfg-if", "js-sys", @@ -4547,9 +4546,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.97" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "705440e08b42d3e4b36de7d66c944be628d579796b8090bfa3471478a2260051" +checksum = "2cc6181fd9a7492eef6fef1f33961e3695e4579b9872a6f7c83aee556666d4fe" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -4557,9 +4556,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.97" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98c9ae5a76e46f4deecd0f0255cc223cfa18dc9b261213b8aa0c7b36f61b3f1d" +checksum = "30d7a95b763d3c45903ed6c81f156801839e5ee968bb07e534c44df0fcd330c2" dependencies = [ "proc-macro2", "quote", @@ -4570,19 +4569,18 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.97" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ee99da9c5ba11bd675621338ef6fa52296b76b83305e9b6e5c77d4c286d6d49" +checksum = "943aab3fdaaa029a6e0271b35ea10b72b943135afe9bffca82384098ad0e06a6" [[package]] name = "wasm-bindgen-test" -version = "0.3.47" +version = "0.3.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d919bb60ebcecb9160afee6c71b43a58a4f0517a2de0054cd050d02cec08201" +checksum = "c61d44563646eb934577f2772656c7ad5e9c90fac78aa8013d776fcdaf24625d" dependencies = [ "js-sys", "minicov", - "once_cell", "scoped-tls", "wasm-bindgen", "wasm-bindgen-futures", @@ -4591,9 +4589,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-test-macro" -version = "0.3.47" +version = "0.3.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "222ebde6ea87fbfa6bdd2e9f1fd8a91d60aee5db68792632176c4e16a74fc7d8" +checksum = "54171416ce73aa0b9c377b51cc3cb542becee1cd678204812e8392e5b0e4a031" dependencies = [ "proc-macro2", "quote", @@ -4602,9 +4600,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.74" +version = "0.3.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a98bc3c33f0fe7e59ad7cd041b89034fa82a7c2d4365ca538dda6cdaf513863c" +checksum = "04dd7223427d52553d3702c004d3b2fe07c148165faa56313cb00211e31c12bc" dependencies = [ "js-sys", "wasm-bindgen", @@ -4888,11 +4886,11 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.8.12" +version = "0.8.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e031087b26520ba76806365896f191416ce84873ed6c6910a9ab5fe0f98f8ed3" +checksum = "67914ab451f3bfd2e69e5e9d2ef3858484e7074d63f204fd166ec391b54de21d" dependencies = [ - "zerocopy-derive 0.8.12", + "zerocopy-derive 0.8.13", ] [[package]] @@ -4908,9 +4906,9 @@ dependencies = [ [[package]] name = "zerocopy-derive" -version = "0.8.12" +version = "0.8.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "568244125ba0fc91ae949b97f2852f82cb1a65c3327bd68e6edadd29e67cca26" +checksum = "7988d73a4303ca289df03316bc490e934accf371af6bc745393cf3c2c5c4f25d" dependencies = [ "proc-macro2", "quote", diff --git a/cli/CHANGELOG.md b/cli/CHANGELOG.md index 67410d583..1d9856200 100644 --- a/cli/CHANGELOG.md +++ b/cli/CHANGELOG.md @@ -6,6 +6,26 @@ This project adheres to [Semantic Versioning](https://semver.org), except that Since version 0.10.0, the format of this changelog is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). +## [0.10.0](https://github.com/contentauth/c2pa-rs/compare/c2patool-v0.9.12...c2patool-v0.10.0) +_11 December 2024_ + +### Added + +* Updates c2patool to use only the new Builder/Reader API (contentauth/c2patool#297) + +### Documented + +* Update Contributing guide, misc minor edits (contentauth/c2patool#296) + +### Other + +* Move profile settings to workspace Cargo.toml +* Fix README links +* Update repository link in cli/Cargo.toml +* Fix formatting of cli/CHANGELOG.md +* Merge branch 'c2patool-main' into c2patool-merge +* Enlarged description of c2pa command-line behavior (contentauth/c2patool[#285](https://github.com/contentauth/c2pa-rs/pull/285)) + ## 0.9.12 _18 October 2024_ diff --git a/cli/Cargo.toml b/cli/Cargo.toml index d6ee7c45a..094d7ad3b 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -2,7 +2,7 @@ name = "c2patool" default-run = "c2patool" -version = "0.9.12" +version = "0.10.0" description = "Tool for displaying and creating C2PA manifests." authors = [ @@ -20,7 +20,7 @@ repository = "https://github.com/contentauth/c2pa-rs/tree/main/cli" [dependencies] anyhow = "1.0" atree = "0.5.2" -c2pa = { path = "../sdk", version = "0.39.0", features = [ +c2pa = { path = "../sdk", version = "0.40.0", features = [ "fetch_remote_manifests", "file_io", "add_thumbnails", diff --git a/internal/crypto/CHANGELOG.md b/internal/crypto/CHANGELOG.md index 9fd3291d8..f0ca74a39 100644 --- a/internal/crypto/CHANGELOG.md +++ b/internal/crypto/CHANGELOG.md @@ -6,6 +6,24 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm The format of this changelog is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). +## [0.2.0](https://github.com/contentauth/c2pa-rs/compare/c2pa-crypto-v0.1.2...c2pa-crypto-v0.2.0) +_11 December 2024_ + +### Added + +* Add `RawSigner` trait to `c2pa-crypto` (derived from `c2pa::Signer`) (#716) +* Move time stamp code into c2pa-crypto (#696) + +### Fixed + +* Verbose assertions for `is_none()` (#704) +* Remove `c2pa::Signer` dependency on `c2pa_crypto::TimeStampProvider` (#718) +* Treat Unicode-3.0 license as approved; unpin related dependencies (#693) + +### Updated dependencies + +* Bump chrono from 0.4.38 to 0.4.39 (#763) + ## [0.1.2](https://github.com/contentauth/c2pa-rs/compare/c2pa-crypto-v0.1.1...c2pa-crypto-v0.1.2) _24 October 2024_ diff --git a/internal/crypto/Cargo.toml b/internal/crypto/Cargo.toml index 0a264ad33..80ac08e52 100644 --- a/internal/crypto/Cargo.toml +++ b/internal/crypto/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "c2pa-crypto" -version = "0.1.2" +version = "0.2.0" description = "Cryptography internals for c2pa-rs crate" authors = [ "Maurice Fisher ", diff --git a/sdk/Cargo.toml b/sdk/Cargo.toml index eb2082649..dd837b568 100644 --- a/sdk/Cargo.toml +++ b/sdk/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "c2pa" -version = "0.39.0" +version = "0.40.0" description = "Rust SDK for C2PA (Coalition for Content Provenance and Authenticity) implementors" authors = [ "Maurice Fisher ", @@ -72,7 +72,7 @@ bcder = "0.7.3" bytes = "1.7.2" byteorder = { version = "1.4.3", default-features = false } byteordered = "0.6.0" -c2pa-crypto = { path = "../internal/crypto", version = "0.1.2" } +c2pa-crypto = { path = "../internal/crypto", version = "0.2.0" } c2pa-status-tracker = { path = "../internal/status-tracker", version = "0.1.0" } chrono = { version = "0.4.39", default-features = false, features = [ "serde", From 8781241233692ffc6ce7387e37518623d0001d55 Mon Sep 17 00:00:00 2001 From: Eric Scouten Date: Wed, 11 Dec 2024 13:50:20 -0800 Subject: [PATCH 14/29] chore: Fix release-plz configuration --- release-plz.toml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/release-plz.toml b/release-plz.toml index 58ed69220..fe0fe3e01 100644 --- a/release-plz.toml +++ b/release-plz.toml @@ -47,14 +47,17 @@ changelog_path = "./CHANGELOG.md" # of in the `sdk` folder (which would be the default). [[package]] -name = "c2pa-crypto" +name = "c2pa-status-tracker" [[package]] -name = "c2pa-status-tracker" +name = "c2pa-crypto" [[package]] name = "cawg-identity" +[[package]] +name = "c2patool" + [[package]] name = "export_schema" publish = false From 612a8a836357af94edcf7d219fb606120bebf613 Mon Sep 17 00:00:00 2001 From: Eric Scouten Date: Wed, 11 Dec 2024 14:04:20 -0800 Subject: [PATCH 15/29] chore: Inspect release-plz `releases` output --- .github/workflows/release.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 1bfd653df..d4eea9c5d 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -25,6 +25,7 @@ jobs: uses: dtolnay/rust-toolchain@stable - name: Run release-plz + id: release-plz uses: MarcoIeni/release-plz-action@v0.5.86 env: GITHUB_TOKEN: ${{ secrets.RELEASE_PLZ_TOKEN }} @@ -40,8 +41,11 @@ jobs: xargs -I {} git push origin --delete {} - name: Identify c2patool release tag + env: + RELEASES: ${{ steps.release-plz.outputs.releases }} run: | echo "TO DO: Identify c2patool release tag, if any" + echo $RELEASES exit 1 # publish-c2patool-binaries: From dac8c05315335ac0d247066ba39eba08f68cd5d8 Mon Sep 17 00:00:00 2001 From: Eric Scouten Date: Wed, 11 Dec 2024 14:59:53 -0800 Subject: [PATCH 16/29] chore: Rebuild c2patool binary release process --- .github/workflows/release.yml | 153 ++++++++++++++++++---------------- 1 file changed, 79 insertions(+), 74 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index d4eea9c5d..0f2527da5 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -14,6 +14,9 @@ jobs: name: Release-plz runs-on: ubuntu-latest + outputs: + c2patool-release-tag: ${{ steps.sniff-c2patool-release-tag.outputs.tag }} + steps: - name: Checkout repository uses: actions/checkout@v4 @@ -39,79 +42,81 @@ jobs: tail -n +2 |\ sed 's/origin\///' |\ xargs -I {} git push origin --delete {} - - - name: Identify c2patool release tag - env: - RELEASES: ${{ steps.release-plz.outputs.releases }} + + - name: Identify c2patool release + id: sniff-c2patool-release-tag run: | - echo "TO DO: Identify c2patool release tag, if any" - echo $RELEASES - exit 1 - - # publish-c2patool-binaries: - # name: Publish c2patool binaries - # runs-on: ${{ matrix.os }} - # needs: release-plz - - # strategy: - # fail-fast: false - # matrix: - # os: [ macos-latest, ubuntu-latest, windows-latest ] - # rust_version: [ stable ] - # experimental: [ false ] - # include: - # - os: macos-latest - # artifact_name: c2patool_mac_universal.zip - # uploaded_asset_name: c2patool-${{ needs.repo-prep.outputs.new-tag }}-universal-apple-darwin.zip - # - os: ubuntu-latest - # artifact_name: c2patool_linux_intel.tar.gz - # uploaded_asset_name: c2patool-${{ needs.repo-prep.outputs.new-tag }}-x86_64-unknown-linux-gnu.tar.gz - # - os: windows-latest - # artifact_name: c2patool_win_intel.zip - # uploaded_asset_name: c2patool-${{ needs.repo-prep.outputs.new-tag }}-x86_64-pc-windows-msvc.zip - - # steps: - # - name: Checkout repository - # uses: actions/checkout@v4 - # with: - # ref: ${{ needs.repo-prep.outputs.commit-hash }} - - # - name: Install Rust toolchain - # uses: dtolnay/rust-toolchain@master - # with: - # toolchain: ${{ matrix.rust_version }} - # components: llvm-tools-preview - - # - name: Install cargo-sbom - # uses: baptiste0928/cargo-install@v3 - # with: - # crate: cargo-sbom - # version: '0.9.1' - - # - name: Cache Rust dependencies - # uses: Swatinem/rust-cache@v2 - - # - name: Run make release - # run: make release - - # - name: Upload binary to GitHub - # uses: svenstaro/upload-release-action@v1-release - # with: - # repo_token: ${{ secrets.GITHUB_TOKEN }} - # file: target/${{ matrix.artifact_name }} - # asset_name: ${{ matrix.uploaded_asset_name }} - # tag: ${{ needs.repo-prep.outputs.new-tag }} - # overwrite: true - - # - name: Generate SBOM - # run: cargo sbom > c2patool.${{ matrix.os }}.sbom.json - - # - name: Upload SBOM to Github - # uses: svenstaro/upload-release-action@v1-release - # with: - # repo_token: ${{ secrets.GITHUB_TOKEN }} - # file: c2patool.${{ matrix.os }}.sbom.json - # asset_name: c2patool-${{ needs.repo-prep.outputs.new-tag }}-sbom.json - # tag: ${{ needs.repo-prep.outputs.new-tag }} - # overwrite: true + echo tag=`git tag --contains HEAD | grep '^c2patool-'` >> "$GITHUB_OUTPUT" || true + + publish-c2patool-binaries: + name: Publish c2patool binaries + runs-on: ${{ matrix.os }} + needs: release-plz + + strategy: + fail-fast: false + matrix: + os: [ macos-latest, ubuntu-latest, windows-latest ] + rust_version: [ stable ] + experimental: [ false ] + include: + - os: macos-latest + artifact_name: c2patool_mac_universal.zip + uploaded_asset_name: c2patool-${{ needs.release-plz.outputs.c2patool-release-tag }}-universal-apple-darwin.zip + - os: ubuntu-latest + artifact_name: c2patool_linux_intel.tar.gz + uploaded_asset_name: c2patool-${{ needs.release-plz.outputs.c2patool-release-tag }}-x86_64-unknown-linux-gnu.tar.gz + - os: windows-latest + artifact_name: c2patool_win_intel.zip + uploaded_asset_name: c2patool-${{ needs.release-plz.outputs.c2patool-release-tag }}-x86_64-pc-windows-msvc.zip + + steps: + - name: Checkout repository + if: ${{ needs.release-plz.outputs.c2patool-release-tag }} + uses: actions/checkout@v4 + - name: Install Rust toolchain + if: ${{ needs.release-plz.outputs.c2patool-release-tag }} + uses: dtolnay/rust-toolchain@master + with: + toolchain: ${{ matrix.rust_version }} + components: llvm-tools-preview + + - name: Install cargo-sbom + if: ${{ needs.release-plz.outputs.c2patool-release-tag }} + uses: baptiste0928/cargo-install@v3 + with: + crate: cargo-sbom + version: '0.9.1' + + - name: Cache Rust dependencies + if: ${{ needs.release-plz.outputs.c2patool-release-tag }} + uses: Swatinem/rust-cache@v2 + + - name: Run make release + if: ${{ needs.release-plz.outputs.c2patool-release-tag }} + run: make release + + - name: Upload binary to GitHub + if: ${{ needs.release-plz.outputs.c2patool-release-tag }} + uses: svenstaro/upload-release-action@v1-release + with: + repo_token: ${{ secrets.GITHUB_TOKEN }} + file: target/${{ matrix.artifact_name }} + asset_name: ${{ matrix.uploaded_asset_name }} + tag: ${{ needs.release-plz.outputs.c2patool-release-tag }} + overwrite: true + + - name: Generate SBOM + if: ${{ needs.release-plz.outputs.c2patool-release-tag }} + run: cargo sbom > c2patool.${{ matrix.os }}.sbom.json + + - name: Upload SBOM to Github + if: ${{ needs.release-plz.outputs.c2patool-release-tag }} + uses: svenstaro/upload-release-action@v1-release + with: + repo_token: ${{ secrets.GITHUB_TOKEN }} + file: c2patool.${{ matrix.os }}.sbom.json + asset_name: c2patool-${{ needs.release-plz.outputs.c2patool-release-tag }}-sbom.json + tag: ${{ needs.release-plz.outputs.c2patool-release-tag }} + overwrite: true From b69415e7c5edca74fdfc5e7c6be36ef9dc2d5d43 Mon Sep 17 00:00:00 2001 From: Eric Scouten Date: Wed, 11 Dec 2024 15:50:10 -0800 Subject: [PATCH 17/29] feat: Move `validation_codes` from `c2pa-crypto` to `c2pa-status-tracker` (Actually done in #695, but because I marked that PR as a `chore` it isn't triggering a release of `c2pa-status-tracker`, which is required for other crates to build. Fun times!) --- internal/status-tracker/src/validation_codes.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/status-tracker/src/validation_codes.rs b/internal/status-tracker/src/validation_codes.rs index 79ba7b2a8..45ebe4046 100644 --- a/internal/status-tracker/src/validation_codes.rs +++ b/internal/status-tracker/src/validation_codes.rs @@ -288,7 +288,7 @@ pub const GENERAL_ERROR: &str = "general.error"; /// Returns `false` if the status code is a known C2PA failure status /// code or is unknown. /// -/// # Examples +/// ## Examples /// /// ``` /// use c2pa_status_tracker::validation_codes::*; From 5931f000aca53b110a7803e8f184496cdb03a6a6 Mon Sep 17 00:00:00 2001 From: Eric Scouten Date: Wed, 11 Dec 2024 15:53:26 -0800 Subject: [PATCH 18/29] chore: Revert previous release attempt --- CHANGELOG.md | 30 -------- Cargo.lock | 144 ++++++++++++++++++----------------- cli/CHANGELOG.md | 20 ----- cli/Cargo.toml | 4 +- internal/crypto/CHANGELOG.md | 18 ----- internal/crypto/Cargo.toml | 2 +- sdk/Cargo.toml | 4 +- 7 files changed, 78 insertions(+), 144 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5f96cb8b7..d6ee3dd3a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,36 +6,6 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm Since version 0.36.2, the format of this changelog is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). -Note that this changelog is for the primary `c2pa` crate; there are several other projects hosted within this repo and they each have their own changelog. - -## [0.40.0](https://github.com/contentauth/c2pa-rs/compare/c2pa-v0.39.0...c2pa-v0.40.0) -_11 December 2024_ - -### Added - -* Add `RawSigner` trait to `c2pa-crypto` (derived from `c2pa::Signer`) (#716) -* Move time stamp code into c2pa-crypto (#696) -* Adds ValidationState support (#701) -* Introduce `DynamicAssertion` trait (#566) - -### Fixed - -* Verbose assertions for `is_none()` (#704) -* Remove `c2pa::Signer` dependency on `c2pa_crypto::TimeStampProvider` (#718) -* Add support for MP3 without ID3 header (#652) -* Treat Unicode-3.0 license as approved; unpin related dependencies (#693) -* Remote manifest fetch test was not using full path (#675) -* Fix #624 (edge cases when combining the box hashes) (#625) -* Fix #672, Callback is unsound (#674) -* Support "remote_manifest_fetch" verify setting (#667) - -### Updated dependencies - -* Bump chrono from 0.4.38 to 0.4.39 (#763) -* Bump asn1-rs from 0.5.2 to 0.6.2 (#724) -* Bump mockall requirement from 0.11.2 to 0.13.1 in /sdk (#685) -* Update zip requirement from 0.6.6 to 2.2.1 in /sdk (#698) - ## [0.39.0](https://github.com/contentauth/c2pa-rs/compare/c2pa-v0.38.0...c2pa-v0.39.0) _13 November 2024_ diff --git a/Cargo.lock b/Cargo.lock index 6a4b1d70c..5cc776310 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -611,9 +611,9 @@ dependencies = [ [[package]] name = "bstr" -version = "1.11.1" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "786a307d683a5bf92e6fd5fd69a7eb613751668d1d8d67d802846dfe367c62c8" +checksum = "1a68f1f47cdf0ec8ee4b941b2eee2a80cb796db73118c0dd09ac63fbe405be22" dependencies = [ "memchr", "regex-automata", @@ -661,7 +661,7 @@ checksum = "325918d6fe32f23b19878fe4b34794ae41fc19ddbe53b10571a4874d44ffd39b" [[package]] name = "c2pa" -version = "0.40.0" +version = "0.39.0" dependencies = [ "actix", "anyhow", @@ -744,7 +744,7 @@ dependencies = [ [[package]] name = "c2pa-crypto" -version = "0.2.0" +version = "0.1.2" dependencies = [ "actix", "async-generic", @@ -794,7 +794,7 @@ version = "0.1.0" [[package]] name = "c2patool" -version = "0.10.0" +version = "0.9.12" dependencies = [ "anyhow", "assert_cmd", @@ -824,9 +824,9 @@ version = "0.1.1" [[package]] name = "cc" -version = "1.2.3" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27f657647bcff5394bf56c7317665bbf790a137a50eaaa5c6bfbb9e27a518f2d" +checksum = "f34d93e62b03caf570cccc334cbc6c2fceca82f39211051345108adcba3eebdc" dependencies = [ "shlex", ] @@ -1501,15 +1501,15 @@ dependencies = [ [[package]] name = "fastrand" -version = "2.3.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" +checksum = "486f806e73c5707928240ddc295403b1b93c96a02038563881c4a2fd84b81ac4" [[package]] name = "fdeflate" -version = "0.3.7" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e6853b52649d4ac5c0bd02320cddc5ba956bdb407c4b75a2c6b75bf51500f8c" +checksum = "07c6f4c64c1d33a3111c4466f7365ebdcc37c5bd1ea0d62aae2e3d722aacbedb" dependencies = [ "simd-adler32", ] @@ -2328,9 +2328,9 @@ checksum = "f5d4a7da358eff58addd2877a45865158f0d78c911d43a5784ceb7bbf52833b0" [[package]] name = "js-sys" -version = "0.3.76" +version = "0.3.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6717b6b5b077764fb5966237269cb3c64edddde4b14ce42647430a78ced9e7b7" +checksum = "a865e038f7f6ed956f788f0d7d60c541fff74c7bd74272c5d4cf15c63743e705" dependencies = [ "once_cell", "wasm-bindgen", @@ -2359,9 +2359,9 @@ dependencies = [ [[package]] name = "konst" -version = "0.3.15" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "298ddf99f06a97c1ecd0e910932662b7842855046234b0d0376d35d93add087f" +checksum = "b65f00fb3910881e52bf0850ae2a82aea411488a557e1c02820ceaa60963dce3" dependencies = [ "const_panic", "konst_kernel", @@ -2370,9 +2370,9 @@ dependencies = [ [[package]] name = "konst_kernel" -version = "0.3.15" +version = "0.3.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4b1eb7788f3824c629b1116a7a9060d6e898c358ebff59070093d51103dcc3c" +checksum = "599c1232f55c72c7fc378335a3efe1c878c92720838c8e6a4fd87784ef7764de" dependencies = [ "typewit", ] @@ -2434,9 +2434,9 @@ checksum = "db13adb97ab515a3691f56e4dbab09283d0b86cb45abd991d8634a9d6f501760" [[package]] name = "libc" -version = "0.2.168" +version = "0.2.167" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aaeb2981e0606ca11d79718f8bb01164f1d6ed75080182d3abf017e6d244b6d" +checksum = "09d6582e104315a817dff97f75133544b2e094ee22447d2acf4a74e189ba06fc" [[package]] name = "libm" @@ -2929,20 +2929,20 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pest" -version = "2.7.15" +version = "2.7.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b7cafe60d6cf8e62e1b9b2ea516a089c008945bb5a275416789e7db0bc199dc" +checksum = "879952a81a83930934cbf1786752d6dedc3b1f29e8f8fb2ad1d0a36f377cf442" dependencies = [ "memchr", - "thiserror 2.0.6", + "thiserror 1.0.69", "ucd-trie", ] [[package]] name = "pest_derive" -version = "2.7.15" +version = "2.7.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "816518421cfc6887a0d62bf441b6ffb4536fcc926395a69e1a85852d4363f57e" +checksum = "d214365f632b123a47fd913301e14c946c61d1c183ee245fa76eb752e59a02dd" dependencies = [ "pest", "pest_generator", @@ -2950,9 +2950,9 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.7.15" +version = "2.7.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d1396fd3a870fc7838768d171b4616d5c91f6cc25e377b673d714567d99377b" +checksum = "eb55586734301717aea2ac313f50b2eb8f60d2fc3dc01d190eefa2e625f60c4e" dependencies = [ "pest", "pest_meta", @@ -2963,9 +2963,9 @@ dependencies = [ [[package]] name = "pest_meta" -version = "2.7.15" +version = "2.7.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1e58089ea25d717bfd31fb534e4f3afcc2cc569c70de3e239778991ea3b7dea" +checksum = "b75da2a70cf4d9cb76833c990ac9cd3923c9a8905a8929789ce347c84564d03d" dependencies = [ "once_cell", "pest", @@ -3055,9 +3055,9 @@ checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" [[package]] name = "png" -version = "0.17.15" +version = "0.17.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b67582bd5b65bdff614270e2ea89a1cf15bef71245cc1e5f7ea126977144211d" +checksum = "52f9d46a34a05a6a57566bc2bfae066ef07585a6e3fa30fbbdff5936380623f0" dependencies = [ "bitflags 1.3.2", "crc32fast", @@ -3230,7 +3230,7 @@ version = "0.9.0-beta.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a98fa0b8309344136abe6244130311e76997e546f76fae8054422a7539b43df7" dependencies = [ - "zerocopy 0.8.13", + "zerocopy 0.8.12", ] [[package]] @@ -3332,9 +3332,9 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.5.8" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03a862b389f93e68874fbf580b9de08dd02facb9a788ebadaf4a3fd33cf58834" +checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f" dependencies = [ "bitflags 2.6.0", ] @@ -3538,22 +3538,22 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.42" +version = "0.38.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f93dc38ecbab2eb790ff964bb77fa94faf256fd3e73285fd7ba0903b76bedb85" +checksum = "d7f649912bc1495e167a6edee79151c84b1bad49748cb4f1f1167f459f6224f6" dependencies = [ "bitflags 2.6.0", "errno", "libc", "linux-raw-sys", - "windows-sys 0.59.0", + "windows-sys 0.52.0", ] [[package]] name = "rustls" -version = "0.23.20" +version = "0.23.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5065c3f250cbd332cd894be57c40fa52387247659b14a2d6041d121547903b1b" +checksum = "934b404430bb06b3fae2cba809eb45a1ab1aecd64491213d7c3301b88393f8d1" dependencies = [ "log", "once_cell", @@ -3701,9 +3701,9 @@ checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" [[package]] name = "serde" -version = "1.0.216" +version = "1.0.215" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b9781016e935a97e8beecf0c933758c97a5520d32930e460142b4cd80c6338e" +checksum = "6513c1ad0b11a9376da888e3e0baa0077f1aed55c17f50e7b2397136129fb88f" dependencies = [ "serde_derive", ] @@ -3749,9 +3749,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.216" +version = "1.0.215" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46f859dbbf73865c6627ed570e78961cd3ac92407a2d117204c49232485da55e" +checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0" dependencies = [ "proc-macro2", "quote", @@ -4248,9 +4248,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.13" +version = "0.7.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7fcaa8d55a2bdd6b83ace262b016eca0d79ee02818c5c1bcdf0305114081078" +checksum = "61e7c3654c13bcd040d4a03abee2c75b1d14a37b423cf5a813ceae1cc903ec6a" dependencies = [ "bytes", "futures-core", @@ -4349,9 +4349,9 @@ checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] name = "typewit" -version = "1.11.0" +version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb77c29baba9e4d3a6182d51fa75e3215c7fd1dab8f4ea9d107c716878e55fc0" +checksum = "d51dbd25812f740f45e2a9769f84711982e000483b13b73a8a1852e092abac8c" dependencies = [ "typewit_proc_macros", ] @@ -4400,9 +4400,9 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "ureq" -version = "2.12.1" +version = "2.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02d1a66277ed75f640d608235660df48c8e3c19f3b4edb6a263315626cc3c01d" +checksum = "3193f92e105038f98ae68af40c008e3c94f2f046926e0f95e6c835dc6459bac8" dependencies = [ "base64 0.22.1", "flate2", @@ -4508,9 +4508,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.99" +version = "0.2.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a474f6281d1d70c17ae7aa6a613c87fce69a127e2624002df63dcb39d6cf6396" +checksum = "d15e63b4482863c109d70a7b8706c1e364eb6ea449b201a76c5b89cedcec2d5c" dependencies = [ "cfg-if", "once_cell", @@ -4519,12 +4519,13 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.99" +version = "0.2.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f89bb38646b4f81674e8f5c3fb81b562be1fd936d84320f3264486418519c79" +checksum = "8d36ef12e3aaca16ddd3f67922bc63e48e953f126de60bd33ccc0101ef9998cd" dependencies = [ "bumpalo", "log", + "once_cell", "proc-macro2", "quote", "syn 2.0.90", @@ -4533,9 +4534,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.49" +version = "0.4.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38176d9b44ea84e9184eff0bc34cc167ed044f816accfe5922e54d84cf48eca2" +checksum = "9dfaf8f50e5f293737ee323940c7d8b08a66a95a419223d9f41610ca08b0833d" dependencies = [ "cfg-if", "js-sys", @@ -4546,9 +4547,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.99" +version = "0.2.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2cc6181fd9a7492eef6fef1f33961e3695e4579b9872a6f7c83aee556666d4fe" +checksum = "705440e08b42d3e4b36de7d66c944be628d579796b8090bfa3471478a2260051" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -4556,9 +4557,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.99" +version = "0.2.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30d7a95b763d3c45903ed6c81f156801839e5ee968bb07e534c44df0fcd330c2" +checksum = "98c9ae5a76e46f4deecd0f0255cc223cfa18dc9b261213b8aa0c7b36f61b3f1d" dependencies = [ "proc-macro2", "quote", @@ -4569,18 +4570,19 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.99" +version = "0.2.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "943aab3fdaaa029a6e0271b35ea10b72b943135afe9bffca82384098ad0e06a6" +checksum = "6ee99da9c5ba11bd675621338ef6fa52296b76b83305e9b6e5c77d4c286d6d49" [[package]] name = "wasm-bindgen-test" -version = "0.3.49" +version = "0.3.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c61d44563646eb934577f2772656c7ad5e9c90fac78aa8013d776fcdaf24625d" +checksum = "3d919bb60ebcecb9160afee6c71b43a58a4f0517a2de0054cd050d02cec08201" dependencies = [ "js-sys", "minicov", + "once_cell", "scoped-tls", "wasm-bindgen", "wasm-bindgen-futures", @@ -4589,9 +4591,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-test-macro" -version = "0.3.49" +version = "0.3.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54171416ce73aa0b9c377b51cc3cb542becee1cd678204812e8392e5b0e4a031" +checksum = "222ebde6ea87fbfa6bdd2e9f1fd8a91d60aee5db68792632176c4e16a74fc7d8" dependencies = [ "proc-macro2", "quote", @@ -4600,9 +4602,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.76" +version = "0.3.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04dd7223427d52553d3702c004d3b2fe07c148165faa56313cb00211e31c12bc" +checksum = "a98bc3c33f0fe7e59ad7cd041b89034fa82a7c2d4365ca538dda6cdaf513863c" dependencies = [ "js-sys", "wasm-bindgen", @@ -4886,11 +4888,11 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.8.13" +version = "0.8.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67914ab451f3bfd2e69e5e9d2ef3858484e7074d63f204fd166ec391b54de21d" +checksum = "e031087b26520ba76806365896f191416ce84873ed6c6910a9ab5fe0f98f8ed3" dependencies = [ - "zerocopy-derive 0.8.13", + "zerocopy-derive 0.8.12", ] [[package]] @@ -4906,9 +4908,9 @@ dependencies = [ [[package]] name = "zerocopy-derive" -version = "0.8.13" +version = "0.8.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7988d73a4303ca289df03316bc490e934accf371af6bc745393cf3c2c5c4f25d" +checksum = "568244125ba0fc91ae949b97f2852f82cb1a65c3327bd68e6edadd29e67cca26" dependencies = [ "proc-macro2", "quote", diff --git a/cli/CHANGELOG.md b/cli/CHANGELOG.md index 1d9856200..67410d583 100644 --- a/cli/CHANGELOG.md +++ b/cli/CHANGELOG.md @@ -6,26 +6,6 @@ This project adheres to [Semantic Versioning](https://semver.org), except that Since version 0.10.0, the format of this changelog is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). -## [0.10.0](https://github.com/contentauth/c2pa-rs/compare/c2patool-v0.9.12...c2patool-v0.10.0) -_11 December 2024_ - -### Added - -* Updates c2patool to use only the new Builder/Reader API (contentauth/c2patool#297) - -### Documented - -* Update Contributing guide, misc minor edits (contentauth/c2patool#296) - -### Other - -* Move profile settings to workspace Cargo.toml -* Fix README links -* Update repository link in cli/Cargo.toml -* Fix formatting of cli/CHANGELOG.md -* Merge branch 'c2patool-main' into c2patool-merge -* Enlarged description of c2pa command-line behavior (contentauth/c2patool[#285](https://github.com/contentauth/c2pa-rs/pull/285)) - ## 0.9.12 _18 October 2024_ diff --git a/cli/Cargo.toml b/cli/Cargo.toml index 094d7ad3b..d6ee7c45a 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -2,7 +2,7 @@ name = "c2patool" default-run = "c2patool" -version = "0.10.0" +version = "0.9.12" description = "Tool for displaying and creating C2PA manifests." authors = [ @@ -20,7 +20,7 @@ repository = "https://github.com/contentauth/c2pa-rs/tree/main/cli" [dependencies] anyhow = "1.0" atree = "0.5.2" -c2pa = { path = "../sdk", version = "0.40.0", features = [ +c2pa = { path = "../sdk", version = "0.39.0", features = [ "fetch_remote_manifests", "file_io", "add_thumbnails", diff --git a/internal/crypto/CHANGELOG.md b/internal/crypto/CHANGELOG.md index f0ca74a39..9fd3291d8 100644 --- a/internal/crypto/CHANGELOG.md +++ b/internal/crypto/CHANGELOG.md @@ -6,24 +6,6 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm The format of this changelog is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). -## [0.2.0](https://github.com/contentauth/c2pa-rs/compare/c2pa-crypto-v0.1.2...c2pa-crypto-v0.2.0) -_11 December 2024_ - -### Added - -* Add `RawSigner` trait to `c2pa-crypto` (derived from `c2pa::Signer`) (#716) -* Move time stamp code into c2pa-crypto (#696) - -### Fixed - -* Verbose assertions for `is_none()` (#704) -* Remove `c2pa::Signer` dependency on `c2pa_crypto::TimeStampProvider` (#718) -* Treat Unicode-3.0 license as approved; unpin related dependencies (#693) - -### Updated dependencies - -* Bump chrono from 0.4.38 to 0.4.39 (#763) - ## [0.1.2](https://github.com/contentauth/c2pa-rs/compare/c2pa-crypto-v0.1.1...c2pa-crypto-v0.1.2) _24 October 2024_ diff --git a/internal/crypto/Cargo.toml b/internal/crypto/Cargo.toml index 80ac08e52..0a264ad33 100644 --- a/internal/crypto/Cargo.toml +++ b/internal/crypto/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "c2pa-crypto" -version = "0.2.0" +version = "0.1.2" description = "Cryptography internals for c2pa-rs crate" authors = [ "Maurice Fisher ", diff --git a/sdk/Cargo.toml b/sdk/Cargo.toml index dd837b568..eb2082649 100644 --- a/sdk/Cargo.toml +++ b/sdk/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "c2pa" -version = "0.40.0" +version = "0.39.0" description = "Rust SDK for C2PA (Coalition for Content Provenance and Authenticity) implementors" authors = [ "Maurice Fisher ", @@ -72,7 +72,7 @@ bcder = "0.7.3" bytes = "1.7.2" byteorder = { version = "1.4.3", default-features = false } byteordered = "0.6.0" -c2pa-crypto = { path = "../internal/crypto", version = "0.2.0" } +c2pa-crypto = { path = "../internal/crypto", version = "0.1.2" } c2pa-status-tracker = { path = "../internal/status-tracker", version = "0.1.0" } chrono = { version = "0.4.39", default-features = false, features = [ "serde", From 05be7b4bb8aaa6348a4abea1a6d7236cae9931a0 Mon Sep 17 00:00:00 2001 From: Eric Scouten Date: Wed, 11 Dec 2024 16:02:42 -0800 Subject: [PATCH 19/29] chore: release (#767) --- CHANGELOG.md | 28 +++++ Cargo.lock | 146 +++++++++++++-------------- cli/CHANGELOG.md | 17 ++++ cli/Cargo.toml | 4 +- internal/crypto/CHANGELOG.md | 18 ++++ internal/crypto/Cargo.toml | 4 +- internal/status-tracker/CHANGELOG.md | 7 ++ internal/status-tracker/Cargo.toml | 2 +- sdk/Cargo.toml | 6 +- 9 files changed, 150 insertions(+), 82 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d6ee3dd3a..a630bdfc9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,34 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm Since version 0.36.2, the format of this changelog is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). +## [0.40.0](https://github.com/contentauth/c2pa-rs/compare/c2pa-v0.39.0...c2pa-v0.40.0) +_11 December 2024_ + +### Added + +* Add `RawSigner` trait to `c2pa-crypto` (derived from `c2pa::Signer`) (#716) +* Move time stamp code into c2pa-crypto (#696) +* Adds ValidationState support (#701) +* Introduce `DynamicAssertion` trait (#566) + +### Fixed + +* Verbose assertions for `is_none()` (#704) +* Remove `c2pa::Signer` dependency on `c2pa_crypto::TimeStampProvider` (#718) +* Add support for MP3 without ID3 header (#652) +* Treat Unicode-3.0 license as approved; unpin related dependencies (#693) +* Remote manifest fetch test was not using full path (#675) +* Fix #624 (edge cases when combining the box hashes) (#625) +* Fix #672, Callback is unsound (#674) +* Support "remote_manifest_fetch" verify setting (#667) + +### Updated dependencies + +* Bump chrono from 0.4.38 to 0.4.39 (#763) +* Bump asn1-rs from 0.5.2 to 0.6.2 (#724) +* Bump mockall requirement from 0.11.2 to 0.13.1 in /sdk (#685) +* Update zip requirement from 0.6.6 to 2.2.1 in /sdk (#698) + ## [0.39.0](https://github.com/contentauth/c2pa-rs/compare/c2pa-v0.38.0...c2pa-v0.39.0) _13 November 2024_ diff --git a/Cargo.lock b/Cargo.lock index 5cc776310..44f6b3a65 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -611,9 +611,9 @@ dependencies = [ [[package]] name = "bstr" -version = "1.11.0" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a68f1f47cdf0ec8ee4b941b2eee2a80cb796db73118c0dd09ac63fbe405be22" +checksum = "786a307d683a5bf92e6fd5fd69a7eb613751668d1d8d67d802846dfe367c62c8" dependencies = [ "memchr", "regex-automata", @@ -661,7 +661,7 @@ checksum = "325918d6fe32f23b19878fe4b34794ae41fc19ddbe53b10571a4874d44ffd39b" [[package]] name = "c2pa" -version = "0.39.0" +version = "0.40.0" dependencies = [ "actix", "anyhow", @@ -744,7 +744,7 @@ dependencies = [ [[package]] name = "c2pa-crypto" -version = "0.1.2" +version = "0.2.0" dependencies = [ "actix", "async-generic", @@ -790,11 +790,11 @@ dependencies = [ [[package]] name = "c2pa-status-tracker" -version = "0.1.0" +version = "0.2.0" [[package]] name = "c2patool" -version = "0.9.12" +version = "0.10.0" dependencies = [ "anyhow", "assert_cmd", @@ -824,9 +824,9 @@ version = "0.1.1" [[package]] name = "cc" -version = "1.2.2" +version = "1.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f34d93e62b03caf570cccc334cbc6c2fceca82f39211051345108adcba3eebdc" +checksum = "27f657647bcff5394bf56c7317665bbf790a137a50eaaa5c6bfbb9e27a518f2d" dependencies = [ "shlex", ] @@ -1501,15 +1501,15 @@ dependencies = [ [[package]] name = "fastrand" -version = "2.2.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "486f806e73c5707928240ddc295403b1b93c96a02038563881c4a2fd84b81ac4" +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" [[package]] name = "fdeflate" -version = "0.3.6" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07c6f4c64c1d33a3111c4466f7365ebdcc37c5bd1ea0d62aae2e3d722aacbedb" +checksum = "1e6853b52649d4ac5c0bd02320cddc5ba956bdb407c4b75a2c6b75bf51500f8c" dependencies = [ "simd-adler32", ] @@ -2328,9 +2328,9 @@ checksum = "f5d4a7da358eff58addd2877a45865158f0d78c911d43a5784ceb7bbf52833b0" [[package]] name = "js-sys" -version = "0.3.74" +version = "0.3.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a865e038f7f6ed956f788f0d7d60c541fff74c7bd74272c5d4cf15c63743e705" +checksum = "6717b6b5b077764fb5966237269cb3c64edddde4b14ce42647430a78ced9e7b7" dependencies = [ "once_cell", "wasm-bindgen", @@ -2359,9 +2359,9 @@ dependencies = [ [[package]] name = "konst" -version = "0.3.14" +version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b65f00fb3910881e52bf0850ae2a82aea411488a557e1c02820ceaa60963dce3" +checksum = "298ddf99f06a97c1ecd0e910932662b7842855046234b0d0376d35d93add087f" dependencies = [ "const_panic", "konst_kernel", @@ -2370,9 +2370,9 @@ dependencies = [ [[package]] name = "konst_kernel" -version = "0.3.12" +version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "599c1232f55c72c7fc378335a3efe1c878c92720838c8e6a4fd87784ef7764de" +checksum = "e4b1eb7788f3824c629b1116a7a9060d6e898c358ebff59070093d51103dcc3c" dependencies = [ "typewit", ] @@ -2434,9 +2434,9 @@ checksum = "db13adb97ab515a3691f56e4dbab09283d0b86cb45abd991d8634a9d6f501760" [[package]] name = "libc" -version = "0.2.167" +version = "0.2.168" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09d6582e104315a817dff97f75133544b2e094ee22447d2acf4a74e189ba06fc" +checksum = "5aaeb2981e0606ca11d79718f8bb01164f1d6ed75080182d3abf017e6d244b6d" [[package]] name = "libm" @@ -2929,20 +2929,20 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pest" -version = "2.7.14" +version = "2.7.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "879952a81a83930934cbf1786752d6dedc3b1f29e8f8fb2ad1d0a36f377cf442" +checksum = "8b7cafe60d6cf8e62e1b9b2ea516a089c008945bb5a275416789e7db0bc199dc" dependencies = [ "memchr", - "thiserror 1.0.69", + "thiserror 2.0.6", "ucd-trie", ] [[package]] name = "pest_derive" -version = "2.7.14" +version = "2.7.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d214365f632b123a47fd913301e14c946c61d1c183ee245fa76eb752e59a02dd" +checksum = "816518421cfc6887a0d62bf441b6ffb4536fcc926395a69e1a85852d4363f57e" dependencies = [ "pest", "pest_generator", @@ -2950,9 +2950,9 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.7.14" +version = "2.7.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb55586734301717aea2ac313f50b2eb8f60d2fc3dc01d190eefa2e625f60c4e" +checksum = "7d1396fd3a870fc7838768d171b4616d5c91f6cc25e377b673d714567d99377b" dependencies = [ "pest", "pest_meta", @@ -2963,9 +2963,9 @@ dependencies = [ [[package]] name = "pest_meta" -version = "2.7.14" +version = "2.7.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b75da2a70cf4d9cb76833c990ac9cd3923c9a8905a8929789ce347c84564d03d" +checksum = "e1e58089ea25d717bfd31fb534e4f3afcc2cc569c70de3e239778991ea3b7dea" dependencies = [ "once_cell", "pest", @@ -3055,9 +3055,9 @@ checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" [[package]] name = "png" -version = "0.17.14" +version = "0.17.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52f9d46a34a05a6a57566bc2bfae066ef07585a6e3fa30fbbdff5936380623f0" +checksum = "b67582bd5b65bdff614270e2ea89a1cf15bef71245cc1e5f7ea126977144211d" dependencies = [ "bitflags 1.3.2", "crc32fast", @@ -3230,7 +3230,7 @@ version = "0.9.0-beta.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a98fa0b8309344136abe6244130311e76997e546f76fae8054422a7539b43df7" dependencies = [ - "zerocopy 0.8.12", + "zerocopy 0.8.13", ] [[package]] @@ -3332,9 +3332,9 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.5.7" +version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f" +checksum = "03a862b389f93e68874fbf580b9de08dd02facb9a788ebadaf4a3fd33cf58834" dependencies = [ "bitflags 2.6.0", ] @@ -3538,22 +3538,22 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.41" +version = "0.38.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7f649912bc1495e167a6edee79151c84b1bad49748cb4f1f1167f459f6224f6" +checksum = "f93dc38ecbab2eb790ff964bb77fa94faf256fd3e73285fd7ba0903b76bedb85" dependencies = [ "bitflags 2.6.0", "errno", "libc", "linux-raw-sys", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] name = "rustls" -version = "0.23.19" +version = "0.23.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "934b404430bb06b3fae2cba809eb45a1ab1aecd64491213d7c3301b88393f8d1" +checksum = "5065c3f250cbd332cd894be57c40fa52387247659b14a2d6041d121547903b1b" dependencies = [ "log", "once_cell", @@ -3701,9 +3701,9 @@ checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" [[package]] name = "serde" -version = "1.0.215" +version = "1.0.216" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6513c1ad0b11a9376da888e3e0baa0077f1aed55c17f50e7b2397136129fb88f" +checksum = "0b9781016e935a97e8beecf0c933758c97a5520d32930e460142b4cd80c6338e" dependencies = [ "serde_derive", ] @@ -3749,9 +3749,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.215" +version = "1.0.216" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0" +checksum = "46f859dbbf73865c6627ed570e78961cd3ac92407a2d117204c49232485da55e" dependencies = [ "proc-macro2", "quote", @@ -4248,9 +4248,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.12" +version = "0.7.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61e7c3654c13bcd040d4a03abee2c75b1d14a37b423cf5a813ceae1cc903ec6a" +checksum = "d7fcaa8d55a2bdd6b83ace262b016eca0d79ee02818c5c1bcdf0305114081078" dependencies = [ "bytes", "futures-core", @@ -4349,9 +4349,9 @@ checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] name = "typewit" -version = "1.10.1" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d51dbd25812f740f45e2a9769f84711982e000483b13b73a8a1852e092abac8c" +checksum = "cb77c29baba9e4d3a6182d51fa75e3215c7fd1dab8f4ea9d107c716878e55fc0" dependencies = [ "typewit_proc_macros", ] @@ -4400,9 +4400,9 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "ureq" -version = "2.12.0" +version = "2.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3193f92e105038f98ae68af40c008e3c94f2f046926e0f95e6c835dc6459bac8" +checksum = "02d1a66277ed75f640d608235660df48c8e3c19f3b4edb6a263315626cc3c01d" dependencies = [ "base64 0.22.1", "flate2", @@ -4508,9 +4508,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.97" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d15e63b4482863c109d70a7b8706c1e364eb6ea449b201a76c5b89cedcec2d5c" +checksum = "a474f6281d1d70c17ae7aa6a613c87fce69a127e2624002df63dcb39d6cf6396" dependencies = [ "cfg-if", "once_cell", @@ -4519,13 +4519,12 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.97" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d36ef12e3aaca16ddd3f67922bc63e48e953f126de60bd33ccc0101ef9998cd" +checksum = "5f89bb38646b4f81674e8f5c3fb81b562be1fd936d84320f3264486418519c79" dependencies = [ "bumpalo", "log", - "once_cell", "proc-macro2", "quote", "syn 2.0.90", @@ -4534,9 +4533,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.47" +version = "0.4.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dfaf8f50e5f293737ee323940c7d8b08a66a95a419223d9f41610ca08b0833d" +checksum = "38176d9b44ea84e9184eff0bc34cc167ed044f816accfe5922e54d84cf48eca2" dependencies = [ "cfg-if", "js-sys", @@ -4547,9 +4546,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.97" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "705440e08b42d3e4b36de7d66c944be628d579796b8090bfa3471478a2260051" +checksum = "2cc6181fd9a7492eef6fef1f33961e3695e4579b9872a6f7c83aee556666d4fe" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -4557,9 +4556,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.97" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98c9ae5a76e46f4deecd0f0255cc223cfa18dc9b261213b8aa0c7b36f61b3f1d" +checksum = "30d7a95b763d3c45903ed6c81f156801839e5ee968bb07e534c44df0fcd330c2" dependencies = [ "proc-macro2", "quote", @@ -4570,19 +4569,18 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.97" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ee99da9c5ba11bd675621338ef6fa52296b76b83305e9b6e5c77d4c286d6d49" +checksum = "943aab3fdaaa029a6e0271b35ea10b72b943135afe9bffca82384098ad0e06a6" [[package]] name = "wasm-bindgen-test" -version = "0.3.47" +version = "0.3.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d919bb60ebcecb9160afee6c71b43a58a4f0517a2de0054cd050d02cec08201" +checksum = "c61d44563646eb934577f2772656c7ad5e9c90fac78aa8013d776fcdaf24625d" dependencies = [ "js-sys", "minicov", - "once_cell", "scoped-tls", "wasm-bindgen", "wasm-bindgen-futures", @@ -4591,9 +4589,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-test-macro" -version = "0.3.47" +version = "0.3.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "222ebde6ea87fbfa6bdd2e9f1fd8a91d60aee5db68792632176c4e16a74fc7d8" +checksum = "54171416ce73aa0b9c377b51cc3cb542becee1cd678204812e8392e5b0e4a031" dependencies = [ "proc-macro2", "quote", @@ -4602,9 +4600,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.74" +version = "0.3.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a98bc3c33f0fe7e59ad7cd041b89034fa82a7c2d4365ca538dda6cdaf513863c" +checksum = "04dd7223427d52553d3702c004d3b2fe07c148165faa56313cb00211e31c12bc" dependencies = [ "js-sys", "wasm-bindgen", @@ -4888,11 +4886,11 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.8.12" +version = "0.8.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e031087b26520ba76806365896f191416ce84873ed6c6910a9ab5fe0f98f8ed3" +checksum = "67914ab451f3bfd2e69e5e9d2ef3858484e7074d63f204fd166ec391b54de21d" dependencies = [ - "zerocopy-derive 0.8.12", + "zerocopy-derive 0.8.13", ] [[package]] @@ -4908,9 +4906,9 @@ dependencies = [ [[package]] name = "zerocopy-derive" -version = "0.8.12" +version = "0.8.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "568244125ba0fc91ae949b97f2852f82cb1a65c3327bd68e6edadd29e67cca26" +checksum = "7988d73a4303ca289df03316bc490e934accf371af6bc745393cf3c2c5c4f25d" dependencies = [ "proc-macro2", "quote", diff --git a/cli/CHANGELOG.md b/cli/CHANGELOG.md index 67410d583..87647f99f 100644 --- a/cli/CHANGELOG.md +++ b/cli/CHANGELOG.md @@ -6,6 +6,23 @@ This project adheres to [Semantic Versioning](https://semver.org), except that Since version 0.10.0, the format of this changelog is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). +## [0.10.0](https://github.com/contentauth/c2pa-rs/compare/c2patool-v0.9.12...c2patool-v0.10.0) +_11 December 2024_ + +### Added + +* Updates c2patool to use only the new Builder/Reader API (contentauth/c2patool#297) + +### Documented + +* Update Contributing guide, misc minor edits (contentauth/c2patool#296) + +### Other + +* Move c2patool source code into c2pa-rs repo +* Move profile settings to workspace Cargo.toml +* Enlarged description of c2pa command-line behavior (contentauth/c2patool[#285](https://github.com/contentauth/c2pa-rs/pull/285)) + ## 0.9.12 _18 October 2024_ diff --git a/cli/Cargo.toml b/cli/Cargo.toml index d6ee7c45a..094d7ad3b 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -2,7 +2,7 @@ name = "c2patool" default-run = "c2patool" -version = "0.9.12" +version = "0.10.0" description = "Tool for displaying and creating C2PA manifests." authors = [ @@ -20,7 +20,7 @@ repository = "https://github.com/contentauth/c2pa-rs/tree/main/cli" [dependencies] anyhow = "1.0" atree = "0.5.2" -c2pa = { path = "../sdk", version = "0.39.0", features = [ +c2pa = { path = "../sdk", version = "0.40.0", features = [ "fetch_remote_manifests", "file_io", "add_thumbnails", diff --git a/internal/crypto/CHANGELOG.md b/internal/crypto/CHANGELOG.md index 9fd3291d8..f0ca74a39 100644 --- a/internal/crypto/CHANGELOG.md +++ b/internal/crypto/CHANGELOG.md @@ -6,6 +6,24 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm The format of this changelog is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). +## [0.2.0](https://github.com/contentauth/c2pa-rs/compare/c2pa-crypto-v0.1.2...c2pa-crypto-v0.2.0) +_11 December 2024_ + +### Added + +* Add `RawSigner` trait to `c2pa-crypto` (derived from `c2pa::Signer`) (#716) +* Move time stamp code into c2pa-crypto (#696) + +### Fixed + +* Verbose assertions for `is_none()` (#704) +* Remove `c2pa::Signer` dependency on `c2pa_crypto::TimeStampProvider` (#718) +* Treat Unicode-3.0 license as approved; unpin related dependencies (#693) + +### Updated dependencies + +* Bump chrono from 0.4.38 to 0.4.39 (#763) + ## [0.1.2](https://github.com/contentauth/c2pa-rs/compare/c2pa-crypto-v0.1.1...c2pa-crypto-v0.1.2) _24 October 2024_ diff --git a/internal/crypto/Cargo.toml b/internal/crypto/Cargo.toml index 0a264ad33..17dd7bc5b 100644 --- a/internal/crypto/Cargo.toml +++ b/internal/crypto/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "c2pa-crypto" -version = "0.1.2" +version = "0.2.0" description = "Cryptography internals for c2pa-rs crate" authors = [ "Maurice Fisher ", @@ -35,7 +35,7 @@ async-trait = "0.1.77" base64 = "0.22.1" bcder = "0.7.3" bytes = "1.7.2" -c2pa-status-tracker = { path = "../status-tracker", version = "0.1.0" } +c2pa-status-tracker = { path = "../status-tracker", version = "0.2.0" } ciborium = "0.2.2" const-hex = "1.14" coset = "0.3.1" diff --git a/internal/status-tracker/CHANGELOG.md b/internal/status-tracker/CHANGELOG.md index 0b7dca1e4..a8b844038 100644 --- a/internal/status-tracker/CHANGELOG.md +++ b/internal/status-tracker/CHANGELOG.md @@ -6,6 +6,13 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm The format of this changelog is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). +## [0.2.0](https://github.com/contentauth/c2pa-rs/compare/c2pa-status-tracker-v0.1.0...c2pa-status-tracker-v0.2.0) +_11 December 2024_ + +### Added + +* Move `validation_codes` from `c2pa-crypto` to `c2pa-status-tracker` + ## [0.1.0](https://github.com/contentauth/c2pa-rs/releases/tag/c2pa-status-tracker-v0.1.0) _13 November 2024_ diff --git a/internal/status-tracker/Cargo.toml b/internal/status-tracker/Cargo.toml index 1d6f015c9..5749c8742 100644 --- a/internal/status-tracker/Cargo.toml +++ b/internal/status-tracker/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "c2pa-status-tracker" -version = "0.1.0" +version = "0.2.0" description = "Status tracking internals for c2pa-rs crate" authors = [ "Maurice Fisher ", diff --git a/sdk/Cargo.toml b/sdk/Cargo.toml index eb2082649..212d56b49 100644 --- a/sdk/Cargo.toml +++ b/sdk/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "c2pa" -version = "0.39.0" +version = "0.40.0" description = "Rust SDK for C2PA (Coalition for Content Provenance and Authenticity) implementors" authors = [ "Maurice Fisher ", @@ -72,8 +72,8 @@ bcder = "0.7.3" bytes = "1.7.2" byteorder = { version = "1.4.3", default-features = false } byteordered = "0.6.0" -c2pa-crypto = { path = "../internal/crypto", version = "0.1.2" } -c2pa-status-tracker = { path = "../internal/status-tracker", version = "0.1.0" } +c2pa-crypto = { path = "../internal/crypto", version = "0.2.0" } +c2pa-status-tracker = { path = "../internal/status-tracker", version = "0.2.0" } chrono = { version = "0.4.39", default-features = false, features = [ "serde", "wasmbind", From 2390938261226001516c413d20cc9e19b0e7653c Mon Sep 17 00:00:00 2001 From: Eric Scouten Date: Wed, 11 Dec 2024 16:29:05 -0800 Subject: [PATCH 20/29] fix: Compile `c2pa-crypto` with `cargo check` (#768) Also: Revert unpublished Cargo.toml and CHANGELOG files --- CHANGELOG.md | 28 ---- Cargo.lock | 144 +++++++++--------- cli/CHANGELOG.md | 17 --- cli/Cargo.toml | 4 +- internal/crypto/CHANGELOG.md | 18 --- internal/crypto/Cargo.toml | 2 +- internal/crypto/src/p1363.rs | 4 +- .../crypto/src/raw_signature/validator.rs | 1 + internal/crypto/src/time_stamp/verify.rs | 11 +- sdk/Cargo.toml | 4 +- sdk/src/assertions/actions.rs | 1 + 11 files changed, 91 insertions(+), 143 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a630bdfc9..d6ee3dd3a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,34 +6,6 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm Since version 0.36.2, the format of this changelog is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). -## [0.40.0](https://github.com/contentauth/c2pa-rs/compare/c2pa-v0.39.0...c2pa-v0.40.0) -_11 December 2024_ - -### Added - -* Add `RawSigner` trait to `c2pa-crypto` (derived from `c2pa::Signer`) (#716) -* Move time stamp code into c2pa-crypto (#696) -* Adds ValidationState support (#701) -* Introduce `DynamicAssertion` trait (#566) - -### Fixed - -* Verbose assertions for `is_none()` (#704) -* Remove `c2pa::Signer` dependency on `c2pa_crypto::TimeStampProvider` (#718) -* Add support for MP3 without ID3 header (#652) -* Treat Unicode-3.0 license as approved; unpin related dependencies (#693) -* Remote manifest fetch test was not using full path (#675) -* Fix #624 (edge cases when combining the box hashes) (#625) -* Fix #672, Callback is unsound (#674) -* Support "remote_manifest_fetch" verify setting (#667) - -### Updated dependencies - -* Bump chrono from 0.4.38 to 0.4.39 (#763) -* Bump asn1-rs from 0.5.2 to 0.6.2 (#724) -* Bump mockall requirement from 0.11.2 to 0.13.1 in /sdk (#685) -* Update zip requirement from 0.6.6 to 2.2.1 in /sdk (#698) - ## [0.39.0](https://github.com/contentauth/c2pa-rs/compare/c2pa-v0.38.0...c2pa-v0.39.0) _13 November 2024_ diff --git a/Cargo.lock b/Cargo.lock index 44f6b3a65..78593211c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -611,9 +611,9 @@ dependencies = [ [[package]] name = "bstr" -version = "1.11.1" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "786a307d683a5bf92e6fd5fd69a7eb613751668d1d8d67d802846dfe367c62c8" +checksum = "1a68f1f47cdf0ec8ee4b941b2eee2a80cb796db73118c0dd09ac63fbe405be22" dependencies = [ "memchr", "regex-automata", @@ -661,7 +661,7 @@ checksum = "325918d6fe32f23b19878fe4b34794ae41fc19ddbe53b10571a4874d44ffd39b" [[package]] name = "c2pa" -version = "0.40.0" +version = "0.39.0" dependencies = [ "actix", "anyhow", @@ -744,7 +744,7 @@ dependencies = [ [[package]] name = "c2pa-crypto" -version = "0.2.0" +version = "0.1.2" dependencies = [ "actix", "async-generic", @@ -794,7 +794,7 @@ version = "0.2.0" [[package]] name = "c2patool" -version = "0.10.0" +version = "0.9.12" dependencies = [ "anyhow", "assert_cmd", @@ -824,9 +824,9 @@ version = "0.1.1" [[package]] name = "cc" -version = "1.2.3" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27f657647bcff5394bf56c7317665bbf790a137a50eaaa5c6bfbb9e27a518f2d" +checksum = "f34d93e62b03caf570cccc334cbc6c2fceca82f39211051345108adcba3eebdc" dependencies = [ "shlex", ] @@ -1501,15 +1501,15 @@ dependencies = [ [[package]] name = "fastrand" -version = "2.3.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" +checksum = "486f806e73c5707928240ddc295403b1b93c96a02038563881c4a2fd84b81ac4" [[package]] name = "fdeflate" -version = "0.3.7" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e6853b52649d4ac5c0bd02320cddc5ba956bdb407c4b75a2c6b75bf51500f8c" +checksum = "07c6f4c64c1d33a3111c4466f7365ebdcc37c5bd1ea0d62aae2e3d722aacbedb" dependencies = [ "simd-adler32", ] @@ -2328,9 +2328,9 @@ checksum = "f5d4a7da358eff58addd2877a45865158f0d78c911d43a5784ceb7bbf52833b0" [[package]] name = "js-sys" -version = "0.3.76" +version = "0.3.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6717b6b5b077764fb5966237269cb3c64edddde4b14ce42647430a78ced9e7b7" +checksum = "a865e038f7f6ed956f788f0d7d60c541fff74c7bd74272c5d4cf15c63743e705" dependencies = [ "once_cell", "wasm-bindgen", @@ -2359,9 +2359,9 @@ dependencies = [ [[package]] name = "konst" -version = "0.3.15" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "298ddf99f06a97c1ecd0e910932662b7842855046234b0d0376d35d93add087f" +checksum = "b65f00fb3910881e52bf0850ae2a82aea411488a557e1c02820ceaa60963dce3" dependencies = [ "const_panic", "konst_kernel", @@ -2370,9 +2370,9 @@ dependencies = [ [[package]] name = "konst_kernel" -version = "0.3.15" +version = "0.3.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4b1eb7788f3824c629b1116a7a9060d6e898c358ebff59070093d51103dcc3c" +checksum = "599c1232f55c72c7fc378335a3efe1c878c92720838c8e6a4fd87784ef7764de" dependencies = [ "typewit", ] @@ -2434,9 +2434,9 @@ checksum = "db13adb97ab515a3691f56e4dbab09283d0b86cb45abd991d8634a9d6f501760" [[package]] name = "libc" -version = "0.2.168" +version = "0.2.167" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aaeb2981e0606ca11d79718f8bb01164f1d6ed75080182d3abf017e6d244b6d" +checksum = "09d6582e104315a817dff97f75133544b2e094ee22447d2acf4a74e189ba06fc" [[package]] name = "libm" @@ -2929,20 +2929,20 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pest" -version = "2.7.15" +version = "2.7.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b7cafe60d6cf8e62e1b9b2ea516a089c008945bb5a275416789e7db0bc199dc" +checksum = "879952a81a83930934cbf1786752d6dedc3b1f29e8f8fb2ad1d0a36f377cf442" dependencies = [ "memchr", - "thiserror 2.0.6", + "thiserror 1.0.69", "ucd-trie", ] [[package]] name = "pest_derive" -version = "2.7.15" +version = "2.7.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "816518421cfc6887a0d62bf441b6ffb4536fcc926395a69e1a85852d4363f57e" +checksum = "d214365f632b123a47fd913301e14c946c61d1c183ee245fa76eb752e59a02dd" dependencies = [ "pest", "pest_generator", @@ -2950,9 +2950,9 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.7.15" +version = "2.7.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d1396fd3a870fc7838768d171b4616d5c91f6cc25e377b673d714567d99377b" +checksum = "eb55586734301717aea2ac313f50b2eb8f60d2fc3dc01d190eefa2e625f60c4e" dependencies = [ "pest", "pest_meta", @@ -2963,9 +2963,9 @@ dependencies = [ [[package]] name = "pest_meta" -version = "2.7.15" +version = "2.7.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1e58089ea25d717bfd31fb534e4f3afcc2cc569c70de3e239778991ea3b7dea" +checksum = "b75da2a70cf4d9cb76833c990ac9cd3923c9a8905a8929789ce347c84564d03d" dependencies = [ "once_cell", "pest", @@ -3055,9 +3055,9 @@ checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" [[package]] name = "png" -version = "0.17.15" +version = "0.17.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b67582bd5b65bdff614270e2ea89a1cf15bef71245cc1e5f7ea126977144211d" +checksum = "52f9d46a34a05a6a57566bc2bfae066ef07585a6e3fa30fbbdff5936380623f0" dependencies = [ "bitflags 1.3.2", "crc32fast", @@ -3230,7 +3230,7 @@ version = "0.9.0-beta.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a98fa0b8309344136abe6244130311e76997e546f76fae8054422a7539b43df7" dependencies = [ - "zerocopy 0.8.13", + "zerocopy 0.8.12", ] [[package]] @@ -3332,9 +3332,9 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.5.8" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03a862b389f93e68874fbf580b9de08dd02facb9a788ebadaf4a3fd33cf58834" +checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f" dependencies = [ "bitflags 2.6.0", ] @@ -3538,22 +3538,22 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.42" +version = "0.38.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f93dc38ecbab2eb790ff964bb77fa94faf256fd3e73285fd7ba0903b76bedb85" +checksum = "d7f649912bc1495e167a6edee79151c84b1bad49748cb4f1f1167f459f6224f6" dependencies = [ "bitflags 2.6.0", "errno", "libc", "linux-raw-sys", - "windows-sys 0.59.0", + "windows-sys 0.52.0", ] [[package]] name = "rustls" -version = "0.23.20" +version = "0.23.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5065c3f250cbd332cd894be57c40fa52387247659b14a2d6041d121547903b1b" +checksum = "934b404430bb06b3fae2cba809eb45a1ab1aecd64491213d7c3301b88393f8d1" dependencies = [ "log", "once_cell", @@ -3701,9 +3701,9 @@ checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" [[package]] name = "serde" -version = "1.0.216" +version = "1.0.215" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b9781016e935a97e8beecf0c933758c97a5520d32930e460142b4cd80c6338e" +checksum = "6513c1ad0b11a9376da888e3e0baa0077f1aed55c17f50e7b2397136129fb88f" dependencies = [ "serde_derive", ] @@ -3749,9 +3749,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.216" +version = "1.0.215" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46f859dbbf73865c6627ed570e78961cd3ac92407a2d117204c49232485da55e" +checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0" dependencies = [ "proc-macro2", "quote", @@ -4248,9 +4248,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.13" +version = "0.7.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7fcaa8d55a2bdd6b83ace262b016eca0d79ee02818c5c1bcdf0305114081078" +checksum = "61e7c3654c13bcd040d4a03abee2c75b1d14a37b423cf5a813ceae1cc903ec6a" dependencies = [ "bytes", "futures-core", @@ -4349,9 +4349,9 @@ checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] name = "typewit" -version = "1.11.0" +version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb77c29baba9e4d3a6182d51fa75e3215c7fd1dab8f4ea9d107c716878e55fc0" +checksum = "d51dbd25812f740f45e2a9769f84711982e000483b13b73a8a1852e092abac8c" dependencies = [ "typewit_proc_macros", ] @@ -4400,9 +4400,9 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "ureq" -version = "2.12.1" +version = "2.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02d1a66277ed75f640d608235660df48c8e3c19f3b4edb6a263315626cc3c01d" +checksum = "3193f92e105038f98ae68af40c008e3c94f2f046926e0f95e6c835dc6459bac8" dependencies = [ "base64 0.22.1", "flate2", @@ -4508,9 +4508,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.99" +version = "0.2.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a474f6281d1d70c17ae7aa6a613c87fce69a127e2624002df63dcb39d6cf6396" +checksum = "d15e63b4482863c109d70a7b8706c1e364eb6ea449b201a76c5b89cedcec2d5c" dependencies = [ "cfg-if", "once_cell", @@ -4519,12 +4519,13 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.99" +version = "0.2.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f89bb38646b4f81674e8f5c3fb81b562be1fd936d84320f3264486418519c79" +checksum = "8d36ef12e3aaca16ddd3f67922bc63e48e953f126de60bd33ccc0101ef9998cd" dependencies = [ "bumpalo", "log", + "once_cell", "proc-macro2", "quote", "syn 2.0.90", @@ -4533,9 +4534,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.49" +version = "0.4.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38176d9b44ea84e9184eff0bc34cc167ed044f816accfe5922e54d84cf48eca2" +checksum = "9dfaf8f50e5f293737ee323940c7d8b08a66a95a419223d9f41610ca08b0833d" dependencies = [ "cfg-if", "js-sys", @@ -4546,9 +4547,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.99" +version = "0.2.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2cc6181fd9a7492eef6fef1f33961e3695e4579b9872a6f7c83aee556666d4fe" +checksum = "705440e08b42d3e4b36de7d66c944be628d579796b8090bfa3471478a2260051" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -4556,9 +4557,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.99" +version = "0.2.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30d7a95b763d3c45903ed6c81f156801839e5ee968bb07e534c44df0fcd330c2" +checksum = "98c9ae5a76e46f4deecd0f0255cc223cfa18dc9b261213b8aa0c7b36f61b3f1d" dependencies = [ "proc-macro2", "quote", @@ -4569,18 +4570,19 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.99" +version = "0.2.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "943aab3fdaaa029a6e0271b35ea10b72b943135afe9bffca82384098ad0e06a6" +checksum = "6ee99da9c5ba11bd675621338ef6fa52296b76b83305e9b6e5c77d4c286d6d49" [[package]] name = "wasm-bindgen-test" -version = "0.3.49" +version = "0.3.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c61d44563646eb934577f2772656c7ad5e9c90fac78aa8013d776fcdaf24625d" +checksum = "3d919bb60ebcecb9160afee6c71b43a58a4f0517a2de0054cd050d02cec08201" dependencies = [ "js-sys", "minicov", + "once_cell", "scoped-tls", "wasm-bindgen", "wasm-bindgen-futures", @@ -4589,9 +4591,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-test-macro" -version = "0.3.49" +version = "0.3.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54171416ce73aa0b9c377b51cc3cb542becee1cd678204812e8392e5b0e4a031" +checksum = "222ebde6ea87fbfa6bdd2e9f1fd8a91d60aee5db68792632176c4e16a74fc7d8" dependencies = [ "proc-macro2", "quote", @@ -4600,9 +4602,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.76" +version = "0.3.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04dd7223427d52553d3702c004d3b2fe07c148165faa56313cb00211e31c12bc" +checksum = "a98bc3c33f0fe7e59ad7cd041b89034fa82a7c2d4365ca538dda6cdaf513863c" dependencies = [ "js-sys", "wasm-bindgen", @@ -4886,11 +4888,11 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.8.13" +version = "0.8.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67914ab451f3bfd2e69e5e9d2ef3858484e7074d63f204fd166ec391b54de21d" +checksum = "e031087b26520ba76806365896f191416ce84873ed6c6910a9ab5fe0f98f8ed3" dependencies = [ - "zerocopy-derive 0.8.13", + "zerocopy-derive 0.8.12", ] [[package]] @@ -4906,9 +4908,9 @@ dependencies = [ [[package]] name = "zerocopy-derive" -version = "0.8.13" +version = "0.8.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7988d73a4303ca289df03316bc490e934accf371af6bc745393cf3c2c5c4f25d" +checksum = "568244125ba0fc91ae949b97f2852f82cb1a65c3327bd68e6edadd29e67cca26" dependencies = [ "proc-macro2", "quote", diff --git a/cli/CHANGELOG.md b/cli/CHANGELOG.md index 87647f99f..67410d583 100644 --- a/cli/CHANGELOG.md +++ b/cli/CHANGELOG.md @@ -6,23 +6,6 @@ This project adheres to [Semantic Versioning](https://semver.org), except that Since version 0.10.0, the format of this changelog is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). -## [0.10.0](https://github.com/contentauth/c2pa-rs/compare/c2patool-v0.9.12...c2patool-v0.10.0) -_11 December 2024_ - -### Added - -* Updates c2patool to use only the new Builder/Reader API (contentauth/c2patool#297) - -### Documented - -* Update Contributing guide, misc minor edits (contentauth/c2patool#296) - -### Other - -* Move c2patool source code into c2pa-rs repo -* Move profile settings to workspace Cargo.toml -* Enlarged description of c2pa command-line behavior (contentauth/c2patool[#285](https://github.com/contentauth/c2pa-rs/pull/285)) - ## 0.9.12 _18 October 2024_ diff --git a/cli/Cargo.toml b/cli/Cargo.toml index 094d7ad3b..d6ee7c45a 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -2,7 +2,7 @@ name = "c2patool" default-run = "c2patool" -version = "0.10.0" +version = "0.9.12" description = "Tool for displaying and creating C2PA manifests." authors = [ @@ -20,7 +20,7 @@ repository = "https://github.com/contentauth/c2pa-rs/tree/main/cli" [dependencies] anyhow = "1.0" atree = "0.5.2" -c2pa = { path = "../sdk", version = "0.40.0", features = [ +c2pa = { path = "../sdk", version = "0.39.0", features = [ "fetch_remote_manifests", "file_io", "add_thumbnails", diff --git a/internal/crypto/CHANGELOG.md b/internal/crypto/CHANGELOG.md index f0ca74a39..9fd3291d8 100644 --- a/internal/crypto/CHANGELOG.md +++ b/internal/crypto/CHANGELOG.md @@ -6,24 +6,6 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm The format of this changelog is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). -## [0.2.0](https://github.com/contentauth/c2pa-rs/compare/c2pa-crypto-v0.1.2...c2pa-crypto-v0.2.0) -_11 December 2024_ - -### Added - -* Add `RawSigner` trait to `c2pa-crypto` (derived from `c2pa::Signer`) (#716) -* Move time stamp code into c2pa-crypto (#696) - -### Fixed - -* Verbose assertions for `is_none()` (#704) -* Remove `c2pa::Signer` dependency on `c2pa_crypto::TimeStampProvider` (#718) -* Treat Unicode-3.0 license as approved; unpin related dependencies (#693) - -### Updated dependencies - -* Bump chrono from 0.4.38 to 0.4.39 (#763) - ## [0.1.2](https://github.com/contentauth/c2pa-rs/compare/c2pa-crypto-v0.1.1...c2pa-crypto-v0.1.2) _24 October 2024_ diff --git a/internal/crypto/Cargo.toml b/internal/crypto/Cargo.toml index 17dd7bc5b..c209242cc 100644 --- a/internal/crypto/Cargo.toml +++ b/internal/crypto/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "c2pa-crypto" -version = "0.2.0" +version = "0.1.2" description = "Cryptography internals for c2pa-rs crate" authors = [ "Maurice Fisher ", diff --git a/internal/crypto/src/p1363.rs b/internal/crypto/src/p1363.rs index 473f24e56..838a4d80b 100644 --- a/internal/crypto/src/p1363.rs +++ b/internal/crypto/src/p1363.rs @@ -44,10 +44,10 @@ pub struct EcSigComps<'a> { pub s: &'a [u8], } -#[cfg(not(target_arch = "wasm32"))] // Maye will be used later? +#[cfg(feature = "openssl")] use crate::{raw_signature::RawSignerError, SigningAlg}; -#[cfg(not(target_arch = "wasm32"))] // Maye will be used later? +#[cfg(feature = "openssl")] pub(crate) fn der_to_p1363(data: &[u8], alg: SigningAlg) -> Result, RawSignerError> { // P1363 format: r | s diff --git a/internal/crypto/src/raw_signature/validator.rs b/internal/crypto/src/raw_signature/validator.rs index 089f2de57..63a5b44b4 100644 --- a/internal/crypto/src/raw_signature/validator.rs +++ b/internal/crypto/src/raw_signature/validator.rs @@ -50,6 +50,7 @@ pub fn validator_for_signing_alg(alg: SigningAlg) -> Option Result DateTime { } } +#[cfg(any(feature = "openssl", target_arch = "wasm32"))] fn validate_timestamp_sig( sig_alg: &bcder::Oid, hash_alg: &bcder::Oid, @@ -337,6 +342,8 @@ fn validate_timestamp_sig( tbs: &[u8], signing_key_der: &[u8], ) -> Result<(), TimeStampError> { + use crate::raw_signature::validator_for_sig_and_hash_algs; + let Some(validator) = validator_for_sig_and_hash_algs(sig_alg, hash_alg) else { return Err(TimeStampError::UnsupportedAlgorithm); }; diff --git a/sdk/Cargo.toml b/sdk/Cargo.toml index 212d56b49..c38d5ea21 100644 --- a/sdk/Cargo.toml +++ b/sdk/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "c2pa" -version = "0.40.0" +version = "0.39.0" description = "Rust SDK for C2PA (Coalition for Content Provenance and Authenticity) implementors" authors = [ "Maurice Fisher ", @@ -72,7 +72,7 @@ bcder = "0.7.3" bytes = "1.7.2" byteorder = { version = "1.4.3", default-features = false } byteordered = "0.6.0" -c2pa-crypto = { path = "../internal/crypto", version = "0.2.0" } +c2pa-crypto = { path = "../internal/crypto", version = "0.1.2" } c2pa-status-tracker = { path = "../internal/status-tracker", version = "0.2.0" } chrono = { version = "0.4.39", default-features = false, features = [ "serde", diff --git a/sdk/src/assertions/actions.rs b/sdk/src/assertions/actions.rs index b17f67c5d..2fe7901b6 100644 --- a/sdk/src/assertions/actions.rs +++ b/sdk/src/assertions/actions.rs @@ -280,6 +280,7 @@ impl Action { } // Internal function to return any ingredients referenced by this action. + #[allow(dead_code)] // not used in some scenarios pub(crate) fn ingredient_ids(&mut self) -> Option> { match self.get_parameter(CAI_INGREDIENT_IDS) { Some(Value::Array(ids)) => { From a2cb9dbc2693d78c2a70a83bf2b59e2a37df3107 Mon Sep 17 00:00:00 2001 From: Eric Scouten Date: Wed, 11 Dec 2024 16:40:06 -0800 Subject: [PATCH 21/29] chore: release (#769) --- CHANGELOG.md | 29 +++++++ Cargo.lock | 144 +++++++++++++++++------------------ cli/CHANGELOG.md | 21 +++++ cli/Cargo.toml | 4 +- internal/crypto/CHANGELOG.md | 19 +++++ internal/crypto/Cargo.toml | 2 +- sdk/Cargo.toml | 4 +- 7 files changed, 145 insertions(+), 78 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d6ee3dd3a..f61183a91 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,35 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm Since version 0.36.2, the format of this changelog is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). +## [0.40.0](https://github.com/contentauth/c2pa-rs/compare/c2pa-v0.39.0...c2pa-v0.40.0) +_12 December 2024_ + +### Added + +* Add `RawSigner` trait to `c2pa-crypto` (derived from `c2pa::Signer`) (#716) +* Move time stamp code into c2pa-crypto (#696) +* Adds ValidationState support (#701) +* Introduce `DynamicAssertion` trait (#566) + +### Fixed + +* Compile `c2pa-crypto` with `cargo check` (#768) +* Verbose assertions for `is_none()` (#704) +* Remove `c2pa::Signer` dependency on `c2pa_crypto::TimeStampProvider` (#718) +* Add support for MP3 without ID3 header (#652) +* Treat Unicode-3.0 license as approved; unpin related dependencies (#693) +* Remote manifest fetch test was not using full path (#675) +* Fix #624 (edge cases when combining the box hashes) (#625) +* Fix #672, Callback is unsound (#674) +* Support "remote_manifest_fetch" verify setting (#667) + +### Updated dependencies + +* Bump chrono from 0.4.38 to 0.4.39 (#763) +* Bump asn1-rs from 0.5.2 to 0.6.2 (#724) +* Bump mockall requirement from 0.11.2 to 0.13.1 in /sdk (#685) +* Update zip requirement from 0.6.6 to 2.2.1 in /sdk (#698) + ## [0.39.0](https://github.com/contentauth/c2pa-rs/compare/c2pa-v0.38.0...c2pa-v0.39.0) _13 November 2024_ diff --git a/Cargo.lock b/Cargo.lock index 78593211c..44f6b3a65 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -611,9 +611,9 @@ dependencies = [ [[package]] name = "bstr" -version = "1.11.0" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a68f1f47cdf0ec8ee4b941b2eee2a80cb796db73118c0dd09ac63fbe405be22" +checksum = "786a307d683a5bf92e6fd5fd69a7eb613751668d1d8d67d802846dfe367c62c8" dependencies = [ "memchr", "regex-automata", @@ -661,7 +661,7 @@ checksum = "325918d6fe32f23b19878fe4b34794ae41fc19ddbe53b10571a4874d44ffd39b" [[package]] name = "c2pa" -version = "0.39.0" +version = "0.40.0" dependencies = [ "actix", "anyhow", @@ -744,7 +744,7 @@ dependencies = [ [[package]] name = "c2pa-crypto" -version = "0.1.2" +version = "0.2.0" dependencies = [ "actix", "async-generic", @@ -794,7 +794,7 @@ version = "0.2.0" [[package]] name = "c2patool" -version = "0.9.12" +version = "0.10.0" dependencies = [ "anyhow", "assert_cmd", @@ -824,9 +824,9 @@ version = "0.1.1" [[package]] name = "cc" -version = "1.2.2" +version = "1.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f34d93e62b03caf570cccc334cbc6c2fceca82f39211051345108adcba3eebdc" +checksum = "27f657647bcff5394bf56c7317665bbf790a137a50eaaa5c6bfbb9e27a518f2d" dependencies = [ "shlex", ] @@ -1501,15 +1501,15 @@ dependencies = [ [[package]] name = "fastrand" -version = "2.2.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "486f806e73c5707928240ddc295403b1b93c96a02038563881c4a2fd84b81ac4" +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" [[package]] name = "fdeflate" -version = "0.3.6" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07c6f4c64c1d33a3111c4466f7365ebdcc37c5bd1ea0d62aae2e3d722aacbedb" +checksum = "1e6853b52649d4ac5c0bd02320cddc5ba956bdb407c4b75a2c6b75bf51500f8c" dependencies = [ "simd-adler32", ] @@ -2328,9 +2328,9 @@ checksum = "f5d4a7da358eff58addd2877a45865158f0d78c911d43a5784ceb7bbf52833b0" [[package]] name = "js-sys" -version = "0.3.74" +version = "0.3.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a865e038f7f6ed956f788f0d7d60c541fff74c7bd74272c5d4cf15c63743e705" +checksum = "6717b6b5b077764fb5966237269cb3c64edddde4b14ce42647430a78ced9e7b7" dependencies = [ "once_cell", "wasm-bindgen", @@ -2359,9 +2359,9 @@ dependencies = [ [[package]] name = "konst" -version = "0.3.14" +version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b65f00fb3910881e52bf0850ae2a82aea411488a557e1c02820ceaa60963dce3" +checksum = "298ddf99f06a97c1ecd0e910932662b7842855046234b0d0376d35d93add087f" dependencies = [ "const_panic", "konst_kernel", @@ -2370,9 +2370,9 @@ dependencies = [ [[package]] name = "konst_kernel" -version = "0.3.12" +version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "599c1232f55c72c7fc378335a3efe1c878c92720838c8e6a4fd87784ef7764de" +checksum = "e4b1eb7788f3824c629b1116a7a9060d6e898c358ebff59070093d51103dcc3c" dependencies = [ "typewit", ] @@ -2434,9 +2434,9 @@ checksum = "db13adb97ab515a3691f56e4dbab09283d0b86cb45abd991d8634a9d6f501760" [[package]] name = "libc" -version = "0.2.167" +version = "0.2.168" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09d6582e104315a817dff97f75133544b2e094ee22447d2acf4a74e189ba06fc" +checksum = "5aaeb2981e0606ca11d79718f8bb01164f1d6ed75080182d3abf017e6d244b6d" [[package]] name = "libm" @@ -2929,20 +2929,20 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pest" -version = "2.7.14" +version = "2.7.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "879952a81a83930934cbf1786752d6dedc3b1f29e8f8fb2ad1d0a36f377cf442" +checksum = "8b7cafe60d6cf8e62e1b9b2ea516a089c008945bb5a275416789e7db0bc199dc" dependencies = [ "memchr", - "thiserror 1.0.69", + "thiserror 2.0.6", "ucd-trie", ] [[package]] name = "pest_derive" -version = "2.7.14" +version = "2.7.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d214365f632b123a47fd913301e14c946c61d1c183ee245fa76eb752e59a02dd" +checksum = "816518421cfc6887a0d62bf441b6ffb4536fcc926395a69e1a85852d4363f57e" dependencies = [ "pest", "pest_generator", @@ -2950,9 +2950,9 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.7.14" +version = "2.7.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb55586734301717aea2ac313f50b2eb8f60d2fc3dc01d190eefa2e625f60c4e" +checksum = "7d1396fd3a870fc7838768d171b4616d5c91f6cc25e377b673d714567d99377b" dependencies = [ "pest", "pest_meta", @@ -2963,9 +2963,9 @@ dependencies = [ [[package]] name = "pest_meta" -version = "2.7.14" +version = "2.7.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b75da2a70cf4d9cb76833c990ac9cd3923c9a8905a8929789ce347c84564d03d" +checksum = "e1e58089ea25d717bfd31fb534e4f3afcc2cc569c70de3e239778991ea3b7dea" dependencies = [ "once_cell", "pest", @@ -3055,9 +3055,9 @@ checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" [[package]] name = "png" -version = "0.17.14" +version = "0.17.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52f9d46a34a05a6a57566bc2bfae066ef07585a6e3fa30fbbdff5936380623f0" +checksum = "b67582bd5b65bdff614270e2ea89a1cf15bef71245cc1e5f7ea126977144211d" dependencies = [ "bitflags 1.3.2", "crc32fast", @@ -3230,7 +3230,7 @@ version = "0.9.0-beta.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a98fa0b8309344136abe6244130311e76997e546f76fae8054422a7539b43df7" dependencies = [ - "zerocopy 0.8.12", + "zerocopy 0.8.13", ] [[package]] @@ -3332,9 +3332,9 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.5.7" +version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f" +checksum = "03a862b389f93e68874fbf580b9de08dd02facb9a788ebadaf4a3fd33cf58834" dependencies = [ "bitflags 2.6.0", ] @@ -3538,22 +3538,22 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.41" +version = "0.38.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7f649912bc1495e167a6edee79151c84b1bad49748cb4f1f1167f459f6224f6" +checksum = "f93dc38ecbab2eb790ff964bb77fa94faf256fd3e73285fd7ba0903b76bedb85" dependencies = [ "bitflags 2.6.0", "errno", "libc", "linux-raw-sys", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] name = "rustls" -version = "0.23.19" +version = "0.23.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "934b404430bb06b3fae2cba809eb45a1ab1aecd64491213d7c3301b88393f8d1" +checksum = "5065c3f250cbd332cd894be57c40fa52387247659b14a2d6041d121547903b1b" dependencies = [ "log", "once_cell", @@ -3701,9 +3701,9 @@ checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" [[package]] name = "serde" -version = "1.0.215" +version = "1.0.216" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6513c1ad0b11a9376da888e3e0baa0077f1aed55c17f50e7b2397136129fb88f" +checksum = "0b9781016e935a97e8beecf0c933758c97a5520d32930e460142b4cd80c6338e" dependencies = [ "serde_derive", ] @@ -3749,9 +3749,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.215" +version = "1.0.216" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0" +checksum = "46f859dbbf73865c6627ed570e78961cd3ac92407a2d117204c49232485da55e" dependencies = [ "proc-macro2", "quote", @@ -4248,9 +4248,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.12" +version = "0.7.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61e7c3654c13bcd040d4a03abee2c75b1d14a37b423cf5a813ceae1cc903ec6a" +checksum = "d7fcaa8d55a2bdd6b83ace262b016eca0d79ee02818c5c1bcdf0305114081078" dependencies = [ "bytes", "futures-core", @@ -4349,9 +4349,9 @@ checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] name = "typewit" -version = "1.10.1" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d51dbd25812f740f45e2a9769f84711982e000483b13b73a8a1852e092abac8c" +checksum = "cb77c29baba9e4d3a6182d51fa75e3215c7fd1dab8f4ea9d107c716878e55fc0" dependencies = [ "typewit_proc_macros", ] @@ -4400,9 +4400,9 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "ureq" -version = "2.12.0" +version = "2.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3193f92e105038f98ae68af40c008e3c94f2f046926e0f95e6c835dc6459bac8" +checksum = "02d1a66277ed75f640d608235660df48c8e3c19f3b4edb6a263315626cc3c01d" dependencies = [ "base64 0.22.1", "flate2", @@ -4508,9 +4508,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.97" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d15e63b4482863c109d70a7b8706c1e364eb6ea449b201a76c5b89cedcec2d5c" +checksum = "a474f6281d1d70c17ae7aa6a613c87fce69a127e2624002df63dcb39d6cf6396" dependencies = [ "cfg-if", "once_cell", @@ -4519,13 +4519,12 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.97" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d36ef12e3aaca16ddd3f67922bc63e48e953f126de60bd33ccc0101ef9998cd" +checksum = "5f89bb38646b4f81674e8f5c3fb81b562be1fd936d84320f3264486418519c79" dependencies = [ "bumpalo", "log", - "once_cell", "proc-macro2", "quote", "syn 2.0.90", @@ -4534,9 +4533,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.47" +version = "0.4.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dfaf8f50e5f293737ee323940c7d8b08a66a95a419223d9f41610ca08b0833d" +checksum = "38176d9b44ea84e9184eff0bc34cc167ed044f816accfe5922e54d84cf48eca2" dependencies = [ "cfg-if", "js-sys", @@ -4547,9 +4546,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.97" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "705440e08b42d3e4b36de7d66c944be628d579796b8090bfa3471478a2260051" +checksum = "2cc6181fd9a7492eef6fef1f33961e3695e4579b9872a6f7c83aee556666d4fe" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -4557,9 +4556,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.97" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98c9ae5a76e46f4deecd0f0255cc223cfa18dc9b261213b8aa0c7b36f61b3f1d" +checksum = "30d7a95b763d3c45903ed6c81f156801839e5ee968bb07e534c44df0fcd330c2" dependencies = [ "proc-macro2", "quote", @@ -4570,19 +4569,18 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.97" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ee99da9c5ba11bd675621338ef6fa52296b76b83305e9b6e5c77d4c286d6d49" +checksum = "943aab3fdaaa029a6e0271b35ea10b72b943135afe9bffca82384098ad0e06a6" [[package]] name = "wasm-bindgen-test" -version = "0.3.47" +version = "0.3.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d919bb60ebcecb9160afee6c71b43a58a4f0517a2de0054cd050d02cec08201" +checksum = "c61d44563646eb934577f2772656c7ad5e9c90fac78aa8013d776fcdaf24625d" dependencies = [ "js-sys", "minicov", - "once_cell", "scoped-tls", "wasm-bindgen", "wasm-bindgen-futures", @@ -4591,9 +4589,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-test-macro" -version = "0.3.47" +version = "0.3.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "222ebde6ea87fbfa6bdd2e9f1fd8a91d60aee5db68792632176c4e16a74fc7d8" +checksum = "54171416ce73aa0b9c377b51cc3cb542becee1cd678204812e8392e5b0e4a031" dependencies = [ "proc-macro2", "quote", @@ -4602,9 +4600,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.74" +version = "0.3.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a98bc3c33f0fe7e59ad7cd041b89034fa82a7c2d4365ca538dda6cdaf513863c" +checksum = "04dd7223427d52553d3702c004d3b2fe07c148165faa56313cb00211e31c12bc" dependencies = [ "js-sys", "wasm-bindgen", @@ -4888,11 +4886,11 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.8.12" +version = "0.8.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e031087b26520ba76806365896f191416ce84873ed6c6910a9ab5fe0f98f8ed3" +checksum = "67914ab451f3bfd2e69e5e9d2ef3858484e7074d63f204fd166ec391b54de21d" dependencies = [ - "zerocopy-derive 0.8.12", + "zerocopy-derive 0.8.13", ] [[package]] @@ -4908,9 +4906,9 @@ dependencies = [ [[package]] name = "zerocopy-derive" -version = "0.8.12" +version = "0.8.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "568244125ba0fc91ae949b97f2852f82cb1a65c3327bd68e6edadd29e67cca26" +checksum = "7988d73a4303ca289df03316bc490e934accf371af6bc745393cf3c2c5c4f25d" dependencies = [ "proc-macro2", "quote", diff --git a/cli/CHANGELOG.md b/cli/CHANGELOG.md index 67410d583..b4c492182 100644 --- a/cli/CHANGELOG.md +++ b/cli/CHANGELOG.md @@ -6,6 +6,27 @@ This project adheres to [Semantic Versioning](https://semver.org), except that Since version 0.10.0, the format of this changelog is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). +## [0.10.0](https://github.com/contentauth/c2pa-rs/compare/c2patool-v0.9.12...c2patool-v0.10.0) +_12 December 2024_ + +### Added + +* Updates c2patool to use only the new Builder/Reader API (contentauth/c2patool#297) + +### Documented + +* Update Contributing guide, misc minor edits (contentauth/c2patool#296) + +### Fixed + +* Compile `c2pa-crypto` with `cargo check` (#768) + +### Other + +* Move c2patool source code into c2pa-rs repo (#723) +* Move profile settings to workspace Cargo.toml +* Enlarged description of c2pa command-line behavior (contentauth/c2patool[#285](https://github.com/contentauth/c2pa-rs/pull/285)) + ## 0.9.12 _18 October 2024_ diff --git a/cli/Cargo.toml b/cli/Cargo.toml index d6ee7c45a..094d7ad3b 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -2,7 +2,7 @@ name = "c2patool" default-run = "c2patool" -version = "0.9.12" +version = "0.10.0" description = "Tool for displaying and creating C2PA manifests." authors = [ @@ -20,7 +20,7 @@ repository = "https://github.com/contentauth/c2pa-rs/tree/main/cli" [dependencies] anyhow = "1.0" atree = "0.5.2" -c2pa = { path = "../sdk", version = "0.39.0", features = [ +c2pa = { path = "../sdk", version = "0.40.0", features = [ "fetch_remote_manifests", "file_io", "add_thumbnails", diff --git a/internal/crypto/CHANGELOG.md b/internal/crypto/CHANGELOG.md index 9fd3291d8..a0b4346d4 100644 --- a/internal/crypto/CHANGELOG.md +++ b/internal/crypto/CHANGELOG.md @@ -6,6 +6,25 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm The format of this changelog is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). +## [0.2.0](https://github.com/contentauth/c2pa-rs/compare/c2pa-crypto-v0.1.2...c2pa-crypto-v0.2.0) +_12 December 2024_ + +### Added + +* Add `RawSigner` trait to `c2pa-crypto` (derived from `c2pa::Signer`) (#716) +* Move time stamp code into c2pa-crypto (#696) + +### Fixed + +* Compile `c2pa-crypto` with `cargo check` (#768) +* Verbose assertions for `is_none()` (#704) +* Remove `c2pa::Signer` dependency on `c2pa_crypto::TimeStampProvider` (#718) +* Treat Unicode-3.0 license as approved; unpin related dependencies (#693) + +### Updated dependencies + +* Bump chrono from 0.4.38 to 0.4.39 (#763) + ## [0.1.2](https://github.com/contentauth/c2pa-rs/compare/c2pa-crypto-v0.1.1...c2pa-crypto-v0.1.2) _24 October 2024_ diff --git a/internal/crypto/Cargo.toml b/internal/crypto/Cargo.toml index c209242cc..17dd7bc5b 100644 --- a/internal/crypto/Cargo.toml +++ b/internal/crypto/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "c2pa-crypto" -version = "0.1.2" +version = "0.2.0" description = "Cryptography internals for c2pa-rs crate" authors = [ "Maurice Fisher ", diff --git a/sdk/Cargo.toml b/sdk/Cargo.toml index c38d5ea21..212d56b49 100644 --- a/sdk/Cargo.toml +++ b/sdk/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "c2pa" -version = "0.39.0" +version = "0.40.0" description = "Rust SDK for C2PA (Coalition for Content Provenance and Authenticity) implementors" authors = [ "Maurice Fisher ", @@ -72,7 +72,7 @@ bcder = "0.7.3" bytes = "1.7.2" byteorder = { version = "1.4.3", default-features = false } byteordered = "0.6.0" -c2pa-crypto = { path = "../internal/crypto", version = "0.1.2" } +c2pa-crypto = { path = "../internal/crypto", version = "0.2.0" } c2pa-status-tracker = { path = "../internal/status-tracker", version = "0.2.0" } chrono = { version = "0.4.39", default-features = false, features = [ "serde", From e17fef731584a1a5f9efd9faee5728c885017cfc Mon Sep 17 00:00:00 2001 From: Eric Scouten Date: Wed, 11 Dec 2024 16:49:31 -0800 Subject: [PATCH 22/29] fix: Binary release process for c2patool --- .github/workflows/release.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 0f2527da5..4a1789881 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -95,7 +95,7 @@ jobs: - name: Run make release if: ${{ needs.release-plz.outputs.c2patool-release-tag }} - run: make release + run: cd cli && make release - name: Upload binary to GitHub if: ${{ needs.release-plz.outputs.c2patool-release-tag }} @@ -109,14 +109,14 @@ jobs: - name: Generate SBOM if: ${{ needs.release-plz.outputs.c2patool-release-tag }} - run: cargo sbom > c2patool.${{ matrix.os }}.sbom.json + run: cd cli && cargo sbom > c2patool.${{ matrix.os }}.sbom.json - name: Upload SBOM to Github if: ${{ needs.release-plz.outputs.c2patool-release-tag }} uses: svenstaro/upload-release-action@v1-release with: repo_token: ${{ secrets.GITHUB_TOKEN }} - file: c2patool.${{ matrix.os }}.sbom.json + file: cli/c2patool.${{ matrix.os }}.sbom.json asset_name: c2patool-${{ needs.release-plz.outputs.c2patool-release-tag }}-sbom.json tag: ${{ needs.release-plz.outputs.c2patool-release-tag }} overwrite: true From 9b825f542f87c3c17f95831c5bfc855487102d61 Mon Sep 17 00:00:00 2001 From: Eric Scouten Date: Thu, 12 Dec 2024 08:19:19 -0800 Subject: [PATCH 23/29] chore: Use `cargo check` to preflight `cargo publish` (i.e. default features only) --- .github/workflows/ci.yml | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index eb94ab35c..77293a946 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -175,6 +175,30 @@ jobs: fail_ci_if_error: true verbose: true + tests: + name: Default features build + if: | + github.event_name != 'pull_request' || + github.event.pull_request.author_association == 'COLLABORATOR' || + github.event.pull_request.author_association == 'MEMBER' || + github.event.pull_request.user.login == 'dependabot[bot]' || + contains(github.event.pull_request.labels.*.name, 'safe to test') + + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Install Rust toolchain + uses: dtolnay/rust-toolchain@stable + + - name: Cache Rust dependencies + uses: Swatinem/rust-cache@v2 + + - name: "`cargo check` with default features" + run: cargo check + tests-cross: name: Unit tests if: | From c86340820bb2705c2922e67bf8f56e7f2f72a6cd Mon Sep 17 00:00:00 2001 From: Eric Scouten Date: Thu, 12 Dec 2024 08:20:45 -0800 Subject: [PATCH 24/29] fix: No-op change to trigger new c2patool release --- cli/src/info.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cli/src/info.rs b/cli/src/info.rs index 94303e2bc..9a9160d4d 100644 --- a/cli/src/info.rs +++ b/cli/src/info.rs @@ -15,7 +15,7 @@ use std::{io::Cursor, path::Path}; use anyhow::Result; use c2pa::{IngredientOptions, Reader}; -/// display additional C2PA information about the asset (not json formatted) +/// Display additional C2PA information about the asset (not JSON formatted). pub fn info(path: &Path) -> Result<()> { struct Options {} impl IngredientOptions for Options { From 2ba4706a479ebb3f6a4bbb5467e517d534db8744 Mon Sep 17 00:00:00 2001 From: Eric Scouten Date: Thu, 12 Dec 2024 08:27:16 -0800 Subject: [PATCH 25/29] chore(c2patool): release v0.10.1 (#772) --- Cargo.lock | 6 +++--- cli/CHANGELOG.md | 7 +++++++ cli/Cargo.toml | 2 +- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 44f6b3a65..4547830bf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -794,7 +794,7 @@ version = "0.2.0" [[package]] name = "c2patool" -version = "0.10.0" +version = "0.10.1" dependencies = [ "anyhow", "assert_cmd", @@ -4987,9 +4987,9 @@ checksum = "3f423a2c17029964870cfaabb1f13dfab7d092a62a29a89264f4d36990ca414a" [[package]] name = "zune-jpeg" -version = "0.4.13" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16099418600b4d8f028622f73ff6e3deaabdff330fb9a2a131dea781ee8b0768" +checksum = "99a5bab8d7dedf81405c4bb1f2b83ea057643d9cb28778cea9eecddeedd2e028" dependencies = [ "zune-core", ] diff --git a/cli/CHANGELOG.md b/cli/CHANGELOG.md index b4c492182..04e491ee6 100644 --- a/cli/CHANGELOG.md +++ b/cli/CHANGELOG.md @@ -6,6 +6,13 @@ This project adheres to [Semantic Versioning](https://semver.org), except that Since version 0.10.0, the format of this changelog is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). +## [0.10.1](https://github.com/contentauth/c2pa-rs/compare/c2patool-v0.10.0...c2patool-v0.10.1) +_12 December 2024_ + +### Fixed + +* No-op change to trigger new c2patool release + ## [0.10.0](https://github.com/contentauth/c2pa-rs/compare/c2patool-v0.9.12...c2patool-v0.10.0) _12 December 2024_ diff --git a/cli/Cargo.toml b/cli/Cargo.toml index 094d7ad3b..eedaabd28 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -2,7 +2,7 @@ name = "c2patool" default-run = "c2patool" -version = "0.10.0" +version = "0.10.1" description = "Tool for displaying and creating C2PA manifests." authors = [ From a628a7d16e2fa2d39b05b8e2858d9b28740be0a6 Mon Sep 17 00:00:00 2001 From: Eric Scouten Date: Thu, 12 Dec 2024 10:23:04 -0800 Subject: [PATCH 26/29] fix: Update makefile for c2patool's new location in c2pa-rs workspace --- cli/Makefile | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/cli/Makefile b/cli/Makefile index 478cb959b..b73138f22 100644 --- a/cli/Makefile +++ b/cli/Makefile @@ -31,13 +31,13 @@ fmt: # Creates a folder wtih c2patool bin, samples and readme c2patool-package: - rm -rf target/c2patool* - mkdir -p target/c2patool - mkdir -p target/c2patool/sample - cp target/release/c2patool target/c2patool/c2patool - cp README.md target/c2patool/README.md - cp sample/* target/c2patool/sample - cp CHANGELOG.md target/c2patool/CHANGELOG.md + rm -rf ../target/c2patool* + mkdir -p ../target/c2patool + mkdir -p ../target/c2patool/sample + cp ../target/release/c2patool ../target/c2patool/c2patool + cp README.md ../target/c2patool/README.md + cp sample/* ../target/c2patool/sample + cp CHANGELOG.md ../target/c2patool/CHANGELOG.md # These are for building the c2patool release bin on various platforms build-release-win: @@ -52,7 +52,7 @@ build-release-mac-x86: MACOSX_DEPLOYMENT_TARGET=10.15 cargo build --target=x86_64-apple-darwin --release build-release-mac-universal: build-release-mac-arm build-release-mac-x86 - lipo -create -output target/release/c2patool target/aarch64-apple-darwin/release/c2patool target/x86_64-apple-darwin/release/c2patool + lipo -create -output ../target/release/c2patool ../target/aarch64-apple-darwin/release/c2patool ../target/x86_64-apple-darwin/release/c2patool build-release-linux: cargo build --release @@ -60,13 +60,13 @@ build-release-linux: # Builds and packages a zip for c2patool for each platform ifeq ($(PLATFORM), mac) release: build-release-mac-universal c2patool-package - cd target && zip -r c2patool_mac_universal.zip c2patool && cd .. + cd ../target && zip -r c2patool_mac_universal.zip c2patool && cd .. endif ifeq ($(PLATFORM), win) release: build-release-win c2patool-package - cd target && 7z a -r c2patool_win_intel.zip c2patool && cd .. + cd ../target && 7z a -r c2patool_win_intel.zip c2patool && cd .. endif ifeq ($(PLATFORM), linux) release: build-release-linux c2patool-package - cd target && tar -czvf c2patool_linux_intel.tar.gz c2patool && cd .. + cd ../target && tar -czvf c2patool_linux_intel.tar.gz c2patool && cd .. endif From fc7d0f9dd05ee69a963fa3a401cb74cebc298990 Mon Sep 17 00:00:00 2001 From: Eric Scouten Date: Thu, 12 Dec 2024 10:24:40 -0800 Subject: [PATCH 27/29] fix: No-op change to trigger new c2patool build --- cli/src/main.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/cli/src/main.rs b/cli/src/main.rs index 910635f90..96db545d7 100644 --- a/cli/src/main.rs +++ b/cli/src/main.rs @@ -14,9 +14,10 @@ /// Tool to display and create C2PA manifests /// -/// A file path to an asset must be provided -/// If only the path is given, this will generate a summary report of any claims in that file -/// If a manifest definition json file is specified, the claim will be added to any existing claims +/// A file path to an asset must be provided. If only the path +/// is given, this will generate a summary report of any claims +/// in that file. If a manifest definition JSON file is specified, +/// the claim will be added to any existing claims. use std::{ fs::{create_dir_all, remove_dir_all, File}, io::Write, From 0f5271c37f787d30ab4f1fb23dab4af534f6b983 Mon Sep 17 00:00:00 2001 From: Eric Scouten Date: Thu, 12 Dec 2024 10:26:49 -0800 Subject: [PATCH 28/29] chore(c2patool): release v0.10.2 (#773) --- Cargo.lock | 2 +- cli/CHANGELOG.md | 8 ++++++++ cli/Cargo.toml | 2 +- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4547830bf..f32635748 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -794,7 +794,7 @@ version = "0.2.0" [[package]] name = "c2patool" -version = "0.10.1" +version = "0.10.2" dependencies = [ "anyhow", "assert_cmd", diff --git a/cli/CHANGELOG.md b/cli/CHANGELOG.md index 04e491ee6..8ff9340ea 100644 --- a/cli/CHANGELOG.md +++ b/cli/CHANGELOG.md @@ -6,6 +6,14 @@ This project adheres to [Semantic Versioning](https://semver.org), except that Since version 0.10.0, the format of this changelog is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). +## [0.10.2](https://github.com/contentauth/c2pa-rs/compare/c2patool-v0.10.1...c2patool-v0.10.2) +_12 December 2024_ + +### Fixed + +* No-op change to trigger new c2patool build +* Update makefile for c2patool's new location in c2pa-rs workspace + ## [0.10.1](https://github.com/contentauth/c2pa-rs/compare/c2patool-v0.10.0...c2patool-v0.10.1) _12 December 2024_ diff --git a/cli/Cargo.toml b/cli/Cargo.toml index eedaabd28..d4b1c1066 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -2,7 +2,7 @@ name = "c2patool" default-run = "c2patool" -version = "0.10.1" +version = "0.10.2" description = "Tool for displaying and creating C2PA manifests." authors = [ From 11e2c0daa1ece49f278ac6284f03e36906e731ad Mon Sep 17 00:00:00 2001 From: Eric Scouten Date: Thu, 12 Dec 2024 10:46:38 -0800 Subject: [PATCH 29/29] chore: Fix broken CI workflow file --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 77293a946..a9e2ca14f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -175,7 +175,7 @@ jobs: fail_ci_if_error: true verbose: true - tests: + cargo-check: name: Default features build if: | github.event_name != 'pull_request' ||