@@ -9,10 +9,262 @@ import TabItem from '@theme/TabItem';
9
9
<Tabs groupId = " programming-lang" >
10
10
<TabItem value = " python" label = " Python" default >
11
11
This is how to sign a manifest using Python.
12
+
13
+ ``` python
14
+ request_data = ... # This is the asset being signed
15
+ content_type = ... # MIME type of the asset
16
+
17
+ manifest = json.dumps({
18
+ " title" : " image.jpg" ,
19
+ " format" : " image/jpeg" ,
20
+ " claim_generator_info" : [
21
+ {
22
+ " name" : " Documentation example" ,
23
+ " version" : " 0.0.1"
24
+ }
25
+ ],
26
+ " assertions" : [
27
+ {
28
+ " label" : " c2pa.actions" ,
29
+ " data" : {
30
+ " actions" : [
31
+ {
32
+ " action" : " c2pa.edited" ,
33
+ " softwareAgent" : {
34
+ " name" : " C2PA Python Example" ,
35
+ " version" : " 0.1.0"
36
+ }
37
+ }
38
+ ]
39
+ }
40
+ }
41
+ ]
42
+ })
43
+
44
+ try :
45
+ builder = Builder(manifest)
46
+
47
+ signer = create_signer(kms_sign, signing_alg,
48
+ cert_chain, timestamp_url)
49
+
50
+ result = io.BytesIO(b " " )
51
+ builder.sign(signer, content_type, io.BytesIO(request_data), result)
52
+
53
+ return result.getvalue()
54
+ except Exception as e:
55
+ logging.error(e)
56
+ abort(500 , description = e)
57
+ ```
58
+
12
59
</TabItem >
13
60
14
61
<TabItem value = " node" label = " Node.js" >
15
62
This is how to sign a manifest using Node.js.
63
+
64
+ Use the ` c2pa.sign() ` method to sign an ingredient, either locally if you have a signing certificate and key available, or by using a remote signing API.
65
+
66
+ ## Signing buffers
67
+
68
+ If you have an asset file's data loaded into memory, you can sign the the asset using the loaded buffer.
69
+
70
+ ** NOTE** : Signing using a buffer is currently supported only for ` image/jpeg ` and ` image/png ` data. For all other file types, use the [ file-based approach] ( #signing-files ) .
71
+
72
+ ``` ts
73
+ import { readFile } from ' node:fs/promises' ;
74
+ import { createC2pa , createTestSigner } from ' c2pa-node' ;
75
+
76
+ // read an asset into a buffer
77
+ const buffer = await readFile (' to-be-signed.jpg' );
78
+ const asset: Asset = { buffer , mimeType: ' image/jpeg' };
79
+
80
+ // build a manifest to use for signing
81
+ const manifest = new ManifestBuilder (
82
+ {
83
+ claim_generator: ' my-app/1.0.0' ,
84
+ format: ' image/jpeg' ,
85
+ title: ' buffer_signer.jpg' ,
86
+ assertions: [
87
+ {
88
+ label: ' c2pa.actions' ,
89
+ data: {
90
+ actions: [
91
+ {
92
+ action: ' c2pa.created' ,
93
+ },
94
+ ],
95
+ },
96
+ },
97
+ {
98
+ label: ' com.custom.my-assertion' ,
99
+ data: {
100
+ description: ' My custom test assertion' ,
101
+ version: ' 1.0.0' ,
102
+ },
103
+ },
104
+ ],
105
+ },
106
+ { vendor: ' cai' },
107
+ );
108
+
109
+ // create a signing function
110
+ async function sign(asset , manifest ) {
111
+ const signer = await createTestSigner ();
112
+ const c2pa = createC2pa ({
113
+ signer ,
114
+ });
115
+
116
+ const { signedAsset, signedManifest } = await c2pa .sign ({
117
+ asset ,
118
+ manifest ,
119
+ });
120
+ }
121
+
122
+ // sign
123
+ await sign (asset , manifest );
124
+ ```
125
+
126
+ ## Signing files
127
+
128
+ To avoid loading the entire asset into memory (or for file types other than JPEG and PNG that don't support in-memory signing), pass in the file path to the asset file to sign it; for example:
129
+
130
+ ``` ts
131
+ import { resolve } from ' node:path' ;
132
+ import { createC2pa , createTestSigner } from ' c2pa-node' ;
133
+
134
+ // get the asset full path
135
+ const asset = {
136
+ path: resolve (' to-be-signed.jpg' ),
137
+ };
138
+ // define a location where to place the signed asset
139
+ const outputPath = resolve (' signed.jpg' );
140
+
141
+ // create a signing function
142
+ async function sign(asset , manifest ) {
143
+ const signer = await createTestSigner ();
144
+ const c2pa = createC2pa ({
145
+ signer ,
146
+ });
147
+
148
+ const { signedAsset, signedManifest } = await c2pa .sign ({
149
+ manifest ,
150
+ asset ,
151
+ options: {
152
+ outputPath ,
153
+ },
154
+ });
155
+ }
156
+
157
+ // build a manifest to use for signing
158
+ const manifest = new ManifestBuilder (
159
+ {
160
+ claim_generator: ' my-app/1.0.0' ,
161
+ format: ' image/jpeg' ,
162
+ title: ' buffer_signer.jpg' ,
163
+ assertions: [
164
+ {
165
+ label: ' c2pa.actions' ,
166
+ data: {
167
+ actions: [
168
+ {
169
+ action: ' c2pa.created' ,
170
+ },
171
+ ],
172
+ },
173
+ },
174
+ {
175
+ label: ' com.custom.my-assertion' ,
176
+ data: {
177
+ description: ' My custom test assertion' ,
178
+ version: ' 1.0.0' ,
179
+ },
180
+ },
181
+ ],
182
+ },
183
+ { vendor: ' cai' },
184
+ );
185
+
186
+ // sign
187
+ await sign (asset , manifest );
188
+ ```
189
+
190
+ ## Remote signing
191
+
192
+ If you have access to a web service that performs signing, you can use it to sign remotely; for example:
193
+
194
+ ``` ts
195
+ import { readFile } from ' node:fs/promises' ;
196
+ import { fetch , Headers } from ' node-fetch' ;
197
+ import { createC2pa , SigningAlgorithm } from ' c2pa-node' ;
198
+
199
+ function createRemoteSigner() {
200
+ return {
201
+ type: ' remote' ,
202
+ async reserveSize() {
203
+ const url = ` https://my.signing.service/box-size ` ;
204
+ const res = await fetch (url );
205
+ const data = (await res .json ()) as { boxSize: number };
206
+ return data .boxSize ;
207
+ },
208
+ async sign({ reserveSize , toBeSigned }) {
209
+ const url = ` https://my.signing.service/sign?boxSize=${reserveSize } ` ;
210
+ const res = await fetch (url , {
211
+ method: ' POST' ,
212
+ headers: new Headers ({
213
+ ' Content-Type' : ' application/octet-stream' ,
214
+ }),
215
+ body: toBeSigned ,
216
+ });
217
+ return res .buffer ();
218
+ },
219
+ };
220
+ }
221
+
222
+ async function sign(asset , manifest ) {
223
+ const signer = createRemoteSigner ();
224
+ const c2pa = createC2pa ({
225
+ signer ,
226
+ });
227
+
228
+ const { signedAsset, signedManifest } = await c2pa .sign ({
229
+ asset ,
230
+ manifest ,
231
+ });
232
+ }
233
+
234
+ const buffer = await readFile (' to-be-signed.jpg' );
235
+ const asset: Asset = { buffer , mimeType: ' image/jpeg' };
236
+
237
+ const manifest = new ManifestBuilder (
238
+ {
239
+ claim_generator: ' my-app/1.0.0' ,
240
+ format: ' image/jpeg' ,
241
+ title: ' buffer_signer.jpg' ,
242
+ assertions: [
243
+ {
244
+ label: ' c2pa.actions' ,
245
+ data: {
246
+ actions: [
247
+ {
248
+ action: ' c2pa.created' ,
249
+ },
250
+ ],
251
+ },
252
+ },
253
+ {
254
+ label: ' com.custom.my-assertion' ,
255
+ data: {
256
+ description: ' My custom test assertion' ,
257
+ version: ' 1.0.0' ,
258
+ },
259
+ },
260
+ ],
261
+ },
262
+ { vendor: ' cai' },
263
+ );
264
+
265
+ await sign (asset , manifest );
266
+ ```
267
+
16
268
</TabItem >
17
269
18
270
<TabItem value = " cpp" label = " C++" >
0 commit comments