jclyo1 commited on
Commit
707c523
1 Parent(s): 19e2b6d
Files changed (4) hide show
  1. Dockerfile +3 -0
  2. main.py +7 -0
  3. scripts/upload.sh +26 -0
  4. scripts/verify.sh +165 -0
Dockerfile CHANGED
@@ -36,6 +36,9 @@ RUN unzip truepic-lens-cli-51f4cfbc6472a2205e53d726713619ca8df5340b-ubuntu-20.04
36
  RUN tar -xf truepic-lens-cli-51f4cfbc6472a2205e53d726713619ca8df5340b-ubuntu-20.04.tar.gz
37
 
38
  RUN chmod +x truepic
 
 
 
39
 
40
  RUN --mount=type=secret,id=api_key,mode=0444,required=true \
41
  ./truepic enroll file-system --api-key $(cat /run/secrets/api_key)
 
36
  RUN tar -xf truepic-lens-cli-51f4cfbc6472a2205e53d726713619ca8df5340b-ubuntu-20.04.tar.gz
37
 
38
  RUN chmod +x truepic
39
+ RUN chmod +x scripts/sign.sh
40
+ RUN chmod +x scripts/verify.sh
41
+ RUN chmod +x scripts/upload.sh
42
 
43
  RUN --mount=type=secret,id=api_key,mode=0444,required=true \
44
  ./truepic enroll file-system --api-key $(cat /run/secrets/api_key)
main.py CHANGED
@@ -91,6 +91,13 @@ def verify_image(fileUpload: UploadFile):
91
  # ]
92
  # )
