Module: C2PA

Defined in:
lib/c2pa.rb,
lib/c2pa/error.rb,
lib/c2pa/actions.rb,
lib/c2pa/version.rb,
lib/c2pa/manifest.rb,
lib/c2pa/digital_source_types.rb

Defined Under Namespace

Modules: Actions, DigitalSourceTypes Classes: Error, InvalidManifestError, Manifest, ReadError, SigningError

Constant Summary collapse

VALID_STATES =

Validation states that mean a signed asset is good.

"Trusted" is "Valid" plus a signing certificate that chains to a root in the active trust list. Accepting only "Valid" would reject exactly the production files that are most correct.

%w[Valid Trusted].freeze
VERSION =
"0.3.0"

Class Method Summary collapse

Class Method Details

.read(file:) ⇒ Hash

Read the C2PA manifest embedded in a signed file.

Examples:

manifest = C2PA.read(file: "photo_signed.jpg")
active = manifest["manifests"][manifest["active_manifest"]]
puts active["title"]

Parameters:

  • file (String)

    path to the signed file

Returns:

  • (Hash)

    parsed manifest JSON

Raises:



73
74
75
76
77
# File 'lib/c2pa.rb', line 73

def self.read(file:)
  JSON.parse(Native.read_file(file))
rescue RuntimeError => e
  raise ReadError, e.message
end

.sdk_versionString

Return the version of the underlying c2pa-rs SDK.

Returns:

  • (String)


82
83
84
# File 'lib/c2pa.rb', line 82

def self.sdk_version
  Native.sdk_version
end

.sign(file:, output:, certificate:, key:, algorithm: "es256", manifest:, verify: true) ⇒ String

Sign a file with a C2PA manifest.

Examples:

manifest = C2PA::Manifest.new(title: "Sunset over the bay")
manifest.add_action(C2PA::Actions::CREATED)

C2PA.sign(
  file:        "photo.jpg",
  output:      "photo_signed.jpg",
  certificate: "cert.pem",
  key:         "key.pem",
  manifest:    manifest
)

Parameters:

  • file (String)

    path to the input file

  • output (String)

    path for the signed output file (must not already exist)

  • certificate (String)

    path to a PEM-encoded X.509 certificate (chain)

  • key (String)

    path to a PEM-encoded private key

  • algorithm (String) (defaults to: "es256")

    signing algorithm (default: "es256")

  • manifest (C2PA::Manifest)

    the manifest to embed

  • verify (Boolean) (defaults to: true)

    read the signed file back and confirm it validates (default: true)

Returns:

  • (String)

    the output path

Raises:



41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/c2pa.rb', line 41

def self.sign(file:, output:, certificate:, key:, algorithm: "es256", manifest:, verify: true)
  manifest_json = manifest.to_json

  raise SigningError, "Source file not found: '#{file}'"             unless File.exist?(file)
  raise SigningError, "Certificate file not found: '#{certificate}'" unless File.exist?(certificate)
  raise SigningError, "Key file not found: '#{key}'"                 unless File.exist?(key)
  raise SigningError, "Output file already exists: '#{output}'"      if File.exist?(output)

  begin
    # to_json is the only thing genuinely required of a manifest, so an
    # object that provides just that still signs — as a creation.
    intent = manifest.respond_to?(:intent) ? manifest.intent&.to_s : nil
    Native.sign_file(file, output, certificate, key, algorithm, manifest_json, intent)
  rescue RuntimeError => e
    raise SigningError, e.message
  end

  verify_signed_output!(output) if verify

  output
end