|
#!/usr/bin/env bash |
|
|
|
set -e |
|
|
|
MEDIA_FILE=$(readlink -f "$1") |
|
|
|
TRUEPIC_CLI=/home/user/app/truepic |
|
STEG_SCRIPTS=/home/user/app/scripts/ |
|
|
|
echo -n "Checking for C2PA data in the media..." |
|
set +e |
|
verification_json=$(${TRUEPIC_CLI} verify $MEDIA_FILE 2>&1) |
|
set -e |
|
|
|
if jq -e . <<< "$verification_json" >/dev/null 2>&1; then |
|
echo " embedded C2PA manifest found." |
|
echo |
|
echo ${verification_json} | jq |
|
exit 0 |
|
fi |
|
echo " no embedded C2PA manifest found." |
|
|
|
echo |
|
echo -n "Uploading media to steg.ai..." |
|
media_id=$(${STEG_SCRIPTS}/upload.sh ${MEDIA_FILE} "image/jpeg") |
|
echo " --> media_id=${media_id}" |
|
|
|
echo |
|
echo -n "Detecting a watermark..." |
|
decode_response=$( |
|
curl -s https://api.steg.ai/decode_image_async \ |
|
-H "x-api-key: ${STEG_AI_API_KEY}" \ |
|
--data-raw '{ "media_id": "'${media_id}'" }' |
|
) |
|
request_id=$(echo "$decode_response" | jq -r '.data.request_id') |
|
|
|
if [ -z "$request_id" ] || [ "$request_id" = "null" ]; then |
|
echo |
|
echo "No request_id" |
|
exit 1; |
|
fi |
|
|
|
status_response="" |
|
decode_status="" |
|
while [ "$decode_status" != "Completed." ]; do |
|
sleep 1 |
|
echo -n ".." |
|
status_response=$( |
|
curl -s https://api.steg.ai/media_status?request_id=${request_id} \ |
|
-H "x-api-key: ${STEG_AI_API_KEY}" |
|
) |
|
decode_status=$(echo "${status_response}" | jq -r '.data.status') |
|
done |
|
|
|
manifest_id=$(echo "${status_response}" | jq -r '.data.media_data.custom' | jq -r '.manifest_id') |
|
watermark_signature=$(echo "${status_response}" | jq -r '.data.media_data.custom' | jq -r '.watermark_signature') |
|
|
|
if [ -z "$manifest_id" ] || [ "$manifest_id" = "null" ]; then |
|
echo |
|
echo "No manifest_id" |
|
else |
|
echo " --> media_id=${manifest_id}" |
|
fi |
|
|
|
echo |
|
echo -n "Deleting uploaded media (${media_id}) from steg.ai... " |
|
delete_result=$( |
|
curl -s https://api.steg.ai/asset \ |
|
-X DELETE \ |
|
-H "x-api-key: ${STEG_AI_API_KEY}" \ |
|
--data-raw '{ |
|
"media_id" : "'${media_id}'" |
|
}' |
|
) |
|
|
|
if [ -z "$manifest_id" ] || [ "$manifest_id" = "null" ]; then |
|
exit 1 |
|
fi |
|
|
|
echo ${delete_result} | jq -r '.message' |
|
echo |
|
echo -n "Downloading manifest..." |
|
manifest_info=$(curl -s https://api.steg.ai/asset?media_id=${manifest_id} -H "x-api-key: ${STEG_AI_API_KEY}") |
|
manifest_url=$(echo ${manifest_info} | jq -r '.data[0].path') |
|
downloaded_manifest=$(mktemp).bin |
|
curl -s -o ${downloaded_manifest} ${manifest_url} |
|
echo " --> ${downloaded_manifest}" |
|
|
|
echo |
|
echo -n "Inserting manifest into media file..." |
|
${TRUEPIC_CLI} manifest insert ${downloaded_manifest} $MEDIA_FILE --output re_inserted_image.jpg > /dev/null 2>&1 |
|
echo " --> re_inserted_image.jpg" |
|
|
|
echo |
|
echo "Checking the manifest." |
|
verification_json=$(${TRUEPIC_CLI} verify re_inserted_image.jpg) |
|
|
|
hash_status=$( |
|
echo "${verification_json}" | \ |
|
jq -r '.manifest_store[] | select(.is_active == true) | .assertions."c2pa.hash.data"[0].status' |
|
) |
|
thumbnail_hash=$( |
|
echo "${verification_json}" | \ |
|
jq -r '.manifest_store[0].assertions."c2pa.thumbnail.claim.jpeg"[0].thumbnail_id' |
|
) |
|
timestamp=$( |
|
echo "${verification_json}" | \ |
|
jq -r '.manifest_store[0].trusted_timestamp.timestamp' |
|
) |
|
public_key=$( |
|
echo "${verification_json}" | \ |
|
jq -r '.manifest_store[] | select(.is_active == true) | .certificate.cert_der' | \ |
|
base64 -d | \ |
|
openssl x509 -pubkey -noout |
|
) |
|
|
|
echo -n "Checking watermark signature... ${thumbnail_hash}|${timestamp} ... ${watermark_signature} ..." |
|
signature_verification=$( |
|
openssl dgst -sha256 \ |
|
-verify <(echo "${public_key}") \ |
|
-signature <(echo "${watermark_signature}" | base64 -d) \ |
|
<(echo "${thumbnail_hash}|${timestamp}") |
|
) |
|
|
|
echo " ${signature_verification}" |
|
|
|
echo -n "Checking image hash..." |
|
if [ "$hash_status" = "VALID" ]; then |
|
echo " hashes match." |
|
echo "${verification_json}" | jq |
|
rm -f ${downloaded_manifest} |
|
exit 0 |
|
fi |
|
echo " hashes DON'T match!" |
|
rm -f re_inserted_image.jpg |
|
|
|
echo |
|
echo -n "Re-signing the watermarked media..." |
|
${TRUEPIC_CLI} sign ${MEDIA_FILE} \ |
|
--ingredient-manifest-store ${downloaded_manifest} \ |
|
--output re_signed_image.jpg \ |
|
--assertions-inline '{ |
|
"assertions": [ |
|
{ |
|
"label": "c2pa.actions", |
|
"data": { |
|
"actions": [ |
|
{ |
|
"action": "c2pa.unknown", |
|
"when": "@now", |
|
"parameters": { |
|
"description": "Some unknown edits have been made between watermarking and now." |
|
} |
|
} |
|
] |
|
} |
|
} |
|
] |
|
}' > /dev/null 2>&1 |
|
echo " --> re_signed_image.jpg" |
|
rm -f ${downloaded_manifest} |
|
|
|
echo |
|
echo "Checking the manifest..." |
|
${TRUEPIC_CLI} verify re_signed_image.jpg | jq |