93
 
 
 
 
 
 
 
 
94
  subprocess.check_output(
95
  [
96
  "./scripts/sign.sh",
 
91
  # ]
92
  # )
93
 
94
+ subprocess.check_output(
95
+ [
96
+ "export",
97
+ "STEG_AI_API_KEY=" + os.environ.get("steg_api_key"),
98
+ ]
99
+ )
100
+
101
  subprocess.check_output(
102
  [
103
  "./scripts/sign.sh",
scripts/upload.sh ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env bash
2
+
3
+ set -e
4
+
5
+ FILE=$(readlink -f "$1")
6
+ FORMAT=$2
7
+
8
+ json_data=$(
9
+ curl -s https://api.steg.ai/upload \
10
+ -H "x-api-key: ${STEG_AI_API_KEY}" \
11
+ --data-raw '{ "name": "'$(basename "${FILE}")'", "content_type": "'$FORMAT'" }')
12
+
13
+ readarray -t fields < <(echo "${json_data}" | jq -r '.data.post_to.fields | keys[]')
14
+ media_id=$(echo "${json_data}" | jq -r '.data.media_id')
15
+ presigned_url=$(echo "${json_data}" | jq -r '.data.post_to.url')
16
+
17
+ # Iterate over the keys array and build the curl parameters
18
+ form_string=""
19
+ for field in "${fields[@]}"; do
20
+ value=$(echo "${json_data}" | jq -r --arg key "${field}" '.data.post_to.fields[$key]')
21
+ form_string+="--form ${field}=${value} "
22
+ done
23
+
24
+ curl -s --location --request POST ${presigned_url} ${form_string} --form "file=@${FILE}"
25
+
26
+ echo ${media_id}
scripts/verify.sh ADDED
@@ -0,0 +1,165 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env bash
2
+
3
+ set -e
4
+
5
+ MEDIA_FILE=$(readlink -f "$1")
6
+
7
+ TRUEPIC_CLI=/home/user/app/truepic
8
+ STEG_SCRIPTS=/home/user/app/scripts/
9
+
10
+ echo -n "Checking for C2PA data in the media..."
11
+ set +e
12
+ verification_json=$(${TRUEPIC_CLI} verify $MEDIA_FILE 2>&1)
13
+ set -e
14
+
15
+ if jq -e . <<< "$verification_json" >/dev/null 2>&1; then
16
+ echo " embedded C2PA manifest found."
17
+ echo
18
+ echo ${verification_json} | jq
19
+ exit 0
20
+ fi
21
+ echo " no embedded C2PA manifest found."
22
+
23
+ echo
24
+ echo -n "Uploading media to steg.ai..."
25
+ media_id=$(${STEG_SCRIPTS}/upload.sh ${MEDIA_FILE} "image/jpeg")
26
+ echo " --> media_id=${media_id}"
27
+
28
+ echo
29
+ echo -n "Detecting a watermark..."
30
+ decode_response=$(
31
+ curl -s https://api.steg.ai/decode_image_async \
32
+ -H "x-api-key: ${STEG_AI_API_KEY}" \
33
+ --data-raw '{ "media_id": "'${media_id}'" }'
34
+ )
35
+ request_id=$(echo "$decode_response" | jq -r '.data.request_id')
36
+
37
+ if [ -z "$request_id" ] || [ "$request_id" = "null" ]; then
38
+ echo
39
+ echo "No request_id"
40
+ exit 1;
41
+ fi
42
+
43
+ status_response=""
44
+ decode_status=""
45
+ while [ "$decode_status" != "Completed." ]; do
46
+ sleep 1
47
+ echo -n ".."
48
+ status_response=$(
49
+ curl -s https://api.steg.ai/media_status?request_id=${request_id} \
50
+ -H "x-api-key: ${STEG_AI_API_KEY}"
51
+ )
52
+ decode_status=$(echo "${status_response}" | jq -r '.data.status')
53
+ done
54
+
55
+ manifest_id=$(echo "${status_response}" | jq -r '.data.media_data.custom' | jq -r '.manifest_id')
56
+ watermark_signature=$(echo "${status_response}" | jq -r '.data.media_data.custom' | jq -r '.watermark_signature')
57
+
58
+ if [ -z "$manifest_id" ] || [ "$manifest_id" = "null" ]; then
59
+ echo
60
+ echo "No manifest_id"
61
+ else
62
+ echo " --> media_id=${manifest_id}"
63
+ fi
64
+
65
+ echo
66
+ echo -n "Deleting uploaded media (${media_id}) from steg.ai... "
67
+ delete_result=$(
68
+ curl -s https://api.steg.ai/asset \
69
+ -X DELETE \
70
+ -H "x-api-key: ${STEG_AI_API_KEY}" \
71
+ --data-raw '{
72
+ "media_id" : "'${media_id}'"
73
+ }'
74
+ )
75
+
76
+ if [ -z "$manifest_id" ] || [ "$manifest_id" = "null" ]; then
77
+ exit 1
78
+ fi
79
+
80
+ echo ${delete_result} | jq -r '.message'
81
+ echo
82
+ echo -n "Downloading manifest..."
83
+ manifest_info=$(curl -s https://api.steg.ai/asset?media_id=${manifest_id} -H "x-api-key: ${STEG_AI_API_KEY}")
84
+ manifest_url=$(echo ${manifest_info} | jq -r '.data[0].path')
85
+ downloaded_manifest=$(mktemp).bin
86
+ curl -s -o ${downloaded_manifest} ${manifest_url}
87
+ echo " --> ${downloaded_manifest}"
88
+
89
+ echo
90
+ echo -n "Inserting manifest into media file..."
91
+ ${TRUEPIC_CLI} manifest insert ${downloaded_manifest} $MEDIA_FILE --output re_inserted_image.jpg > /dev/null 2>&1
92
+ echo " --> re_inserted_image.jpg"
93
+
94
+ echo
95
+ echo "Checking the manifest."
96
+ verification_json=$(${TRUEPIC_CLI} verify re_inserted_image.jpg)
97
+
98
+ hash_status=$(
99
+ echo "${verification_json}" | \
100
+ jq -r '.manifest_store[] | select(.is_active == true) | .assertions."c2pa.hash.data"[0].status'
101
+ )
102
+ thumbnail_hash=$(
103
+ echo "${verification_json}" | \
104
+ jq -r '.manifest_store[0].assertions."c2pa.thumbnail.claim.jpeg"[0].thumbnail_id'
105
+ )
106
+ timestamp=$(
107
+ echo "${verification_json}" | \
108
+ jq -r '.manifest_store[0].trusted_timestamp.timestamp'
109
+ )
110
+ public_key=$(
111
+ echo "${verification_json}" | \
112
+ jq -r '.manifest_store[] | select(.is_active == true) | .certificate.cert_der' | \
113
+ base64 -d | \
114
+ openssl x509 -pubkey -noout
115
+ )
116
+
117
+ echo -n "Checking watermark signature... ${thumbnail_hash}|${timestamp} ... ${watermark_signature} ..."
118
+ signature_verification=$(
119
+ openssl dgst -sha256 \
120
+ -verify <(echo "${public_key}") \
121
+ -signature <(echo "${watermark_signature}" | base64 -d) \
122
+ <(echo "${thumbnail_hash}|${timestamp}")
123
+ )
124
+
125
+ echo " ${signature_verification}"
126
+
127
+ echo -n "Checking image hash..."
128
+ if [ "$hash_status" = "VALID" ]; then
129
+ echo " hashes match."
130
+ echo "${verification_json}" | jq
131
+ rm -f ${downloaded_manifest}
132
+ exit 0
133
+ fi
134
+ echo " hashes DON'T match!"
135
+ rm -f re_inserted_image.jpg
136
+
137
+ echo
138
+ echo -n "Re-signing the watermarked media..."
139
+ ${TRUEPIC_CLI} sign ${MEDIA_FILE} \
140
+ --ingredient-manifest-store ${downloaded_manifest} \
141
+ --output re_signed_image.jpg \
142
+ --assertions-inline '{
143
+ "assertions": [
144
+ {
145
+ "label": "c2pa.actions",
146
+ "data": {
147
+ "actions": [
148
+ {
149
+ "action": "c2pa.unknown",
150
+ "when": "@now",
151
+ "parameters": {
152
+ "description": "Some unknown edits have been made between watermarking and now."
153
+ }
154
+ }
155
+ ]
156
+ }
157
+ }
158
+ ]
159
+ }' > /dev/null 2>&1
160
+ echo " --> re_signed_image.jpg"
161
+ rm -f ${downloaded_manifest}
162
+
163
+ echo
164
+ echo "Checking the manifest..."
165
+ ${TRUEPIC_CLI} verify re_signed_image.jpg | jq