Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

proof-of-concept: go library #27

Draft
wants to merge 38 commits into
base: main
Choose a base branch
from
Draft

Conversation

iameli
Copy link

@iameli iameli commented Aug 8, 2024

This is a working proof-of-concept of using NordSecurity/uniffi-bindgen-go to generate Go bindings the same way the Python ones are generated. Running make will generate a demo file that will display embedded C2PA manifests:

./dist/go-demo ~/testvids/screenshot-signed.jpg
{
  "active_manifest": "urn:uuid:019cfdc5-8d91-4b2a-bb0d-f94afb9badef",
  "manifests": {
    "urn:uuid:019cfdc5-8d91-4b2a-bb0d-f94afb9badef": {
      "claim_generator": "Aquareum c2patool/0.9.6 c2pa-rs/0.33.1",
[ ... ]

Some notes:

  1. I had to bump to uniffi = "0.25.0" to match the expected version for uniffi-bindgen-go. Doing so required this change, which I do not understand in the slightest, but it got it compiling:
diff --git a/src/streams.rs b/src/streams.rs
index 960c9b4..62001e0 100644
--- a/src/streams.rs
+++ b/src/streams.rs
@@ -51,6 +51,10 @@ impl Stream for Box<dyn Stream> {
     }
 }

+unsafe impl uniffi::LiftRef<crate::UniFfiTag> for Box<dyn Stream> {
+    type LiftType = Box<dyn Stream>;
+}
+
  1. I'm not really sure of the best way to get this into the hands of Go developers. Unlike Python, we can't just distribute prebuilt libraries as wheels, so I think inevitably there's going to be a cargo build step somewhere in any projects that make use of this. Not a problem for my use case exactly, but worth contemplating. Maybe it could be as simple as a single cargo install command that you have to run once to get the dependency in place?
  2. I'm making use of the same Stream primitives as the Python library, using a Go implementation of the interface at pkg/c2pa/c2pa.go. I don't really know if this is wise or unwise, but if it's actually useful maybe those primitives could be moved to an upstream library so they wouldn't be duplicated in the Python and Go examples.
  3. I changed crate-type = ["cdylib"] to crate-type = ["staticlib"] which seems like a better fit for Go's single-binary output.

"identifier": "thumbnail",
"format": "image/jpeg"
],
"signature_info": {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

signature_info is a read only structure from a signed manifest, you can't set these values when defining an ingredient. The SDK may not complain about it, but it will ignore it. This data comes from the certs and Timestamp authority as part of signing.

Copy link

@iameli-streams iameli-streams Aug 8, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To be clear, this doesn't have anything to do with my changes, I was just putting the output of the first embedded manifest file I had on hand. Could be anything.

That said, anything wrong with how I created it? I used this c2patool command:

c2patool --manifest manifest.json screenshot.jpg --output screenshot-signed.jpg

And this manifest.json:

{
  "alg": "ES256",
  "private_key": "/home/iameli/testvids/cert.key",
  "sign_cert": "/home/iameli/testvids/cert.crt",
  "ta_url": "http://timestamp.digicert.com",
  "claim_generator": "Aquareum",
  "title": "Video File",
  "assertions": [
    {
      "label": "c2pa.actions",
      "data": { "actions": [{ "action": "c2pa.published" }] }
    }
  ]
}

With a self-signed cert I created using this command (followed by pressing Enter a bunch of times):

openssl req \
  -new -x509 -nodes \
  -newkey ec:<(openssl ecparam -name secp384r1) \
  -extensions usr_cert \
  -addext "keyUsage = digitalSignature" \
  -addext "extendedKeyUsage = emailProtection" \
  -keyout cert.key -out cert.crt -days 3650

Resulting in the following JPEG: [EDIT: whoops, wrong link, next post has the right one]

Everything chill?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@iameli iameli closed this Aug 9, 2024
@iameli iameli reopened this Aug 9, 2024
@duggaraju
Copy link

Shouldn't this be part of standalone c2pa-bindings-v2 repo instead of c2pa-python. I know the old repo c2pa-bindings-v1 is archived now but may be create a new one based on the v2 API? I would like to add C# bindings as well but putting it all in the python repo seems incorrect.

@iameli
Copy link
Author

iameli commented Jan 28, 2025

Yep I 100% agree. There's been some discussion on the Discord on forking out the uniffi parts of this into its own repo to allow both c2pa-go and c2pa-python to be downstream of it - not sure if anything has happened there.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants