ruby-c2pa 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/LICENSE +21 -0
- data/README.md +296 -0
- data/Rakefile +18 -0
- data/ext/c2pa_native/Cargo.toml +19 -0
- data/ext/c2pa_native/extconf.rb +4 -0
- data/ext/c2pa_native/src/lib.rs +104 -0
- data/ext/c2pa_native/target/release/build/oid-registry-c350c75504c969dc/out/oid_db.rs +540 -0
- data/ext/c2pa_native/target/release/build/pix-f303ab89d734032b/out/gamma_lut.rs +68 -0
- data/ext/c2pa_native/target/release/build/serde-2e9abb4d9d73cae4/out/private.rs +6 -0
- data/ext/c2pa_native/target/release/build/serde-f471616b462b0caf/out/private.rs +6 -0
- data/ext/c2pa_native/target/release/build/serde_core-2b94e9134dc44065/out/private.rs +5 -0
- data/ext/c2pa_native/target/release/build/serde_core-3dc945fa0ab21dd5/out/private.rs +5 -0
- data/ext/c2pa_native/target/release/build/thiserror-a1f4c63469c326b9/out/private.rs +5 -0
- data/ext/c2pa_native/target/release/build/typenum-4eb7d34b9fb695ef/out/tests.rs +20563 -0
- data/ext/c2pa_native/target/release/build/typenum-b8de96984639a942/out/tests.rs +20563 -0
- data/lib/c2pa/actions.rb +29 -0
- data/lib/c2pa/error.rb +6 -0
- data/lib/c2pa/manifest.rb +85 -0
- data/lib/c2pa/version.rb +3 -0
- data/lib/c2pa.rb +58 -0
- data/ruby-c2pa.gemspec +25 -0
- metadata +120 -0
data/lib/c2pa/actions.rb
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
module C2PA
|
|
2
|
+
module Actions
|
|
3
|
+
CREATED = "c2pa.created"
|
|
4
|
+
OPENED = "c2pa.opened"
|
|
5
|
+
EDITED = "c2pa.edited"
|
|
6
|
+
EDITED_METADATA = "c2pa.edited.metadata"
|
|
7
|
+
ADJUSTED_COLOR = "c2pa.adjustedColor"
|
|
8
|
+
CHANGED_SPEED = "c2pa.changedSpeed"
|
|
9
|
+
CONVERTED = "c2pa.converted"
|
|
10
|
+
CROPPED = "c2pa.cropped"
|
|
11
|
+
DELETED = "c2pa.deleted"
|
|
12
|
+
DRAWING = "c2pa.drawing"
|
|
13
|
+
DUBBED = "c2pa.dubbed"
|
|
14
|
+
ENHANCED = "c2pa.enhanced"
|
|
15
|
+
FILTERED = "c2pa.filtered"
|
|
16
|
+
ORIENTATION = "c2pa.orientation"
|
|
17
|
+
PLACED = "c2pa.placed"
|
|
18
|
+
PUBLISHED = "c2pa.published"
|
|
19
|
+
REDACTED = "c2pa.redacted"
|
|
20
|
+
REMOVED = "c2pa.removed"
|
|
21
|
+
REPACKAGED = "c2pa.repackaged"
|
|
22
|
+
RESIZED = "c2pa.resized"
|
|
23
|
+
TRANSLATED = "c2pa.translated"
|
|
24
|
+
TRANSCODED = "c2pa.transcoded"
|
|
25
|
+
TRIMMED = "c2pa.trimmed"
|
|
26
|
+
UNKNOWN = "c2pa.unknown"
|
|
27
|
+
WATERMARKED = "c2pa.watermarked"
|
|
28
|
+
end
|
|
29
|
+
end
|
data/lib/c2pa/error.rb
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
require "json"
|
|
2
|
+
|
|
3
|
+
module C2PA
|
|
4
|
+
class Manifest
|
|
5
|
+
# @param title [String] human-readable title for this asset
|
|
6
|
+
def initialize(title:)
|
|
7
|
+
@title = title
|
|
8
|
+
@actions = []
|
|
9
|
+
@assertions = []
|
|
10
|
+
@ingredients = []
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# Add a C2PA action to this manifest.
|
|
14
|
+
#
|
|
15
|
+
# @param action [String] one of the C2PA::Actions constants
|
|
16
|
+
# @param when_time [String, nil] ISO 8601 timestamp of when the action occurred
|
|
17
|
+
# @param software_agent [String, nil] name/version of the software that performed the action;
|
|
18
|
+
# defaults to "ruby-c2pa/<version>"
|
|
19
|
+
# @param digital_source_type [String, nil] URI from the C2PA digitalSourceType vocabulary
|
|
20
|
+
# @param changed [Array<String>, nil] list of regions or ingredients that changed
|
|
21
|
+
# @param parameters [Hash, nil] action-specific additional parameters
|
|
22
|
+
# @return [self]
|
|
23
|
+
def add_action(action,
|
|
24
|
+
when_time: nil,
|
|
25
|
+
software_agent: nil,
|
|
26
|
+
digital_source_type: nil,
|
|
27
|
+
changed: nil,
|
|
28
|
+
parameters: nil)
|
|
29
|
+
entry = { "action" => action }
|
|
30
|
+
entry["when"] = when_time if when_time
|
|
31
|
+
entry["softwareAgent"] = software_agent || "ruby-c2pa/#{VERSION}"
|
|
32
|
+
entry["digitalSourceType"] = digital_source_type if digital_source_type
|
|
33
|
+
entry["changed"] = changed if changed
|
|
34
|
+
entry["parameters"] = parameters if parameters
|
|
35
|
+
@actions << entry
|
|
36
|
+
self
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Add an arbitrary assertion to this manifest.
|
|
40
|
+
#
|
|
41
|
+
# @param label [String] the assertion label, e.g. "stds.schema-org.CreativeWork"
|
|
42
|
+
# @param data [Hash] the assertion data
|
|
43
|
+
# @return [self]
|
|
44
|
+
def add_assertion(label:, data:)
|
|
45
|
+
@assertions << { "label" => label, "data" => data }
|
|
46
|
+
self
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# Add an ingredient (source asset) to this manifest.
|
|
50
|
+
#
|
|
51
|
+
# @param title [String] human-readable title of the ingredient
|
|
52
|
+
# @param format [String] MIME type of the ingredient, e.g. "image/jpeg"
|
|
53
|
+
# @param instance_id [String] unique identifier for the ingredient instance
|
|
54
|
+
# @param relationship [String] relationship to this asset; defaults to "parentOf"
|
|
55
|
+
# @return [self]
|
|
56
|
+
def add_ingredient(title:, format:, instance_id:, relationship: "parentOf")
|
|
57
|
+
@ingredients << {
|
|
58
|
+
"title" => title,
|
|
59
|
+
"format" => format,
|
|
60
|
+
"instance_id" => instance_id,
|
|
61
|
+
"relationship" => relationship
|
|
62
|
+
}
|
|
63
|
+
self
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# Serialize to the JSON structure expected by c2pa-rs.
|
|
67
|
+
#
|
|
68
|
+
# @return [String]
|
|
69
|
+
# @raise [C2PA::InvalidManifestError] if no actions have been added
|
|
70
|
+
def to_json
|
|
71
|
+
raise InvalidManifestError, "at least one action is required" if @actions.empty?
|
|
72
|
+
|
|
73
|
+
manifest = {
|
|
74
|
+
"title" => @title,
|
|
75
|
+
"assertions" => [
|
|
76
|
+
{ "label" => "c2pa.actions.v2", "data" => { "actions" => @actions } },
|
|
77
|
+
*@assertions
|
|
78
|
+
]
|
|
79
|
+
}
|
|
80
|
+
manifest["ingredients"] = @ingredients unless @ingredients.empty?
|
|
81
|
+
|
|
82
|
+
JSON.generate(manifest)
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|
data/lib/c2pa/version.rb
ADDED
data/lib/c2pa.rb
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
require "json"
|
|
2
|
+
require_relative "c2pa/version"
|
|
3
|
+
require_relative "c2pa/error"
|
|
4
|
+
require_relative "c2pa/actions"
|
|
5
|
+
require_relative "c2pa/manifest"
|
|
6
|
+
require "c2pa/c2pa_native"
|
|
7
|
+
|
|
8
|
+
module C2PA
|
|
9
|
+
# Sign a file with a C2PA manifest.
|
|
10
|
+
#
|
|
11
|
+
# @param file [String] path to the input file
|
|
12
|
+
# @param output [String] path for the signed output file (must not already exist)
|
|
13
|
+
# @param certificate [String] path to a PEM-encoded X.509 certificate (chain)
|
|
14
|
+
# @param key [String] path to a PEM-encoded private key
|
|
15
|
+
# @param algorithm [String] signing algorithm (default: "es256")
|
|
16
|
+
# @param manifest [C2PA::Manifest] the manifest to embed
|
|
17
|
+
# @return [String] the output path
|
|
18
|
+
#
|
|
19
|
+
# @example
|
|
20
|
+
# manifest = C2PA::Manifest.new(title: "Sunset over the bay")
|
|
21
|
+
# manifest.add_action(C2PA::Actions::CREATED)
|
|
22
|
+
#
|
|
23
|
+
# C2PA.sign(
|
|
24
|
+
# file: "photo.jpg",
|
|
25
|
+
# output: "photo_signed.jpg",
|
|
26
|
+
# certificate: "cert.pem",
|
|
27
|
+
# key: "key.pem",
|
|
28
|
+
# manifest: manifest
|
|
29
|
+
# )
|
|
30
|
+
def self.sign(file:, output:, certificate:, key:, algorithm: "es256", manifest:)
|
|
31
|
+
Native.sign_file(file, output, certificate, key, algorithm, manifest.to_json)
|
|
32
|
+
rescue RuntimeError => e
|
|
33
|
+
raise SigningError, e.message
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# Read the C2PA manifest embedded in a signed file.
|
|
37
|
+
#
|
|
38
|
+
# @param file [String] path to the signed file
|
|
39
|
+
# @return [Hash] parsed manifest JSON
|
|
40
|
+
# @raise [C2PA::ReadError] if the file has no valid manifest
|
|
41
|
+
#
|
|
42
|
+
# @example
|
|
43
|
+
# manifest = C2PA.read(file: "photo_signed.jpg")
|
|
44
|
+
# active = manifest["manifests"][manifest["active_manifest"]]
|
|
45
|
+
# puts active["title"]
|
|
46
|
+
def self.read(file:)
|
|
47
|
+
JSON.parse(Native.read_file(file))
|
|
48
|
+
rescue RuntimeError => e
|
|
49
|
+
raise ReadError, e.message
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# Return the version of the underlying c2pa-rs SDK.
|
|
53
|
+
#
|
|
54
|
+
# @return [String]
|
|
55
|
+
def self.sdk_version
|
|
56
|
+
Native.sdk_version
|
|
57
|
+
end
|
|
58
|
+
end
|
data/ruby-c2pa.gemspec
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
require_relative "lib/c2pa/version"
|
|
2
|
+
|
|
3
|
+
Gem::Specification.new do |spec|
|
|
4
|
+
spec.name = "ruby-c2pa"
|
|
5
|
+
spec.version = C2PA::VERSION
|
|
6
|
+
spec.authors = [`git config user.name`.strip]
|
|
7
|
+
spec.email = [`git config user.email`.strip]
|
|
8
|
+
spec.summary = "Ruby bindings for the c2pa content authenticity library"
|
|
9
|
+
spec.description = "Embed and verify C2PA content provenance and authenticity credentials in images, video, and audio files. Ruby bindings for the official Rust c2pa-rs library."
|
|
10
|
+
spec.license = "MIT"
|
|
11
|
+
spec.homepage = "https://github.com/carlosrodriguez/ruby-c2pa"
|
|
12
|
+
spec.metadata["source_code_uri"] = spec.homepage
|
|
13
|
+
|
|
14
|
+
spec.files = Dir["lib/**/*.rb", "ext/**/*.{rs,toml,rb}", "Rakefile", "*.gemspec", "LICENSE", "README.md"]
|
|
15
|
+
spec.require_paths = ["lib"]
|
|
16
|
+
spec.extensions = ["ext/c2pa_native/extconf.rb"]
|
|
17
|
+
|
|
18
|
+
spec.required_ruby_version = ">= 3.0"
|
|
19
|
+
|
|
20
|
+
spec.add_dependency "rb_sys", "~> 0.9"
|
|
21
|
+
|
|
22
|
+
spec.add_development_dependency "rake-compiler", "~> 1.2"
|
|
23
|
+
spec.add_development_dependency "minitest", "~> 5.0"
|
|
24
|
+
spec.add_development_dependency "rake", "~> 13.0"
|
|
25
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: ruby-c2pa
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.2.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Carlos Rodriguez
|
|
8
|
+
bindir: bin
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
|
+
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: rb_sys
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - "~>"
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '0.9'
|
|
19
|
+
type: :runtime
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - "~>"
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: '0.9'
|
|
26
|
+
- !ruby/object:Gem::Dependency
|
|
27
|
+
name: rake-compiler
|
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
|
29
|
+
requirements:
|
|
30
|
+
- - "~>"
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: '1.2'
|
|
33
|
+
type: :development
|
|
34
|
+
prerelease: false
|
|
35
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
36
|
+
requirements:
|
|
37
|
+
- - "~>"
|
|
38
|
+
- !ruby/object:Gem::Version
|
|
39
|
+
version: '1.2'
|
|
40
|
+
- !ruby/object:Gem::Dependency
|
|
41
|
+
name: minitest
|
|
42
|
+
requirement: !ruby/object:Gem::Requirement
|
|
43
|
+
requirements:
|
|
44
|
+
- - "~>"
|
|
45
|
+
- !ruby/object:Gem::Version
|
|
46
|
+
version: '5.0'
|
|
47
|
+
type: :development
|
|
48
|
+
prerelease: false
|
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
50
|
+
requirements:
|
|
51
|
+
- - "~>"
|
|
52
|
+
- !ruby/object:Gem::Version
|
|
53
|
+
version: '5.0'
|
|
54
|
+
- !ruby/object:Gem::Dependency
|
|
55
|
+
name: rake
|
|
56
|
+
requirement: !ruby/object:Gem::Requirement
|
|
57
|
+
requirements:
|
|
58
|
+
- - "~>"
|
|
59
|
+
- !ruby/object:Gem::Version
|
|
60
|
+
version: '13.0'
|
|
61
|
+
type: :development
|
|
62
|
+
prerelease: false
|
|
63
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
64
|
+
requirements:
|
|
65
|
+
- - "~>"
|
|
66
|
+
- !ruby/object:Gem::Version
|
|
67
|
+
version: '13.0'
|
|
68
|
+
description: Embed and verify C2PA content provenance and authenticity credentials
|
|
69
|
+
in images, video, and audio files. Ruby bindings for the official Rust c2pa-rs library.
|
|
70
|
+
email:
|
|
71
|
+
- carlos@eddorre.com
|
|
72
|
+
executables: []
|
|
73
|
+
extensions:
|
|
74
|
+
- ext/c2pa_native/extconf.rb
|
|
75
|
+
extra_rdoc_files: []
|
|
76
|
+
files:
|
|
77
|
+
- LICENSE
|
|
78
|
+
- README.md
|
|
79
|
+
- Rakefile
|
|
80
|
+
- ext/c2pa_native/Cargo.toml
|
|
81
|
+
- ext/c2pa_native/extconf.rb
|
|
82
|
+
- ext/c2pa_native/src/lib.rs
|
|
83
|
+
- ext/c2pa_native/target/release/build/oid-registry-c350c75504c969dc/out/oid_db.rs
|
|
84
|
+
- ext/c2pa_native/target/release/build/pix-f303ab89d734032b/out/gamma_lut.rs
|
|
85
|
+
- ext/c2pa_native/target/release/build/serde-2e9abb4d9d73cae4/out/private.rs
|
|
86
|
+
- ext/c2pa_native/target/release/build/serde-f471616b462b0caf/out/private.rs
|
|
87
|
+
- ext/c2pa_native/target/release/build/serde_core-2b94e9134dc44065/out/private.rs
|
|
88
|
+
- ext/c2pa_native/target/release/build/serde_core-3dc945fa0ab21dd5/out/private.rs
|
|
89
|
+
- ext/c2pa_native/target/release/build/thiserror-a1f4c63469c326b9/out/private.rs
|
|
90
|
+
- ext/c2pa_native/target/release/build/typenum-4eb7d34b9fb695ef/out/tests.rs
|
|
91
|
+
- ext/c2pa_native/target/release/build/typenum-b8de96984639a942/out/tests.rs
|
|
92
|
+
- lib/c2pa.rb
|
|
93
|
+
- lib/c2pa/actions.rb
|
|
94
|
+
- lib/c2pa/error.rb
|
|
95
|
+
- lib/c2pa/manifest.rb
|
|
96
|
+
- lib/c2pa/version.rb
|
|
97
|
+
- ruby-c2pa.gemspec
|
|
98
|
+
homepage: https://github.com/carlosrodriguez/ruby-c2pa
|
|
99
|
+
licenses:
|
|
100
|
+
- MIT
|
|
101
|
+
metadata:
|
|
102
|
+
source_code_uri: https://github.com/carlosrodriguez/ruby-c2pa
|
|
103
|
+
rdoc_options: []
|
|
104
|
+
require_paths:
|
|
105
|
+
- lib
|
|
106
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
107
|
+
requirements:
|
|
108
|
+
- - ">="
|
|
109
|
+
- !ruby/object:Gem::Version
|
|
110
|
+
version: '3.0'
|
|
111
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
112
|
+
requirements:
|
|
113
|
+
- - ">="
|
|
114
|
+
- !ruby/object:Gem::Version
|
|
115
|
+
version: '0'
|
|
116
|
+
requirements: []
|
|
117
|
+
rubygems_version: 4.0.3
|
|
118
|
+
specification_version: 4
|
|
119
|
+
summary: Ruby bindings for the c2pa content authenticity library
|
|
120
|
+
test_files: []
|