contentauth / c2pa-rs Goto Github PK
View Code? Open in Web Editor NEWRust SDK for the core C2PA (Coalition for Content Provenance and Authenticity) specification
License: Other
Rust SDK for the core C2PA (Coalition for Content Provenance and Authenticity) specification
License: Other
There is lot of duplication across the various functions like
start_save() vs start_save_stream()
finish_save() vs finish_save_stream() finsh_save_to_memory()
and the corresponding jumbf versions .
If they can be combined or refactored to reuse the same code then that would avoid duplication and make it easy to test or even support signing bmff files from a memory buffer etc.
Check that Jira to Github export works.
Attached file is failing with "explanation": "certificate params incorrect"
, but I'm not clear why that is
As far as I can see, other than being self-signed it's structurally identical to the key from truepic-20230212-library.jpg
from the public repository
Android OS automatically redacts (replaces with 0) Geotags from Exif Data, unless the App has requested the ACCESS_MEDIA_LOCATION permission. This behavior is documented here.
This resulted in the Hashes not matching on Android, while the same image validated successfully on a Mac. It took a lot of debugging to find, because the last thing we expected was Android silently modifying the files content upon reading.
I would like to suggest adding this piece of information to an FAQ/Pitfalls section to help out others who might want to use this SDK on Android.
Originally submitted as an issue to c2patool: contentauth/c2patool#152 but this looks like a bug in c2pa-rs.
c2patool cannot be used with self-signed certs because c2pa-rs rejects self-signed certs.
As noted by Leszko in contentauth/c2patool#114, the c2pa-rs source code is written to explicitly forbid self-signed certs. (
c2pa-rs/sdk/src/cose_validator.rs
Line 350 in d9b077c
This contradicts the C2PA specification, which repeatedly mentions the use of self-signed certificates:
https://c2pa.org/specifications/specifications/1.2/specs/C2PA_Specification.html#_x_509_certificates
E.g.,
If you comment out the check/rejection of self-signed certs in the c2pa-rs code, then it correctly accepts self-signed certs. However, nobody else using c2patool will be able to validate it unless they apply the same patch.
Either c2pa-rs needs to be corrected to permit self-signed certs, or the C2PA specification needs to be updated to forbid self-signed certs.
Check that Jira to Github export works.
With the latest RemoteRefEmbed
trait, there is only the ability to add a reference. It would be useful to also have the ability to remove the remote reference with the same trait.
Cross-posted from the Discord group. I'm not quite sure where to put these, as I think they're issues with the test files as well as issues with the API.
There are two public files from https://github.com/c2pa-org/public-testfiles/tree/main/image that c2patool says are valid, but I'm not so sure:
The active manifest ends in 8a8f462cb30d: the "c2pa.actions" assertion, fourth action is "c2pa.placed"but has no parameters, so no url:
{
"action": "c2pa.placed",
"instanceId": "xmp:iid:a649c709-5c9f-47a7-aa1d-850b26789d62"
},
But 18.10 says
c2pa.placed" action "shall" have parameters
and 15.7.3 point a.iii.A.I.1 says this is an assertion.action.ingredientMismatch
The active manifest ends in 065a84099cc7: the "c2pa.actions" assertion fourth action is "c2pa.placed" and refers to "c2pa.ingredient", which has a relationship of "parentOf"
{
"action": "c2pa.placed",
"instanceId": "xmp.iid:813ee422-9736-4cdc-9be6-4e35ed8e41cb",
"parameters": {
"ingredient": {
"hash": "tTBD4/E0R0AjLUdJFpsVz3lE/KJUq22Vz0UGqzhEpVs=",
"url": "self#jumbf=c2pa.assertions/c2pa.ingredient"
}
}
},
...
"c2pa.ingredient": {
"dc:format": "image/jpeg",
"dc:title": "A.jpg",
"documentID": "xmp.did:813ee422-9736-4cdc-9be6-4e35ed8e41cb",
"instanceID": "xmp.iid:813ee422-9736-4cdc-9be6-4e35ed8e41cb",
"relationship": "parentOf",
"thumbnail": {
"hash": "z55bRqFSv/HdQlFpU96AUPwDnHMWi/XVVanedKE7kxc=",
"url": "self#jumbf=c2pa.assertions/c2pa.thumbnail.ingredient.jpeg"
}
},
But again in 15.7.3 it says:
For c2pa.placed or c2pa.removed: Check that the value of the relationship field is componentOf. If it is not, the claim must be rejected with a failure code of assertion.action.ingredientMismatch.
We do the x.509 parsing in c2pa-rs and right now we will capture the data for the name of an organization, however not personal info if the certificate was set up in a non-organizational manner. This will add support for those other fields so we can display them in downstream projects/SDKs.
In #317, we added an indirect dependency on json
crate which has been unmaintained for more than three years.
I've filed an issue at vstroebel/jfifdump#4 asking the maintainer of jfifdump
crate to consider alternatives.
Tracking issue to ensure we don't keep this dependency in the long term.
Feature request from Discord:
C2PA 1.4 has added support for ZIP-based formats - this is a request to add compatibility with this to c2pa-rs and downstream tools.
Description:
Steps to reproduce:
Observed result:
Expected result:
Workaround:
Reproducible rate: 100%; intermittent; random:
Platform & Version: Mac or Win:
Browser (if applicable):
Plugin Build#: if applicable, and/or Ps Build #:
Regression? (Yes/No). If "Yes", provide the last passed build info:
Attach screenshot of issue and/or problematic image with Content Credentials
Hi, while going through the example in https://docs.rs/c2pa/latest/c2pa/#example-reading-a-manifeststore
Am getting not implemented error (E0599)
error[E0599]: no function or associated item named `from_file` found for struct `ManifestStore` in the current scope
--> src/main.rs:4:41
|
4 | let manifest_store = ManifestStore::from_file("tests/fixtures/C.jpg")?;
| ^^^^^^^^^ function or associated item not found in `ManifestStore`
My cargo.toml file
[dependencies]
c2pa = "0.11.0"
The C2PA 1.0 spec outlines support for three digital signature algorithms, with one being Ed25519. We are not supporting this at the moment in Web Assembly since Web Crypto doesn't have support for this. However, the RustCrypto org has published a crate that provides Ed25519 support in pure Rust, which we should be able to use for this.
I believe the Rust SDK supports SVG format. The c2patool README lists support, but not here. I suspect this is just an oversight.
When we fix this, while we're at it we should probably double-check all the formats listed in https://github.com/contentauth/c2pa-rs/blob/main/README.md#supported-file-formats.
Description
When I ran cargo run --example client
, I ran into the following errors:
$ cargo run --example client
Compiling c2pa v0.7.0 (/home/ec2-user/workspace/c2pa-rs/sdk)
Finished dev [unoptimized + debuginfo] target(s) in 6.86s
Running `target/debug/examples/client`
Error: No such file or directory (os error 2)
After some debugging, it occurs to me it is related to the following two lines:
c2pa-rs/sdk/examples/client/client.rs
Lines 112 to 113 in 6e1af57
signcert_path
should point to the certificate certs.ps256.pub
while pkey_path
should point to the private key certs.ps256.pem
. That is, things should look like
let signcert_path = "./sdk/tests/fixtures/certs/ps256.pub";
let pkey_path = "./sdk/tests/fixtures/certs/ps256.pem";
Hello!
I tried to verify test image (attached to issue) generated by your`s library on this verification site. But it failed in case of unavailable image content credentials (screenshot attached bellow).
But image verified by c2pa-tool (v 0.2.0, from this project) successfully.
Could you say what side is getting wrong: verification site or this project?
Makes the entire code base asynchronous, removes the duplicate functions (with _async suffix).
From yong2023 via Discord:
I think it will be helpful to add in README on how to add credential to an image, then how to show the credentials.
I know this by asking my friends and try myself and finally using the command in Makefile and change the input image in it with my own. Something like:
"cargo run --example client ~/Desktop/Hepburn3.jpg target/tmp/client.jpg"
Then use
make show
orcargo run --example show -- target/tmp/client.jpg
to show the credentialalso can go to verify page at: https://verify.contentauthenticity.org/inspect to show the credentials added
C2PA-rs returns validation code assertion.dataHash.mismatch for a box hash failure instead of assertion.boxesHash.mismatch.
The C2PATool v 0.6.2 returns
{
"code": "assertion.**dataHash**.mismatch",
"url": "self#jumbf=/c2pa/urn:uuid:c1ff5172-2367-4fa0-9f4c-f6e8710900f6/c2pa.assertions/c2pa.hash.boxes",
"explanation": "asset hash error: hash verification( Box hash name not found )"
}
instead of
{
"code": "assertion.**boxesHash**.mismatch",
"url": "self#jumbf=/c2pa/urn:uuid:c1ff5172-2367-4fa0-9f4c-f6e8710900f6/c2pa.assertions/c2pa.hash.boxes",
"explanation": "asset hash error: hash verification( Box hash name not found )"
}
In addition to this change, for boxes hashes success, C2PA is adding the assertion.boxesHash.match success code in the next version to match the other hard binding success codes.
I've been working through the SDK and understanding the layout as well as learning the C2PA specification, so please bear with me if I misunderstand any of the fundamentals or fumble with the terminology.
From what I have observed, the start_save
function in the store
module writes a manifest store, a reference URI to a manifest store, or both to an asset. Due to the use of the embedded_xmp
module, it's currently tied to embedding a remote manifest store URI to specific file formats like JPEG and PNG, which support XMP, limiting its reusability.
To address this, the embedding of remote manifest store URIs could be abstracted into a separate trait that defines methods for writing asset references. This approach is similar to defining IO traits in the asset_io
module. I think this would also start to move in the right direction of supporting remote references for streaming (i.e. start_save_stream
) assets too. For example, could have a ManifestUriRef
trait defined in asset_io
:
/// Interface for supporting a URI reference to an active manifest.
pub trait ManifestUriRef {
/// Add the URI for the active manifest for the file.
///
/// ## Arguments
/// - `asset_path`: Path to the asset to add the URI reference to
/// - `manifest_uri`: A valid URI to the active manifest
fn add_manifest_uri_to_file(&self, asset_path: &Path, manifest_uri: &str) -> Result<()>;
/// Removes the URI for the active manifest for the file.
///
/// ## Arguments
/// - `asset_path`: Path to the asset to add the URI reference to
fn remove_manifest_uri_from_file(&self, asset_path: &Path) -> Result<()>;
}
pub fn get_manifest_ref(ext: &str) -> Result<Box<dyn ManifestUriRef>> {
let ext = ext.to_ascii_lowercase();
match ext.as_ref() {
"jpg" | "jpeg" => Ok(Box::new(JpegIO {})),
"png" => Ok(Box::new(PngIO{})),
"tif" | "tiff" | "dng" => Ok(Box::new(TiffIO{})),
_ => Err(crate::error::Error::RemoteManifestNotSupported),
}
}
The embedded_xmp
functionality can then be implemented as a concrete implementation of the trait for image file formats like JPEG and PNG. This would make the start_save
function more flexible and modular, enabling it to work with various file formats. For example the JpegIO
struct could implement as follows:
impl ManifestUriRef for JpegIO {
fn add_manifest_uri_to_file(&self, asset_path: &Path, manifest_uri: &str) -> Result<()> {
#[cfg(feature="xmp_write")]
{
add_manifest_uri_to_file(asset_path, manifest_uri)
}
#[cfg(not(feature = "xmp_write"))]
{
Err(crate::error::Error::MissingFeature("xmp_write"))
}
}
fn remove_manifest_uri_from_file(&self, _asset_path: &Path) -> Result<()> {
todo!()
}
}
This would allow for the store::start_save
to write the remote reference cleaner:
crate::claim::RemoteManifest::EmbedWithRemote(_url) => {
get_manifest_ref(&ext)?.add_manifest_uri_to_file(dest_path, &_url)?;
dest_path.to_path_buf()
}
Overall, the point is abstracting this part of the code would improve code maintainability and extensibility by separating concerns and enabling reuse of functionality. The sample code provided was just to provide context, there may be a better way to implement said suggestions.
Description
Description
Hi, we have encountered bug where photos from one of our devices can´t be used by c2pa. We use c2pa rust sdk and we tested this photo with c2pa tool both reported same error and it is "not found". After closer look at other images this image has already some data written into app11 segment they are just "00 00" but other images has app11 completly empty we asume this might be the problematic area. When we strip all metadata from photo then we are able to use both our program and c2pa tool with no problem but stripping the metadata should not be needed and is not expected for proper functionality of c2pa sdk.
c2patool 20230102_152829.jpg -m test.json -o 20230102_152829.jpg -f
testing manifest is
{ "ta_url": "http://timestamp.digicert.com", "claim_generator": "TestApp", "assertions": [ { "label": "stds.schema-org.CreativeWork", "data": { "@context": "https://schema.org", "@type": "CreativeWork", "author": [ { "@type": "Person", "name": "Joe Bloggs" } ] } } ] }
We are certain that this problem should be handled inside rust sdk and not in our code as the library doesn´t state that this isnt valid picture. The code in our case crashes when we use manifest_store.embed(...) function and error state just not found with no helpful message or explanation
same error occurs in c2pa_tool
for more information please contact me i am able to share more if needed.
Running cargo deny
on this crate yields the following warning:
error[A003]: Crate `twoway` deprecated by the author
┌─ /.../c2pa-rs/Cargo.lock:223:1
│
223 │ twoway 0.2.2 registry+https://github.com/rust-lang/crates.io-index
│ ------------------------------------------------------------------ unmaintained advisory detected
│
= ID: RUSTSEC-2021-0146
= Advisory: https://rustsec.org/advisories/RUSTSEC-2021-0146
= The commit [`e99b3c7`](https://github.com/bluss/twoway/commit/e99b3c718df1117ad7f54c33f6540c8f46cc17dd) releasing version 0.2.2 explicitly deprecates `twoway` in favour of [`memchr`](https://crates.io/crates/memchr) crate.
= Announcement: https://github.com/bluss/twoway
= Solution: No safe upgrade is available!
= twoway v0.2.2
├── c2pa v0.20.0
│ └── make_test_images v0.20.0
└── make_test_images v0.20.0 (*)
Test that GJSS exports Github issues as Epics
This requires the following changes:
Re <https://opensource.contentauthenticity.org/docs/rust-sdk/]
The image below fails to read in c2patool with the following output
c2patool --info out.jpg
[2023-02-23T17:39:43Z DEBUG c2pa::ingredient] ingredient "out.jpg"
[2023-02-23T17:39:43Z DEBUG c2pa::ingredient] ingredient JumbfParseError(UnexpectedEof)
Information for out.jpg
No C2PA Manifests
This is created by another C2PA API which is still under development - so I'm certainly open to the fact that the C2PA is genuinely invalid.
However the app11 marker is accepted (by jpegtran etc) and the JUMBF box hierarchy is tested by both our code (it's also a verifier, so has been run on all the public C2PA samples) and also loads without error in https://github.com/thorfdbg/codestream-parser. So I'm fairly confident at this point.
SHA256 sum of this image is 4eef35e7becaf084c205fc962448327128f7ded053c987592b04f188f711fe1a, just in case it gets mangled by github - I posted the same to the CAI Discord server, and it was certainly mangled there.
Is version 0.29 on the main branch? The readme indicates its from Nov 2023, but I'm trying to use c2patool on mp3s but keep getting an error "XMP is not supported" even though I specified to use c2pa-rs main branch in the dependencies.
EDIT: More specifically, what I'm trying to do is to embed a remote manifest url on an mp3, without remote manifests it works.
I saved a copy of the CBOR generated in one of our tests (see https://github.com/contentauth/c2pa-rs/blob/main/sdk/src/assertions/actions.rs#L450).
It contains several (hex) ef bf bd
sequences which do not make sense as initial values in CBOR:
ef
= major type 7, minor value 15, which is unassignedbf
= major type 5 (map), indefinite length, which is legalbd
= major type 5 (map), minor value 29, which would be legal, but there are not 29 key/value pairs in the subsequent dataThis file also is rejected by the third-party cbor-diag
parser.
The existing doc doesn't have much other than some basic overview info and API doc.
The docs should explain (for example) how to:
From yong2023 via Discord:
To me, I first faced an
Caused by: failed to load source for dependency async-trait
issue, and the reason was my cargo version too low. So I need runrustup update stable
to update my rustc and cargo to latest version. (edited)Also I run
xcode-select --install
andsoftwareupdate –install -a
to upgrade my clang version on Macbookand finally add exports in
.bash_profile
All these can save a lot of time for newbies like me.
Description:
Steps to reproduce:
Observed result:
Expected result:
Workaround:
Reproducible rate: 100%; intermittent; random:
Platform & Version: Mac or Win:
Browser (if applicable):
Plugin Build#: if applicable, and/or Ps Build #:
Regression? (Yes/No). If "Yes", provide the last passed build info:
Attach screenshot of issue and/or problematic image with Content Credentials
It would be nice to get more details on the failures.
1st example "Box hash name not found" would be better if it was like "Box hash name, SOS, not found in the file."
2nd example: "Hashes do not match" would be better if it was "Hash for box RST1, yy8dviSIFeUgM7C96eAiygJ8T0hjQcjhLGl0Xy0o9Fo=, does not match expected hash, nDOggBltZJSdQGLPSgrdqmeS7y69QOazEcpWJfTwmWk="
Description
I am trying to run C2PA in an environment which uses openssl-sys=0.9.94.
However, the C2PA Cargo locks openssl-sys to 0.9.92, which means I can't use the current version of C2PA in my system.
There are a number of files in https://github.com/c2pa-org/public-testfiles/tree/main/image that refer to the manifest contentauth:urn:uuid:04cdf4ec-f713-4e47-a8d6-7af56501ce4b
(CA.jpg) as an ingredient.
For example, here's an excerpt from the C2PA object in
https://github.com/c2pa-org/public-testfiles/blob/main/image/jpeg/adobe-20220124-CA.jpg
"c2pa.ingredient": {
"c2pa_manifest": {
"alg": "sha256",
"hash": "3epjVN8X1spZW0Z6TYQO/6owR7xADaDDVzeeDBOGV4g=",
"url": "self#jumbf=/c2pa/contentauth:urn:uuid:04cdf4ec-f713-4e47-a8d6-7af56501ce4b"
},
In all cases that same hash is used, which is base64(3epjVN8X1spZW0Z6TYQO/6owR7xADaDDVzeeDBOGV4g=)
or hex(ddea6354df17d6ca595b467a4d840effaa3047bc400da0c357379e0c13865788)
.
My problem is I can't match that to the manifest.
I'm fully aware of the digest algorithm described in https://c2pa.org/specifications/specifications/1.2/specs/C2PA_Specification.html#_hashing_jumbf_boxes
When creating a URI reference to an assertion (i.e., as part of constructing a Claim), a W3C Verifiable Credential or other C2PA structure stored as a JUMBF box, the hash shall be performed over the contents of the structure’s JUMBF superbox, which includes both the JUMBF Description Box and all content boxes therein (but does not include the structure’s JUMBF superbox header).
That's what I'm doing, and it's matching perfectly the output from c2patool for all JUMBF box types - except manifests.
In desperation I have even tried digesting various byte ranges from the C2PA object directly at to try and find one that matches that digest - none do. There is no byte-range in the C2PA object that matches that SHA-256 digest (edit: see next comment), which surely means there must be some special processing for manifest boxes going on.
The digest I am expecting is base64(4h9T1UCSjePpgfwJddVkegL4vFKX5qRj5UYaNtTB0jA=)
or hex(e21f53d540928de3e981fc0975d5647a02f8bc5297e6a463e5461a36d4c1d230)
, which matches the 126477 bytes starting at byte 46 of the C2PA. Here is the C2PA object I am testing, extracted from adobe-20220124-CA.jpg: extracted-c2pa.zip
So I suppose I have two questions as a result:
Finally, below is the file I am trying to verify with (what I think is) the correct digest for that manifest, which is failing to verify in c2patool. It is just a repackaging of adobe-20220124-CA.jpg
Description:
Steps to reproduce:
Observed result:
Expected result:
Workaround:
Reproducible rate: 100%; intermittent; random:
Platform & Version: Mac or Win:
Browser (if applicable):
Plugin Build#: if applicable, and/or Ps Build #:
Regression? (Yes/No). If "Yes", provide the last passed build info:
Attach screenshot of issue and/or problematic image with Content Credentials
Currently, the SDK relies on assets to support XMP to properly be an ingredient. Since not all assets support XMP, would be beneficial to abstract this behavior, to allow for:
This would allow an asset to provide a customized ID instead of one with
xmp:*
The ingredient.rs
mod would be able to utilize these new methods to build out the ingredient information and would appropriately support remote manifests.
Check that Jira to Github export works.
Description
When loading an ingredient the default is to add relationship: "componentOf". This has the effect of override an is_parent: true flag in an ingredient. For better backwards compatibility we should automatically set a "parentOf" relationship if an is_parent flag exists and is set to true. At that same time, we should deprecate is_parent, so developers are warned to move away from it and use relationship instead.
AsyncSigner can be used everywhere and avoid two different sets of APIs?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.