From 25a6f0af6262c5fe5dc92b3e7f8b78128e616c90 Mon Sep 17 00:00:00 2001 From: Rand McKinney Date: Tue, 1 Apr 2025 10:26:55 -0700 Subject: [PATCH 01/10] Start reorg and consolidation of signing docs --- docs/prod-cert.mdx | 6 +-- docs/signing-certs.md | 6 +++ docs/{manifest => }/signing-manifests.md | 12 +++--- sidebars.js | 55 ++++++++++++++---------- 4 files changed, 47 insertions(+), 32 deletions(-) create mode 100644 docs/signing-certs.md rename docs/{manifest => }/signing-manifests.md (95%) diff --git a/docs/prod-cert.mdx b/docs/prod-cert.mdx index 82c8c412..c0625e64 100644 --- a/docs/prod-cert.mdx +++ b/docs/prod-cert.mdx @@ -1,11 +1,11 @@ --- id: prod-cert -title: Getting and using a signing certificate +title: Getting and using a production certificate --- ## Overview -For convenience, C2PA Tool, the Rust library, and the CAI prerelease libraries include one or more [test certificates](manifest/signing-manifests.md#test-certificates) and private keys for use during development, typically in the `tests/fixtures` directory. While these test certificates and keys are useful during development and testing, for production deployment you must use your own private key and certificate. +For convenience, C2PA Tool, the Rust library, and the CAI prerelease libraries include one or more [test certificates](signing-certs.md#test-certificates) and private keys for use during development, typically in the `tests/fixtures` directory. While these test certificates and keys are useful during development and testing, for production deployment you must use your own private key and certificate. Certificates and private keys are often stored on a hardware security module (HSM), a physical device that attaches directly to a computer or server and is used to securely manage and perform operations on cryptographic keys. A Key Management Service (KMS) is software used to manage keys in a networked environment. A KMS can be connected to a HSM for extra security. For example, the [Python example application](c2pa-python-example/readme.md) uses [AWS KMS](https://aws.amazon.com/kms/). @@ -26,7 +26,7 @@ A CSR is just an unsigned certificate that's a template for the certificate that A CSR comprises a public key, as well as ["distinguished name" information](https://knowledge.digicert.com/general-information/what-is-a-distinguished-name) that identifies the individual or organization requesting the certificate. The distinguished name includes a common name, organization, city, state, country, and e-mail address. Not all of these fields are required and will vary depending with the assurance level of the desired certificate. :::tip -For the C2PA [Verify tool](https://verify.contentauthenticity.org/) to display your organization name in the Content Credentials, your CSR must include the "O" or Organization Name attribute in the distinguished name information. See [below](#organization-name) for details. +For the C2PA [Verify tool](https://verify.contentauthenticity.org/) to display your organization name in the Content Credentials, your CSR must include the "O" or Organization Name attribute in the distinguished name information. See [below](#organization-name) for details. ::: You sign the CSR with your private key; this proves to the CA that you have control of the private key that corresponds to the public key included in the CSR. Once the requested information in a CSR passes a vetting process and domain control is established, the CA may sign the public key to indicate that it can be publicly trusted. diff --git a/docs/signing-certs.md b/docs/signing-certs.md new file mode 100644 index 00000000..02c4b3ab --- /dev/null +++ b/docs/signing-certs.md @@ -0,0 +1,6 @@ +--- +id: signing-certs +title: Signing and certificates +--- + +TBD \ No newline at end of file diff --git a/docs/manifest/signing-manifests.md b/docs/signing-manifests.md similarity index 95% rename from docs/manifest/signing-manifests.md rename to docs/signing-manifests.md index 2934d3e0..bb437b16 100644 --- a/docs/manifest/signing-manifests.md +++ b/docs/signing-manifests.md @@ -1,10 +1,10 @@ --- -id: signing-manifests +id: sign-manifests title: Signing manifests --- :::tip -Before reading this page, be sure to read [Getting started](../getting-started.mdx) so you'll have some basic background on public-key infrastructure (PKI) technology, certificates, and signing manifests. +Before reading this page, be sure to read [Getting started](getting-started.mdx) so you'll have some basic background on public-key infrastructure (PKI) technology, certificates, and signing manifests. ::: ## Overview @@ -78,7 +78,7 @@ The information in this table is based on the [C2PA specification Trust Model se Here is an example of generating a C2PA-compliant set of credentials using [GlobalSign](http://globalsign.com/) certificate authority (CA). :::note -GlobalSign is just one of many CAs. For a list of some others, see [Getting started](../getting-started.mdx#getting-a-security-certificate). +GlobalSign is just one of many CAs. For a list of some others, see [Getting started](getting-started.mdx#getting-a-security-certificate). :::note Credential management is a complex topic and different for every organization. See [above](#overview) for links to best practices. @@ -163,7 +163,7 @@ Certificate: . ``` -You now have all the needed information to configure C2PA Tool for manifest signing. Edit your [manifest store file](../c2patool/docs/manifest.md) to have the following content: +You now have all the needed information to configure C2PA Tool for manifest signing. Edit your [manifest store file](./c2patool/docs/manifest.md) to have the following content: ```json "alg": "ps256", @@ -173,7 +173,7 @@ You now have all the needed information to configure C2PA Tool for manifest sign The `private_key` and `sign_cert` properties must be full paths to the key and certificate chain files generated above. -You can now use C2PA Tool [to add a manifest to an image or other asset file](../c2patool/docs/usage.md#adding-a-manifest-to-an-asset-file). The command will be something like this: +You can now use C2PA Tool [to add a manifest to an image or other asset file](c2patool/docs/usage.md#adding-a-manifest-to-an-asset-file). The command will be something like this: ``` c2patool -m my_manifest.json -o signed_image.jpg my_image.jpg @@ -182,7 +182,7 @@ c2patool -m my_manifest.json -o signed_image.jpg my_image.jpg The example above uses the information in `my_manifest.json` to add a new manifest to output `signed_image.jpg` using source `my_image.jpg`. The manifest will be signed using the PS256 signature algorithm with private key `mykey.pem`. The manifest will contain the trust chain specified in `mycerts.pem`. :::warning -This example accesses the private key and certificate directly from the file system, which is fine during development, but in production may not be secure. Instead, in a production application, use a hardware security module (HSM) or a Key Management Service (KMS); for example as show in the [C2PA Python Example](../c2pa-python-example/readme.md). +This example accesses the private key and certificate directly from the file system, which is fine during development, but in production may not be secure. Instead, in a production application, use a hardware security module (HSM) or a Key Management Service (KMS); for example as show in the [C2PA Python Example](c2pa-python-example/readme.md). ::: ### Confirm it worked diff --git a/sidebars.js b/sidebars.js index 8d13b2fb..a4159c7c 100644 --- a/sidebars.js +++ b/sidebars.js @@ -12,6 +12,11 @@ const sidebars = { link: { type: 'doc', id: 'getting-started' }, collapsed: true, items: [ + { + type: 'doc', + label: 'FAQs', + id: 'faqs', + }, { type: 'doc', id: 'verify', @@ -40,10 +45,6 @@ const sidebars = { type: 'doc', id: 'manifest/manifest-validation', }, - { - type: 'doc', - id: 'manifest/signing-manifests', - }, { type: 'doc', id: 'manifest/manifest-examples', @@ -60,7 +61,6 @@ const sidebars = { }, ], }, - { type: 'category', label: 'C2PA Tool', @@ -111,7 +111,6 @@ const sidebars = { collapsed: true, items: jsSdkSidebar.docs, }, - { type: 'category', label: 'Prerelease libraries', @@ -209,7 +208,6 @@ const sidebars = { }, ], }, - { type: 'category', label: 'Rust library', @@ -249,19 +247,22 @@ const sidebars = { ], }, { - type: 'doc', - label: 'Getting and using a certificate', - id: 'prod-cert', - }, - { - type: 'doc', - label: 'FAQs', - id: 'faqs', - }, - { - type: 'doc', - label: 'Community resources', - id: 'community-resources', + type: 'category', + label: 'Signing and certificates', + link: { type: 'doc', id: 'signing-certs' }, + collapsed: true, + items: [ + { + type: 'doc', + label: 'Signing manifests', + id: 'sign-manifests', + }, + { + type: 'doc', + label: 'Using a certificate in production', + id: 'prod-cert', + }, + ], }, { type: 'category', @@ -325,9 +326,17 @@ const sidebars = { ], }, { - type: 'doc', - label: 'Task planning & roadmap', - id: 'roadmap', + type: 'category', + label: 'Community resources', + link: { type: 'doc', id: 'community-resources' }, + collapsed: true, + items: [ + { + type: 'doc', + label: 'Task planning & roadmap', + id: 'roadmap', + }, + ], }, ], }; From ee9dc272fbcddd353400f216f6496fb7425375a7 Mon Sep 17 00:00:00 2001 From: Rand McKinney Date: Tue, 1 Apr 2025 16:10:05 -0700 Subject: [PATCH 02/10] WIP reorg docs on certs and signing --- docs/getting-started.mdx | 45 +-------- docs/signing-certs.md | 6 -- docs/signing-manifests-redirect.mdx | 2 +- docs/{ => signing}/prod-cert.mdx | 26 ++++++ .../signing-certs.md} | 93 ++++++++++--------- sidebars.js | 9 +- 6 files changed, 84 insertions(+), 97 deletions(-) delete mode 100644 docs/signing-certs.md rename docs/{ => signing}/prod-cert.mdx (58%) rename docs/{signing-manifests.md => signing/signing-certs.md} (67%) diff --git a/docs/getting-started.mdx b/docs/getting-started.mdx index 3f1ab5ae..c5ef77c2 100644 --- a/docs/getting-started.mdx +++ b/docs/getting-started.mdx @@ -76,53 +76,18 @@ A signed digital certificate verifies the authenticity of an entity, such as a s ## Signing and certificates -Once you initially attach a manifest to an asset, it has information about the origin of the asset, such as the name of the tool that created it (for example, Photoshop) and your name as the _actor_ who created or modified it. Each time someone edits or updates the asset using a tool that supports CAI, it adds a new manifest with the actions taken and the certificate of the tool/site; this becomes the _active manifest_, which then references any prior manifests as ingredients. +A manifest attached to an asset contains information about the origin of the asset, such as the name of the tool that created it (for example, Photoshop) and the name of the _actor_ who created or modified it. Each time someone edits or updates the asset using a tool that supports CAI, it adds a new manifest with the actions taken and the certificate of the tool/site; this becomes the _active manifest_, which then references any prior manifests as ingredients. -Each manifest is digitally signed with the application's or client's credentials. To make validation of the credentials possible, the manifest also includes the signing certificate chain. The "chain" of certificates starts with the certificate from the last tool that signed the manifest (known as the "end-entity") followed by the certificate that signed it, and so on, back to the original CA issuer. In other words, a user knows they can trust that the manifest is valid because there is a "trust chain" that goes back to a trusted root certificate authority. That's why you need to acquire a security certificate from a legitimate certificate authority. +Each manifest is digitally signed with the application's or client's credentials. To enable validation of the credentials, the manifest also includes the signing certificate chain. The "chain" of certificates starts with the certificate from the last tool that signed the manifest (known as the "end-entity") followed by the certificate that signed it, and so on, back to the original CA issuer. A user can trust that the manifest is valid because there is a "trust chain" that goes back to a trusted root certificate authority. That's why you need to acquire a security certificate from a legitimate certificate authority. In practice, to use a certificate with the CAI SDK, follow this process: 1. Purchase security credentials (certificate and key) from a certificate authority. Either email protection or document signing certificates are valid. -2. Extract the certificate by using a tool such as OpenSSL. You could also host the certificate in a secure environment like a hardware security module (HSM). -3. Use one of the supporting CAI libraries or C2PA Tool to sign manifests using the certificate. +2. Extract the certificate by using a tool such as OpenSSL (for use during development). In production, you should host the private key in a secure environment like a hardware security module (HSM). +3. Use one of the supporting CAI libraries or C2PA Tool to sign manifests using the certificate and your private key. :::tip -For a short tutorial example, see [Signing manifests](manifest/signing-manifests.md). For more information on how to get and use a signing certificate in production, see [Getting and using a signing certificate](prod-cert.mdx). -::: - -### Getting a security certificate - -To create or modify Content Credentials, you must have a valid security certificate and key that conform to the requirements laid out in the [C2PA specification Trust Model section](https://c2pa.org/specifications/specifications/1.4/specs/C2PA_Specification.html#_trust_model). - -You must purchase a X.509 v3 security certificate from a certificate authority (CA). There are many CAs that issue certificates. Some of the most popular ones are: - -- GlobalSign: [S/MIME email signing](https://shop.globalsign.com/en/secure-email), [document signing](https://shop.globalsign.com/en/document-signing) -- IdenTrust: [S/MIME email signing](https://www.identrust.com/digital-certificates/secure-email-smime), [document signing](https://www.identrust.com/digital-certificates/document-signing) -- Comodo Cybersecurity: [S/MIME email signing cert](https://ssl.comodoca.com/s-mime), [document signing cert](https://ssl.comodoca.com/document-signing-certificates) -- Digicert: [S/MIME email signing cert](https://www.digicert.com/tls-ssl/secure-email-smime-certificates), [document signing cert](https://www.digicert.com/signing/document-signing-certificates) - -The above list is for reference only; inclusion does not imply endorsement by CAI or Adobe, Inc. - -When you purchase a certificate, you must select at least one of the extended key usage (EKU) fields that specify what the certificate can be used for: **email protection** and **document signing**. Applications that use the CAI SDK won't accept the certificate unless it has one of these EKUs. - -### Extracting the certificate - -To work with the certificate, you need to extract it. When the CAI SDK adds Content Credentials to an asset, it incorporates the certificate (including the associated public key) into the manifest. - -:::info Important -The _private key_ associated with the certificate is extremely sensitive. Always treat it with the highest security to ensure your credentials are not compromised. If someone does obtain your private key, they will be able to sign C2PA manifests and other content on your behalf without your consent. -::: - -### Using the certificate to sign a manifest - -The simplest way to add a C2PA manifest to an asset file is by using C2PA Tool (`c2patool`). You can run C2PA Tool tool manually from the command line (for example, during development) and more generally from any executable program that can call out to the shell, such as a Node.js application as shown in the [c2patool Node.js service example](c2pa-node-example/). - -The prerelease libraries for [Node.js](c2pa-node/), [Python](c2pa-python/), and [C++/C](c2pa-c/) can also add and sign a manifest. - -Similarly, using the Rust SDK, you can [add a manifest to an asset file](https://docs.rs/c2pa/latest/c2pa/#example-adding-a-manifest-to-a-file), referencing the certificate and private key file. For a simple example of creating and signing a manifest from a C program, see the [c2c2pa repository](https://github.com/contentauth/c2c2pa). - -:::warning Warning -Accessing a private key and certificate directly from the file system is fine during development, but doing so in production may be insecure. Instead use a Key Management Service (KMS) or a hardware security module (HSM) to access the certificate and key; for example as show in the [C2PA Python Example](https://github.com/contentauth/c2pa-python-example). +For a short tutorial example, see [Signing manifests](signing/signing-manifests.md). For more information on how to get and use a signing certificate in production, see [Getting and using a signing certificate](signing/prod-cert.mdx). ::: ### Verify known certificate list diff --git a/docs/signing-certs.md b/docs/signing-certs.md deleted file mode 100644 index 02c4b3ab..00000000 --- a/docs/signing-certs.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -id: signing-certs -title: Signing and certificates ---- - -TBD \ No newline at end of file diff --git a/docs/signing-manifests-redirect.mdx b/docs/signing-manifests-redirect.mdx index 6c67a005..0e66fb40 100644 --- a/docs/signing-manifests-redirect.mdx +++ b/docs/signing-manifests-redirect.mdx @@ -5,6 +5,6 @@ title: Redirect import { Redirect } from '@docusaurus/router'; - + This page will be redirected to `https://opensource.contentauthenticity.org/docs/manifest/signing-manifests`. diff --git a/docs/prod-cert.mdx b/docs/signing/prod-cert.mdx similarity index 58% rename from docs/prod-cert.mdx rename to docs/signing/prod-cert.mdx index c0625e64..2e45c854 100644 --- a/docs/prod-cert.mdx +++ b/docs/signing/prod-cert.mdx @@ -19,6 +19,32 @@ The process to purchase a certificate and key is different for each CA: You migh The certificate chain starts with the certificate from the last tool that signed the manifest (known as the "end-entity") followed by the certificate that signed it, and so on, back to the original CA issuer. This enables a validating application to determine that the manifest is valid because the certificate chain goes back to a trusted root certificate authority. +### Signature types + +The following table describes the signature algorithms and types that the CAI SDK supports. You must supply credentials (certificates and keys) that correspond to the signing algorithm. Signing/validation will fail if the the supplied credentials don't support the signature type. + +| Certificate `signatureAlgorithm` | Description | Recommended signature type | RFC Reference | +| --------------------------------------------------------- | ------------------------------------------------------------- | -------------------------- | ------------------------------------------------------------------------------------- | +| `ecdsa-with-SHA256` | ECDSA with SHA-256 | ES256\* | [RFC 5758 section 3.2](https://www.rfc-editor.org/rfc/rfc5758.html#section-3.2) | +| `ecdsa-with-SHA384` | ECDSA with SHA-384 | ES384\* | [RFC 5758 section 3.2](https://www.rfc-editor.org/rfc/rfc5758.html#section-3.2) | +| `ecdsa-with-SHA512` | ECDSA with SHA-512 | ES512\* | [RFC 5758 section 3.2](https://www.rfc-editor.org/rfc/rfc5758.html#section-3.2) | +| `sha256WithRSAEncryption` | RSASSA-PSS with SHA-256
MGF1 with SHA-256 | PS256 | [RFC 8017 appendix A.2.4](https://www.rfc-editor.org/rfc/rfc8017.html#appendix-A.2.4) | +| `sha384WithRSAEncryption` | RSASSA-PSS
SHA-384, MGF1 with SHA-384 | PS384 | [RFC 8017 appendix A.2.4](https://www.rfc-editor.org/rfc/rfc8017.html#appendix-A.2.4) | +| `sha512WithRSAEncryption` | RSASSA-PSS
SHA-512, MGF1 with SHA-512 | PS512 | [RFC 8017 appendix A.2.4](https://www.rfc-editor.org/rfc/rfc8017.html#appendix-A.2.4) | +| `id-RSASSA-PSS` - ASN1 OID: prime256v1, NIST CURVE: P-256 | RSA-PSS | ES256\* | [RFC 5758 section 3.2](https://www.rfc-editor.org/rfc/rfc5758.html#section-3.2) | +| `id-RSASSA-PSS` - ASN1 OID: secp384r1 | RSA-PSS | ES384\* | [RFC 5758 section 3.2](https://www.rfc-editor.org/rfc/rfc5758.html#section-3.2) | +| `id-RSASSA-PSS` - ASN1 OID: secp521r1 | RSA-PSS | ES512\* | [RFC 5758 section 3.2](https://www.rfc-editor.org/rfc/rfc5758.html#section-3.2) | +| `id-Ed25519` | EdDSA (Edwards-Curve DSA) with SHA-512 (SHA-2) and Curve25519 | Ed25519 instance ONLY. | [RFC 8410 section 3](https://www.rfc-editor.org/rfc/rfc8410.html#section-3) | + +:::info + + +* ES256, ES384, and ES512 signatures must be in IEEE P1363 format. + +::: + +The information in this table is based on the [C2PA specification Trust Model section](https://c2pa.org/specifications/specifications/2.1/specs/C2PA_Specification.html#_trust_model). The C2PA specification also covers two other certificates for timestamp responses and OCSP certificate revocation, which are not covered here. + ### Certificate signing requests (CSRs) A CSR is just an unsigned certificate that's a template for the certificate that you're requesting. The CA creates a new certificate with the parameters specified in the CSR, and signs it with their root certificate, which makes it a valid certificate. diff --git a/docs/signing-manifests.md b/docs/signing/signing-certs.md similarity index 67% rename from docs/signing-manifests.md rename to docs/signing/signing-certs.md index bb437b16..e56c2093 100644 --- a/docs/signing-manifests.md +++ b/docs/signing/signing-certs.md @@ -1,42 +1,33 @@ --- -id: sign-manifests -title: Signing manifests +id: signing-certs +title: Signing and certificates --- :::tip -Before reading this page, be sure to read [Getting started](getting-started.mdx) so you'll have some basic background on public-key infrastructure (PKI) technology, certificates, and signing manifests. +Before reading further, be sure to read [Getting started](getting-started.mdx#signing-and-certificates) so you'll have some basic background on public-key infrastructure (PKI) technology, certificates, and signing manifests. ::: ## Overview -To sign a C2PA manifest you need an end-entity certificate that complies with the C2PA trust model. Then you can use your private key and public certificates in the signing process. This page walks through an example of obtaining appropriate credentials and then signing a manifest with them using C2PA Tool. +To sign a claim in a C2PA manifest you need an end-entity certificate that complies with the C2PA trust model. Then you can use your private key with the certificate to sign it. :::note -Best practices for handling keys and certificates are beyond the scope of this documentation. Always protect your private keys with the highest level of security; for example, never share them through insecure channels such as email. +Best practices for handling keys and certificates are beyond the scope of this documentation. Always protect your private keys with the highest level of security; for example, never share them through insecure channels such as email. +::: Some useful references include: - [Key Management Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Key_Management_Cheat_Sheet.html#storage) from the Open Worldwide Application Security Project (OWASP). - [Key Management Guidelines](https://csrc.nist.gov/Projects/Key-Management/Key-Management-Guidelines) from the National Institute of Standards and Technology, US Department of Commerce. - [Protect your private keys](https://www.ncsc.gov.uk/collection/in-house-public-key-infrastructure/pki-principles/protect-your-private-keys) from the UK National Cyber Security Centre. -:::note ## Certificates Trust lists connect the end-entity certificate that signed a manifest back to the originating root CA. This is accomplished by supplying the subordinate public X.509 certificates forming the trust chain (the public X.509 certificate chain). If those are not supplied, you can use a private credential store to validate the certificate trust chain. If you do not supply a certificate chain or trust list, validators may reject the manifest. See the C2PA specification for more details. -A certificate used to sign C2PA manifests must: - -- Follow the Public Key Infrastructure (PKI) X.509 V3 specification. -- Have the Key Usage (KU) extension, which must be marked as critical. -- Assert the `digitalSignature` bit. -- Have the Extended Key Usage (EKU) extension. If the Basic Constraints extension is absent or the certificate authority (CA) Boolean is not asserted, the EKU must be non-empty. - - The `anyExtendedKeyUsageEKU` field (2.5.29.37.0) must not be present. - - If the configuration store does not contain a list of EKUs, a certificate that signs C2PA manifests must be valid for the `id-kp-emailProtection` (1.3.6.1.5.5.7.3.4) purpose and/or the `id-kp-documentSigning` (1.3.6.1.5.5.7.3.36) purpose. - ### Test certificates The CAI SDK does not allow you to use a self-signed certificate to sign a manifest. -For development and testing, use the sample certificates provided with the SDK. The [Rust library `sdk/tests/fixtures/certs/` folder](https://github.com/contentauth/c2pa-rs/tree/main/sdk/tests/fixtures/certs) contains certificates and signing keys for many of the supported signature types [described below](#signature-types). +For development and testing, use the sample certificates provided with the SDK. The [Rust library `sdk/tests/fixtures/certs/` folder](https://github.com/contentauth/c2pa-rs/tree/main/sdk/tests/fixtures/certs) contains certificates and signing keys for many of the supported signature types [described below](prod-cert.mdx#signature-types). Additionally, for convenience, CAI prerelease libraries also provide a subset of test certificates in each repository's `tests/fixtures` folder. The Node.js library even provides a [`CreateTestSigner()`](https://github.com/contentauth/c2pa-node/blob/main/docs/README.md#createtestsigner) convenience function to create a local signer instance using the test certificate. @@ -47,52 +38,68 @@ The test certificates are for use during development and testing only. Do not u Although not recommended due to complexity and difficulty, you can create your own certificates for development and testing. Follow the requirements in the C2PA Technical Specification [Credential Types](https://c2pa.org/specifications/specifications/1.4/specs/C2PA_Specification.html#_credential_types) and [Digital Signatures](https://c2pa.org/specifications/specifications/1.4/specs/C2PA_Specification.html#_digital_signatures) sections. -### Signature types +### Getting a security certificate + +To create or modify Content Credentials, you must have a valid security certificate and key that conform to the requirements in the [C2PA specification Trust Model section](https://c2pa.org/specifications/specifications/2.1/specs/C2PA_Specification.html#_trust_model). -The following table describes the signature algorithms and signature types that the CAI SDK supports. You must supply credentials (certificates and keys) that correspond to the signing algorithm. Signing/validation will fail if the the supplied credentials don't support the signature type. +A certificate used to sign C2PA manifests must: + +- Follow the public key infrastructure (PKI) X.509 V3 specification. +- Have the Key Usage (KU) extension, which must be marked as critical. +- Assert the `digitalSignature` bit. +- Have the Extended Key Usage (EKU) extension. If the Basic Constraints extension is absent or the certificate authority (CA) Boolean is not asserted, the EKU must be non-empty. + - The `anyExtendedKeyUsageEKU` field (2.5.29.37.0) must not be present. + - If the configuration store does not contain a list of EKUs, a certificate that signs C2PA manifests must be valid for the `id-kp-emailProtection` (1.3.6.1.5.5.7.3.4) purpose and/or the `id-kp-documentSigning` (1.3.6.1.5.5.7.3.36) purpose. -| Certificate `signatureAlgorithm` | Description | Recommended signature type | RFC Reference | -| -------------------------------- | ------------ | -------------------------- | ------------- | -| `ecdsa-with-SHA256` | ECDSA with SHA-256 | ES256* | [RFC 5758 section 3.2](https://www.rfc-editor.org/rfc/rfc5758.html#section-3.2) | -| `ecdsa-with-SHA384` | ECDSA with SHA-384 | ES384* | [RFC 5758 section 3.2](https://www.rfc-editor.org/rfc/rfc5758.html#section-3.2) | -| `ecdsa-with-SHA512` | ECDSA with SHA-512 | ES512* | [RFC 5758 section 3.2](https://www.rfc-editor.org/rfc/rfc5758.html#section-3.2) | -| `sha256WithRSAEncryption` | RSASSA-PSS with SHA-256
MGF1 with SHA-256| PS256 | [RFC 8017 appendix A.2.4](https://www.rfc-editor.org/rfc/rfc8017.html#appendix-A.2.4) | -| `sha384WithRSAEncryption` | RSASSA-PSS
SHA-384, MGF1 with SHA-384 | PS384 | [RFC 8017 appendix A.2.4](https://www.rfc-editor.org/rfc/rfc8017.html#appendix-A.2.4) | -| `sha512WithRSAEncryption` | RSASSA-PSS
SHA-512, MGF1 with SHA-512 | PS512 | [RFC 8017 appendix A.2.4](https://www.rfc-editor.org/rfc/rfc8017.html#appendix-A.2.4) | -| `id-RSASSA-PSS` - ASN1 OID: prime256v1, NIST CURVE: P-256 | RSA-PSS| ES256* | [RFC 5758 section 3.2](https://www.rfc-editor.org/rfc/rfc5758.html#section-3.2) | -| `id-RSASSA-PSS` - ASN1 OID: secp384r1 | RSA-PSS| ES384* | [RFC 5758 section 3.2](https://www.rfc-editor.org/rfc/rfc5758.html#section-3.2) | -| `id-RSASSA-PSS` - ASN1 OID: secp521r1 | RSA-PSS| ES512* | [RFC 5758 section 3.2](https://www.rfc-editor.org/rfc/rfc5758.html#section-3.2) | -| `id-Ed25519` | EdDSA (Edwards-Curve DSA) with SHA-512 (SHA-2) and Curve25519 | Ed25519 instance ONLY.| [RFC 8410 section 3](https://www.rfc-editor.org/rfc/rfc8410.html#section-3) | +You must purchase a X.509 v3 security certificate from a certificate authority (CA). There are many CAs that issue certificates. Some of the most popular ones are: +- GlobalSign: [S/MIME email signing](https://shop.globalsign.com/en/secure-email), [document signing](https://shop.globalsign.com/en/document-signing) +- IdenTrust: [S/MIME email signing](https://www.identrust.com/digital-certificates/secure-email-smime), [document signing](https://www.identrust.com/digital-certificates/document-signing) +- Comodo Cybersecurity: [S/MIME email signing cert](https://ssl.comodoca.com/s-mime), [document signing cert](https://ssl.comodoca.com/document-signing-certificates) +- Digicert: [S/MIME email signing cert](https://www.digicert.com/tls-ssl/secure-email-smime-certificates), [document signing cert](https://www.digicert.com/signing/document-signing-certificates) -:::info -* ES256, ES384, and ES512 signatures must be in IEEE P1363 format. +The above list is for reference only; inclusion does not imply endorsement by CAI or Adobe, Inc. +When you purchase a certificate, you must select at least one of the extended key usage (EKU) fields that specify what the certificate can be used for: **email protection** and **document signing**. Applications that use the CAI SDK won't accept the certificate unless it has one of these EKUs. + +### Extracting the certificate + +To work with the certificate, you need to extract it. When the CAI SDK adds Content Credentials to an asset, it incorporates the certificate (including the associated public key) into the manifest. + +:::warning Important +The _private key_ associated with the certificate is extremely sensitive. Always treat it with the highest security to ensure your credentials are not compromised. If someone does obtain your private key, they will be able to sign C2PA manifests and other content on your behalf without your consent. ::: +### Signing a manifest + +The simplest way to add a C2PA manifest to an asset file and sign it is by using C2PA Tool (`c2patool`). You can run C2PA Tool manually from the command line (for example, during development) and more generally from any executable program that can call out to the shell, such as a Node.js application as shown in the [c2patool Node.js service example](../c2pa-node-example). + +The prerelease libraries for [Node.js](../c2pa-node), [Python](../c2pa-python), and [C++/C](../c2pa-c) can also add and sign a manifest. -The information in this table is based on the [C2PA specification Trust Model section](https://c2pa.org/specifications/specifications/1.4/specs/C2PA_Specification.html#_trust_model). The C2PA specification also covers two other certificates for timestamp responses and OCSP certificate revocation, which are not covered here. +Similarly, using the Rust SDK, you can [add a manifest to an asset file](https://docs.rs/c2pa/latest/c2pa/#example-adding-a-manifest-to-a-file), referencing the certificate and private key file. For a simple example of creating and signing a manifest from a C program, see the [c2c2pa repository](https://github.com/contentauth/c2c2pa). + +:::warning Warning +Accessing a private key and certificate directly from the file system is fine during development, but doing so in production may be insecure. Instead use a Key Management Service (KMS) or a hardware security module (HSM) to access the certificate and key; for example as show in the [C2PA Python Example](https://github.com/contentauth/c2pa-python-example). +::: ## Example Here is an example of generating a C2PA-compliant set of credentials using [GlobalSign](http://globalsign.com/) certificate authority (CA). +GlobalSign is just one of many CAs. For a list of some others, see [Getting a security certificate](#getting-a-security-certificate) above. -:::note -GlobalSign is just one of many CAs. For a list of some others, see [Getting started](getting-started.mdx#getting-a-security-certificate). -:::note Credential management is a complex topic and different for every organization. See [above](#overview) for links to best practices. +:::note +This example uses an inexpensive personal certificate, which is fine for development and testing, but for production use an enterprise certificate is strongly recommended. An enterprise certificate is required for [Verify](https://verify.contentauthenticity.org/) to display your organization name when for signed assets. +::: + ### Step 1: Purchase credentials This example uses a [PersonSign1](https://shop.globalsign.com/en/secure-email) certificate from GlobalSign that contains KU and EKU values required to sign C2PA manifests. Follow the instructions to purchase and download your `.pfx` file. This file is a PKCS12 container that holds your certificate chain and private signing key. Other certificate providers may have alternate ways of providing your private key and certificate and may include only the end-entity certificate and so you must manually download the rest of the certificate chain. -:::warning Warning -This example uses an inexpensive personal certificate, which is fine for development and testing, but for production use an enterprise certificate is strongly recommended. An enterprise certificate is required for [Verify](https://verify.contentauthenticity.org/) to display your organization name when for signed assets. -::: - The rest of this tutorial uses OpenSSL (a set of cryptographic utilities). If OpenSSL is not installed on your system, see [OpenSSL](https://www.openssl.org/source/) for the source distribution or the [list of unofficial binary distributions](https://wiki.openssl.org/index.php/Binaries). ### Step 2: Extract the certificate and key @@ -133,9 +140,9 @@ For many certificate providers, the `.pfx` file contains not just your certifica openssl pkcs12 -in mycertfile.pfx -nokeys -out mycerts.pem ``` -## Using credentials with C2PA Tool +### Step 3: Use credentials with C2PA Tool -To use the credentials extracted above you must know the signature types they support. Typically, this information is available from your certificate provider. If it is not, enter this OpenSSL command to dump certificate information: +To use the credentials extracted above you must know the signature types they support. Typically, the certificate provider will provide this information. If it is not, enter this OpenSSL command to dump certificate information: ```shell openssl x509 -inform PEM -in mycerts.pem -text @@ -163,7 +170,7 @@ Certificate: . ``` -You now have all the needed information to configure C2PA Tool for manifest signing. Edit your [manifest store file](./c2patool/docs/manifest.md) to have the following content: +You now have all the needed information to configure C2PA Tool for manifest signing. Edit your [manifest store file](c2patool/docs/manifest.md) to add the following fields that are specific to C2PA Tool: ```json "alg": "ps256", diff --git a/sidebars.js b/sidebars.js index a4159c7c..f7be2be3 100644 --- a/sidebars.js +++ b/sidebars.js @@ -249,18 +249,13 @@ const sidebars = { { type: 'category', label: 'Signing and certificates', - link: { type: 'doc', id: 'signing-certs' }, + link: { type: 'doc', id: 'signing/signing-certs' }, collapsed: true, items: [ - { - type: 'doc', - label: 'Signing manifests', - id: 'sign-manifests', - }, { type: 'doc', label: 'Using a certificate in production', - id: 'prod-cert', + id: 'signing/prod-cert', }, ], }, From 7baea9f47fc0cebdc33ae728722298e84c4b2fcf Mon Sep 17 00:00:00 2001 From: Rand McKinney Date: Thu, 3 Apr 2025 13:58:34 -0700 Subject: [PATCH 03/10] More reorg --- docs/getting-started.mdx | 4 +- docs/signing/get-cert.md | 90 +++++++++++++++++++ docs/signing/index.md | 17 ++++ .../{signing-certs.md => local-signing.md} | 67 ++------------ docs/signing/prod-cert.mdx | 72 +++------------ docs/signing/test-certs.md | 19 ++++ sidebars.js | 17 +++- 7 files changed, 162 insertions(+), 124 deletions(-) create mode 100644 docs/signing/get-cert.md create mode 100644 docs/signing/index.md rename docs/signing/{signing-certs.md => local-signing.md} (60%) create mode 100644 docs/signing/test-certs.md diff --git a/docs/getting-started.mdx b/docs/getting-started.mdx index c5ef77c2..aee3a161 100644 --- a/docs/getting-started.mdx +++ b/docs/getting-started.mdx @@ -86,8 +86,8 @@ In practice, to use a certificate with the CAI SDK, follow this process: 2. Extract the certificate by using a tool such as OpenSSL (for use during development). In production, you should host the private key in a secure environment like a hardware security module (HSM). 3. Use one of the supporting CAI libraries or C2PA Tool to sign manifests using the certificate and your private key. -:::tip -For a short tutorial example, see [Signing manifests](signing/signing-manifests.md). For more information on how to get and use a signing certificate in production, see [Getting and using a signing certificate](signing/prod-cert.mdx). +:::info +For more information on getting and using certificates, see [Signing and certificates](signing/signing-certs.md). ::: ### Verify known certificate list diff --git a/docs/signing/get-cert.md b/docs/signing/get-cert.md new file mode 100644 index 00000000..5bcfd3f9 --- /dev/null +++ b/docs/signing/get-cert.md @@ -0,0 +1,90 @@ +--- +id: get-cert +title: Getting a signing certificate +--- + +:::note +Best practices for handling keys and certificates are beyond the scope of this documentation. Always protect your private keys with the highest level of security; for example, never share them through insecure channels such as email. +::: + +## Requirements + +A signing certificate and key (credentials) must conform to the requirements in the [C2PA specification Trust Model section](https://c2pa.org/specifications/specifications/2.1/specs/C2PA_Specification.html#_trust_model). The certificate must: + +- Follow the public key infrastructure (PKI) X.509 V3 specification. +- Have the Key Usage (KU) extension, which must be marked as critical. +- Assert the `digitalSignature` bit. +- Have the Extended Key Usage (EKU) extension. If the Basic Constraints extension is absent or the certificate authority (CA) Boolean is not asserted, the EKU must be non-empty. + - The `anyExtendedKeyUsageEKU` field (2.5.29.37.0) must not be present. + - If the configuration store does not contain a list of EKUs, a certificate that signs C2PA manifests must be valid for the `id-kp-emailProtection` (1.3.6.1.5.5.7.3.4) purpose and/or the `id-kp-documentSigning` (1.3.6.1.5.5.7.3.36) purpose. + +## Certificate authorities (CAs) + +To get a signing certificate, you must purchase a X.509 v3 security certificate from a certificate authority (CA). + +You must select at least one of the extended key usage (EKU) fields that specify what the certificate can be used for: **email protection** and **document signing**. Applications that use the CAI SDK won't accept the certificate unless it has one of these EKUs. + +There are many CAs that issue certificates. Some of the most popular ones are: + +- GlobalSign: [S/MIME email signing](https://shop.globalsign.com/en/secure-email), [document signing](https://shop.globalsign.com/en/document-signing) +- IdenTrust: [S/MIME email signing](https://www.identrust.com/digital-certificates/secure-email-smime), [document signing](https://www.identrust.com/digital-certificates/document-signing) +- Comodo Cybersecurity: [S/MIME email signing cert](https://ssl.comodoca.com/s-mime), [document signing cert](https://ssl.comodoca.com/document-signing-certificates) +- Digicert: [S/MIME email signing cert](https://www.digicert.com/tls-ssl/secure-email-smime-certificates), [document signing cert](https://www.digicert.com/signing/document-signing-certificates) + +The above list is for reference only; inclusion does not imply endorsement by CAI or Adobe, Inc. + +### Types of certificates + +CAs offer a variety of different kinds of certificates (links below are to [Digicert](https://www.digicert.com), but there are many other CAs): + +- The simplest and least expensive option is an [S/MIME email certificate](https://www.digicert.com/tls-ssl/compare-secure-email-smime-certificates). +- Other options, such as [document signing certificate](https://www.digicert.com/signing/compare-document-signing-certificates) require more rigor (like proving your identity) and cost more. + +### Organization name + +If you want the C2PA [Verify tool](https://verify.contentauthenticity.org/) to display your organization name in the Content Credentials, your certificate must include the "O" or [Organization Name attribute](https://www.alvestrand.no/objectid/2.5.4.10.html) (OID value 2.5.4.10) in the distinguished name information. The CA may require some validation steps to prove you are part of that organization (details vary by CA). + +## Purchasing a certificate + +To create or modify Content Credentials, you must have a valid X.509 v3 security certificate and key that conform to the requirements laid out in the [C2PA specification](https://c2pa.org/specifications/specifications/2.0/specs/C2PA_Specification.html#x509_certificates). You must purchase a certificate from a certificate authority (CA). There are many CAs; some popular ones are listed in [Getting started](getting-started.mdx#getting-a-security-certificate). + +The process to purchase a certificate and key is different for each CA: You might be able to simply click a "Buy" button on the CA's website. Or your can make your own key and use it to create a certificate signing request (CSR) that you send to the CA. Regardless of the process, what you get back is a signed certificate that you use to create a certificate chain. + +The certificate chain starts with the certificate from the last tool that signed the manifest (known as the "end-entity") followed by the certificate that signed it, and so on, back to the original CA issuer. This enables a validating application to determine that the manifest is valid because the certificate chain goes back to a trusted root certificate authority. + +### Signature types + +The following table describes the signature algorithms and types that the CAI SDK supports. You must supply credentials (certificates and keys) that correspond to the signing algorithm (`signatureAlgorithm`). Signing/validation will fail if the the supplied credentials don't support the signature type. + +| Certificate `signatureAlgorithm` | Description | Recommended signature type | RFC Reference | +| -------------------------------- | ------------ | -------------------------- | ------------- | +| `ecdsa-with-SHA256` | ECDSA with SHA-256 | ES256\* | [RFC 5758 section 3.2](https://www.rfc-editor.org/rfc/rfc5758.html#section-3.2) | +| `ecdsa-with-SHA384` | ECDSA with SHA-384 | ES384\* | [RFC 5758 section 3.2](https://www.rfc-editor.org/rfc/rfc5758.html#section-3.2) | +| `ecdsa-with-SHA512` | ECDSA with SHA-512 | ES512\* | [RFC 5758 section 3.2](https://www.rfc-editor.org/rfc/rfc5758.html#section-3.2) | +| `sha256WithRSAEncryption` | RSASSA-PSS with SHA-256
MGF1 with SHA-256 | PS256 | [RFC 8017 appendix A.2.4](https://www.rfc-editor.org/rfc/rfc8017.html#appendix-A.2.4) | +| `sha384WithRSAEncryption` | RSASSA-PSS
SHA-384, MGF1 with SHA-384 | PS384 | [RFC 8017 appendix A.2.4](https://www.rfc-editor.org/rfc/rfc8017.html#appendix-A.2.4) | +| `sha512WithRSAEncryption` | RSASSA-PSS
SHA-512, MGF1 with SHA-512 | PS512 | [RFC 8017 appendix A.2.4](https://www.rfc-editor.org/rfc/rfc8017.html#appendix-A.2.4) | +| `id-RSASSA-PSS` - ASN1 OID: prime256v1, NIST CURVE: P-256 | RSA-PSS | ES256\* | [RFC 5758 section 3.2](https://www.rfc-editor.org/rfc/rfc5758.html#section-3.2) | +| `id-RSASSA-PSS` - ASN1 OID: secp384r1 | RSA-PSS | ES384\* | [RFC 5758 section 3.2](https://www.rfc-editor.org/rfc/rfc5758.html#section-3.2) | +| `id-RSASSA-PSS` - ASN1 OID: secp521r1 | RSA-PSS | ES512\* | [RFC 5758 section 3.2](https://www.rfc-editor.org/rfc/rfc5758.html#section-3.2) | +| `id-Ed25519` | EdDSA (Edwards-Curve DSA) with SHA-512 (SHA-2) and Curve25519 | Ed25519 instance ONLY. | [RFC 8410 section 3](https://www.rfc-editor.org/rfc/rfc8410.html#section-3) | + +:::info + + +* ES256, ES384, and ES512 signatures must be in IEEE P1363 format. + +The information in this table is based on the [C2PA specification Trust Model section](https://c2pa.org/specifications/specifications/2.1/specs/C2PA_Specification.html#_trust_model). The C2PA specification also covers two other certificates for timestamp responses and OCSP certificate revocation, which are not covered here. + +### Certificate signing requests (CSRs) + +A CSR is just an unsigned certificate that's a template for the certificate that you're requesting. The CA creates a new certificate with the parameters specified in the CSR, and signs it with their root certificate, which makes it a valid certificate. + +A CSR comprises a public key, as well as ["distinguished name" information](https://knowledge.digicert.com/general-information/what-is-a-distinguished-name) that identifies the individual or organization requesting the certificate. The distinguished name includes a common name, organization, city, state, country, and e-mail address. Not all of these fields are required and will vary depending with the assurance level of the desired certificate. + +:::tip +For the C2PA [Verify tool](https://verify.contentauthenticity.org/) to display your organization name in the Content Credentials, your CSR must include the "O" or Organization Name attribute in the distinguished name information. See [below](#organization-name) for details. +::: + +You sign the CSR with your private key; this proves to the CA that you have control of the private key that corresponds to the public key included in the CSR. Once the requested information in a CSR passes a vetting process and domain control is established, the CA may sign the public key to indicate that it can be publicly trusted. + diff --git a/docs/signing/index.md b/docs/signing/index.md new file mode 100644 index 00000000..97876b00 --- /dev/null +++ b/docs/signing/index.md @@ -0,0 +1,17 @@ +--- +id: signing-and-certs +title: Signing and certificates +--- + +:::tip +Be sure to read [Getting started](getting-started.mdx#signing-and-certificates) for some basic background on public-key infrastructure (PKI) technology, certificates, and signing manifests. +::: + +As you're developing an application that uses the CAI SDK, there are three ways to sign manifest claims: +1. [**Initial prototyping and development**](test-certs.md): Use the test certificates and keys included with the SDK libraries to sign claims. These certs and keys are provided for convenience, but aren't valid for actual signing. +1. [**Local/internal testing**](local-signing.md): Once your code is working with the test certs and keys, you're ready to purchase your own certificate from a certificate authority (CA) using your private key. Then for internal testing, your application can use the certificate and key *locally* (i.e. directly from the file system) to sign manifest claims; however, this is NOT safe in production. +1. [**Production testing/deployment**](prod-cert.mdx): To secure your private key for use in a publicly-accessible production application, store it in a hardware security module (HSM) or key management service (KMS). Then your application can access it securely in production. + +:::warning +Best practices for handling keys and certificates are beyond the scope of this documentation. Always protect your private keys with the highest level of security; for example, never share them through insecure channels such as email. +::: \ No newline at end of file diff --git a/docs/signing/signing-certs.md b/docs/signing/local-signing.md similarity index 60% rename from docs/signing/signing-certs.md rename to docs/signing/local-signing.md index e56c2093..b92c3acc 100644 --- a/docs/signing/signing-certs.md +++ b/docs/signing/local-signing.md @@ -1,67 +1,14 @@ --- -id: signing-certs -title: Signing and certificates +id: local-signing +title: Signing with local credentials --- -:::tip -Before reading further, be sure to read [Getting started](getting-started.mdx#signing-and-certificates) so you'll have some basic background on public-key infrastructure (PKI) technology, certificates, and signing manifests. -::: - ## Overview To sign a claim in a C2PA manifest you need an end-entity certificate that complies with the C2PA trust model. Then you can use your private key with the certificate to sign it. -:::note -Best practices for handling keys and certificates are beyond the scope of this documentation. Always protect your private keys with the highest level of security; for example, never share them through insecure channels such as email. -::: - -Some useful references include: -- [Key Management Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Key_Management_Cheat_Sheet.html#storage) from the Open Worldwide Application Security Project (OWASP). -- [Key Management Guidelines](https://csrc.nist.gov/Projects/Key-Management/Key-Management-Guidelines) from the National Institute of Standards and Technology, US Department of Commerce. -- [Protect your private keys](https://www.ncsc.gov.uk/collection/in-house-public-key-infrastructure/pki-principles/protect-your-private-keys) from the UK National Cyber Security Centre. - -## Certificates - Trust lists connect the end-entity certificate that signed a manifest back to the originating root CA. This is accomplished by supplying the subordinate public X.509 certificates forming the trust chain (the public X.509 certificate chain). If those are not supplied, you can use a private credential store to validate the certificate trust chain. If you do not supply a certificate chain or trust list, validators may reject the manifest. See the C2PA specification for more details. -### Test certificates - -The CAI SDK does not allow you to use a self-signed certificate to sign a manifest. -For development and testing, use the sample certificates provided with the SDK. The [Rust library `sdk/tests/fixtures/certs/` folder](https://github.com/contentauth/c2pa-rs/tree/main/sdk/tests/fixtures/certs) contains certificates and signing keys for many of the supported signature types [described below](prod-cert.mdx#signature-types). - -Additionally, for convenience, CAI prerelease libraries also provide a subset of test certificates in each repository's `tests/fixtures` folder. The Node.js library even provides a [`CreateTestSigner()`](https://github.com/contentauth/c2pa-node/blob/main/docs/README.md#createtestsigner) convenience function to create a local signer instance using the test certificate. - -:::warning Warning -The test certificates are for use during development and testing only. Do not use them in production! -::: - -Although not recommended due to complexity and difficulty, you can create your own certificates for development and testing. Follow the requirements in the C2PA Technical Specification [Credential Types](https://c2pa.org/specifications/specifications/1.4/specs/C2PA_Specification.html#_credential_types) and [Digital Signatures](https://c2pa.org/specifications/specifications/1.4/specs/C2PA_Specification.html#_digital_signatures) sections. - - -### Getting a security certificate - -To create or modify Content Credentials, you must have a valid security certificate and key that conform to the requirements in the [C2PA specification Trust Model section](https://c2pa.org/specifications/specifications/2.1/specs/C2PA_Specification.html#_trust_model). - -A certificate used to sign C2PA manifests must: - -- Follow the public key infrastructure (PKI) X.509 V3 specification. -- Have the Key Usage (KU) extension, which must be marked as critical. -- Assert the `digitalSignature` bit. -- Have the Extended Key Usage (EKU) extension. If the Basic Constraints extension is absent or the certificate authority (CA) Boolean is not asserted, the EKU must be non-empty. - - The `anyExtendedKeyUsageEKU` field (2.5.29.37.0) must not be present. - - If the configuration store does not contain a list of EKUs, a certificate that signs C2PA manifests must be valid for the `id-kp-emailProtection` (1.3.6.1.5.5.7.3.4) purpose and/or the `id-kp-documentSigning` (1.3.6.1.5.5.7.3.36) purpose. - -You must purchase a X.509 v3 security certificate from a certificate authority (CA). There are many CAs that issue certificates. Some of the most popular ones are: - -- GlobalSign: [S/MIME email signing](https://shop.globalsign.com/en/secure-email), [document signing](https://shop.globalsign.com/en/document-signing) -- IdenTrust: [S/MIME email signing](https://www.identrust.com/digital-certificates/secure-email-smime), [document signing](https://www.identrust.com/digital-certificates/document-signing) -- Comodo Cybersecurity: [S/MIME email signing cert](https://ssl.comodoca.com/s-mime), [document signing cert](https://ssl.comodoca.com/document-signing-certificates) -- Digicert: [S/MIME email signing cert](https://www.digicert.com/tls-ssl/secure-email-smime-certificates), [document signing cert](https://www.digicert.com/signing/document-signing-certificates) - -The above list is for reference only; inclusion does not imply endorsement by CAI or Adobe, Inc. - -When you purchase a certificate, you must select at least one of the extended key usage (EKU) fields that specify what the certificate can be used for: **email protection** and **document signing**. Applications that use the CAI SDK won't accept the certificate unless it has one of these EKUs. - ### Extracting the certificate To work with the certificate, you need to extract it. When the CAI SDK adds Content Credentials to an asset, it incorporates the certificate (including the associated public key) into the manifest. @@ -70,16 +17,16 @@ To work with the certificate, you need to extract it. When the CAI SDK adds Cont The _private key_ associated with the certificate is extremely sensitive. Always treat it with the highest security to ensure your credentials are not compromised. If someone does obtain your private key, they will be able to sign C2PA manifests and other content on your behalf without your consent. ::: -### Signing a manifest +## Signing a manifest The simplest way to add a C2PA manifest to an asset file and sign it is by using C2PA Tool (`c2patool`). You can run C2PA Tool manually from the command line (for example, during development) and more generally from any executable program that can call out to the shell, such as a Node.js application as shown in the [c2patool Node.js service example](../c2pa-node-example). -The prerelease libraries for [Node.js](../c2pa-node), [Python](../c2pa-python), and [C++/C](../c2pa-c) can also add and sign a manifest. - Similarly, using the Rust SDK, you can [add a manifest to an asset file](https://docs.rs/c2pa/latest/c2pa/#example-adding-a-manifest-to-a-file), referencing the certificate and private key file. For a simple example of creating and signing a manifest from a C program, see the [c2c2pa repository](https://github.com/contentauth/c2c2pa). +The prerelease libraries for [Node.js](../c2pa-node), [Python](../c2pa-python), and [C++/C](../c2pa-c) can also add and sign a manifest. + :::warning Warning -Accessing a private key and certificate directly from the file system is fine during development, but doing so in production may be insecure. Instead use a Key Management Service (KMS) or a hardware security module (HSM) to access the certificate and key; for example as show in the [C2PA Python Example](https://github.com/contentauth/c2pa-python-example). +Accessing a private key and certificate directly from the file system is fine during development, but doing so in production is not ecure. Instead use a Key Management Service (KMS) or a hardware security module (HSM) to access the certificate and key; for example as show in the [C2PA Python Example](https://github.com/contentauth/c2pa-python-example). ::: ## Example @@ -189,7 +136,7 @@ c2patool -m my_manifest.json -o signed_image.jpg my_image.jpg The example above uses the information in `my_manifest.json` to add a new manifest to output `signed_image.jpg` using source `my_image.jpg`. The manifest will be signed using the PS256 signature algorithm with private key `mykey.pem`. The manifest will contain the trust chain specified in `mycerts.pem`. :::warning -This example accesses the private key and certificate directly from the file system, which is fine during development, but in production may not be secure. Instead, in a production application, use a hardware security module (HSM) or a Key Management Service (KMS); for example as show in the [C2PA Python Example](c2pa-python-example/readme.md). +This example accesses the private key and certificate directly from the file system, which is fine during development, but is not secure for use in production. Instead, use a hardware security module (HSM) or a Key Management Service (KMS); for example as show in the [C2PA Python Example](c2pa-python-example/readme.md). ::: ### Confirm it worked diff --git a/docs/signing/prod-cert.mdx b/docs/signing/prod-cert.mdx index 2e45c854..9b2b534a 100644 --- a/docs/signing/prod-cert.mdx +++ b/docs/signing/prod-cert.mdx @@ -1,73 +1,23 @@ --- id: prod-cert -title: Getting and using a production certificate +title: Using a signing certificate in production --- -## Overview +Accessing a private key and certificate [directly from the local file system](local-signing.md) is fine during development, but doing so in production is not secure. Instead use one or both of: -For convenience, C2PA Tool, the Rust library, and the CAI prerelease libraries include one or more [test certificates](signing-certs.md#test-certificates) and private keys for use during development, typically in the `tests/fixtures` directory. While these test certificates and keys are useful during development and testing, for production deployment you must use your own private key and certificate. - -Certificates and private keys are often stored on a hardware security module (HSM), a physical device that attaches directly to a computer or server and is used to securely manage and perform operations on cryptographic keys. A Key Management Service (KMS) is software used to manage keys in a networked environment. A KMS can be connected to a HSM for extra security. For example, the [Python example application](c2pa-python-example/readme.md) uses [AWS KMS](https://aws.amazon.com/kms/). - -## Purchasing a certificate - -To create or modify Content Credentials, you must have a valid X.509 v3 security certificate and key that conform to the requirements laid out in the [C2PA specification](https://c2pa.org/specifications/specifications/2.0/specs/C2PA_Specification.html#x509_certificates). You must purchase a certificate from a certificate authority (CA). There are many CAs; some popular ones are listed in [Getting started](getting-started.mdx#getting-a-security-certificate). - -When you purchase a certificate, you must select at least one of the extended key usage (EKU) fields that specify what the certificate can be used for: **email protection** and **document signing**. Applications that use the CAI SDK won't accept the certificate unless it has one of these EKUs. - -The process to purchase a certificate and key is different for each CA: You might be able to simply click a "Buy" button on the CA's website. Or your can make your own key and use it to create a certificate signing request (CSR) that you send to the CA (see below). Regardless of the process, what you get back is a signed certificate that you use to create a certificate chain. - -The certificate chain starts with the certificate from the last tool that signed the manifest (known as the "end-entity") followed by the certificate that signed it, and so on, back to the original CA issuer. This enables a validating application to determine that the manifest is valid because the certificate chain goes back to a trusted root certificate authority. - -### Signature types - -The following table describes the signature algorithms and types that the CAI SDK supports. You must supply credentials (certificates and keys) that correspond to the signing algorithm. Signing/validation will fail if the the supplied credentials don't support the signature type. - -| Certificate `signatureAlgorithm` | Description | Recommended signature type | RFC Reference | -| --------------------------------------------------------- | ------------------------------------------------------------- | -------------------------- | ------------------------------------------------------------------------------------- | -| `ecdsa-with-SHA256` | ECDSA with SHA-256 | ES256\* | [RFC 5758 section 3.2](https://www.rfc-editor.org/rfc/rfc5758.html#section-3.2) | -| `ecdsa-with-SHA384` | ECDSA with SHA-384 | ES384\* | [RFC 5758 section 3.2](https://www.rfc-editor.org/rfc/rfc5758.html#section-3.2) | -| `ecdsa-with-SHA512` | ECDSA with SHA-512 | ES512\* | [RFC 5758 section 3.2](https://www.rfc-editor.org/rfc/rfc5758.html#section-3.2) | -| `sha256WithRSAEncryption` | RSASSA-PSS with SHA-256
MGF1 with SHA-256 | PS256 | [RFC 8017 appendix A.2.4](https://www.rfc-editor.org/rfc/rfc8017.html#appendix-A.2.4) | -| `sha384WithRSAEncryption` | RSASSA-PSS
SHA-384, MGF1 with SHA-384 | PS384 | [RFC 8017 appendix A.2.4](https://www.rfc-editor.org/rfc/rfc8017.html#appendix-A.2.4) | -| `sha512WithRSAEncryption` | RSASSA-PSS
SHA-512, MGF1 with SHA-512 | PS512 | [RFC 8017 appendix A.2.4](https://www.rfc-editor.org/rfc/rfc8017.html#appendix-A.2.4) | -| `id-RSASSA-PSS` - ASN1 OID: prime256v1, NIST CURVE: P-256 | RSA-PSS | ES256\* | [RFC 5758 section 3.2](https://www.rfc-editor.org/rfc/rfc5758.html#section-3.2) | -| `id-RSASSA-PSS` - ASN1 OID: secp384r1 | RSA-PSS | ES384\* | [RFC 5758 section 3.2](https://www.rfc-editor.org/rfc/rfc5758.html#section-3.2) | -| `id-RSASSA-PSS` - ASN1 OID: secp521r1 | RSA-PSS | ES512\* | [RFC 5758 section 3.2](https://www.rfc-editor.org/rfc/rfc5758.html#section-3.2) | -| `id-Ed25519` | EdDSA (Edwards-Curve DSA) with SHA-512 (SHA-2) and Curve25519 | Ed25519 instance ONLY. | [RFC 8410 section 3](https://www.rfc-editor.org/rfc/rfc8410.html#section-3) | - -:::info - - -* ES256, ES384, and ES512 signatures must be in IEEE P1363 format. +- **A key management service** (KMS), a system used to securely store and manage cryptographic keys, including generation, storage, rotation, and revocation. +- **A hardware security module** (HSM), a physical device that attaches directly to a server to securely manage and perform operations on cryptographic keys. +:::warning +Best practices for handling keys and certificates are beyond the scope of this documentation. Always protect your private keys with the highest level of security; for example, never share them through insecure channels such as email. ::: -The information in this table is based on the [C2PA specification Trust Model section](https://c2pa.org/specifications/specifications/2.1/specs/C2PA_Specification.html#_trust_model). The C2PA specification also covers two other certificates for timestamp responses and OCSP certificate revocation, which are not covered here. - -### Certificate signing requests (CSRs) - -A CSR is just an unsigned certificate that's a template for the certificate that you're requesting. The CA creates a new certificate with the parameters specified in the CSR, and signs it with their root certificate, which makes it a valid certificate. - -A CSR comprises a public key, as well as ["distinguished name" information](https://knowledge.digicert.com/general-information/what-is-a-distinguished-name) that identifies the individual or organization requesting the certificate. The distinguished name includes a common name, organization, city, state, country, and e-mail address. Not all of these fields are required and will vary depending with the assurance level of the desired certificate. - -:::tip -For the C2PA [Verify tool](https://verify.contentauthenticity.org/) to display your organization name in the Content Credentials, your CSR must include the "O" or Organization Name attribute in the distinguished name information. See [below](#organization-name) for details. -::: - -You sign the CSR with your private key; this proves to the CA that you have control of the private key that corresponds to the public key included in the CSR. Once the requested information in a CSR passes a vetting process and domain control is established, the CA may sign the public key to indicate that it can be publicly trusted. - -### Types of certificates - -CAs offer a variety of different kinds of certificates (links below are to [Digicert](https://www.digicert.com), but there are many other CAs): - -- The simplest and least expensive option is an [S/MIME email certificate](https://www.digicert.com/tls-ssl/compare-secure-email-smime-certificates). -- Other options, such as [document signing certificate](https://www.digicert.com/signing/compare-document-signing-certificates) require more rigor (like proving your identity) and cost more. - -### Organization name +Some useful references for handling keys and certificates include: -If you want the C2PA [Verify tool](https://verify.contentauthenticity.org/) to display your organization name in the Content Credentials, your certificate must include the "O" or [Organization Name attribute](https://www.alvestrand.no/objectid/2.5.4.10.html) (OID value 2.5.4.10) in the distinguished name information. The CA may require some validation steps to prove you are part of that organization (details vary by CA). +- [Key Management Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Key_Management_Cheat_Sheet.html#storage) from the Open Worldwide Application Security Project (OWASP). +- [Key Management Guidelines](https://csrc.nist.gov/Projects/Key-Management/Key-Management-Guidelines) from the National Institute of Standards and Technology, US Department of Commerce. +- [Protect your private keys](https://www.ncsc.gov.uk/collection/in-house-public-key-infrastructure/pki-principles/protect-your-private-keys) from the UK National Cyber Security Centre. ## The C2PA Python example -The [c2pa-python-example](c2pa-python-example/readme.md) app provides an example of constructing a certificate signing request (CSR) and of using a certificate in a way suitable for a production environment. +The [c2pa-python-example](c2pa-python-example/readme.md) app provides an example of constructing a certificate signing request (CSR) and of using [Amazon KMS](https://aws.amazon.com/kms/). diff --git a/docs/signing/test-certs.md b/docs/signing/test-certs.md new file mode 100644 index 00000000..7aa9dbd5 --- /dev/null +++ b/docs/signing/test-certs.md @@ -0,0 +1,19 @@ +--- +id: test-certs +title: Using test certificates +--- + +For development and testing, C2PA Tool, the Rust library, and the CAI prerelease libraries include one or more [test certificates](signing-certs.md#test-certificates) and private keys for use during development. While these test certificates and keys are useful during development and testing, for production deployment you must use your own private key and certificate. + +The [Rust library `sdk/tests/fixtures/certs/` folder](https://github.com/contentauth/c2pa-rs/tree/main/sdk/tests/fixtures/certs) contains certificates and signing keys for many of the supported signature types [described below](prod-cert.mdx#signature-types). + +The CAI prerelease libraries also provide a subset of test certificates in each repository's `tests/fixtures` folder. The Node.js library even provides a [`CreateTestSigner()`](https://github.com/contentauth/c2pa-node/blob/main/docs/README.md#createtestsigner) convenience function to create a local signer instance using the test certificate. + +The CAI SDK does not allow you to use a self-signed certificate to sign a manifest. + +:::warning Warning +The test certificates are for use during development and testing only. Do not use them in production! +::: + +Although not recommended due to complexity and difficulty, you can create your own certificates for development and testing. Follow the requirements in the C2PA Technical Specification [Credential Types](https://c2pa.org/specifications/specifications/1.4/specs/C2PA_Specification.html#_credential_types) and [Digital Signatures](https://c2pa.org/specifications/specifications/1.4/specs/C2PA_Specification.html#_digital_signatures) sections. + diff --git a/sidebars.js b/sidebars.js index f7be2be3..b813eba8 100644 --- a/sidebars.js +++ b/sidebars.js @@ -249,9 +249,24 @@ const sidebars = { { type: 'category', label: 'Signing and certificates', - link: { type: 'doc', id: 'signing/signing-certs' }, + link: { type: 'doc', id: 'signing/signing-and-certs' }, collapsed: true, items: [ + { + type: 'doc', + label: 'Using test certificates', + id: 'signing/test-certs', + }, + { + type: 'doc', + label: 'Getting a certificate', + id: 'signing/get-cert', + }, + { + type: 'doc', + label: 'Signing with local credentials', + id: 'signing/local-signing', + }, { type: 'doc', label: 'Using a certificate in production', From 33f284e0f5d9fef20036237b74fa02b3d99aa86b Mon Sep 17 00:00:00 2001 From: Rand McKinney Date: Thu, 3 Apr 2025 16:08:49 -0700 Subject: [PATCH 04/10] More edits and reorg --- docs/signing/get-cert.md | 74 ++++++++++++++++++----------------- docs/signing/index.md | 14 ++++--- docs/signing/local-signing.md | 23 +++-------- docs/signing/prod-cert.mdx | 14 +++++-- 4 files changed, 63 insertions(+), 62 deletions(-) diff --git a/docs/signing/get-cert.md b/docs/signing/get-cert.md index 5bcfd3f9..6c6d9e36 100644 --- a/docs/signing/get-cert.md +++ b/docs/signing/get-cert.md @@ -3,28 +3,17 @@ id: get-cert title: Getting a signing certificate --- -:::note +:::note Important Best practices for handling keys and certificates are beyond the scope of this documentation. Always protect your private keys with the highest level of security; for example, never share them through insecure channels such as email. ::: -## Requirements - -A signing certificate and key (credentials) must conform to the requirements in the [C2PA specification Trust Model section](https://c2pa.org/specifications/specifications/2.1/specs/C2PA_Specification.html#_trust_model). The certificate must: - -- Follow the public key infrastructure (PKI) X.509 V3 specification. -- Have the Key Usage (KU) extension, which must be marked as critical. -- Assert the `digitalSignature` bit. -- Have the Extended Key Usage (EKU) extension. If the Basic Constraints extension is absent or the certificate authority (CA) Boolean is not asserted, the EKU must be non-empty. - - The `anyExtendedKeyUsageEKU` field (2.5.29.37.0) must not be present. - - If the configuration store does not contain a list of EKUs, a certificate that signs C2PA manifests must be valid for the `id-kp-emailProtection` (1.3.6.1.5.5.7.3.4) purpose and/or the `id-kp-documentSigning` (1.3.6.1.5.5.7.3.36) purpose. +To sign manifest claims, you must have an X.509 v3 security certificate and key that conform to the requirements laid out in the [C2PA specification](https://c2pa.org/specifications/specifications/2.1/specs/C2PA_Specification.html#x509_certificates). ## Certificate authorities (CAs) -To get a signing certificate, you must purchase a X.509 v3 security certificate from a certificate authority (CA). - -You must select at least one of the extended key usage (EKU) fields that specify what the certificate can be used for: **email protection** and **document signing**. Applications that use the CAI SDK won't accept the certificate unless it has one of these EKUs. +To create or modify Content Credentials, you must purchase a signing certificate from a certificate authority (CA). -There are many CAs that issue certificates. Some of the most popular ones are: +There are many CAs that issue certificates. Some popular ones include: - GlobalSign: [S/MIME email signing](https://shop.globalsign.com/en/secure-email), [document signing](https://shop.globalsign.com/en/document-signing) - IdenTrust: [S/MIME email signing](https://www.identrust.com/digital-certificates/secure-email-smime), [document signing](https://www.identrust.com/digital-certificates/document-signing) @@ -35,22 +24,47 @@ The above list is for reference only; inclusion does not imply endorsement by CA ### Types of certificates -CAs offer a variety of different kinds of certificates (links below are to [Digicert](https://www.digicert.com), but there are many other CAs): +CAs offer a variety of different types of certificates (links below are to [Digicert](https://www.digicert.com), but most CAs offer these types of certificates): - The simplest and least expensive option is an [S/MIME email certificate](https://www.digicert.com/tls-ssl/compare-secure-email-smime-certificates). - Other options, such as [document signing certificate](https://www.digicert.com/signing/compare-document-signing-certificates) require more rigor (like proving your identity) and cost more. -### Organization name +### Purchasing a certificate -If you want the C2PA [Verify tool](https://verify.contentauthenticity.org/) to display your organization name in the Content Credentials, your certificate must include the "O" or [Organization Name attribute](https://www.alvestrand.no/objectid/2.5.4.10.html) (OID value 2.5.4.10) in the distinguished name information. The CA may require some validation steps to prove you are part of that organization (details vary by CA). +The process to purchase a certificate and key is different for each CA: You might be able to simply click a "Buy" button on the CA's website. Or your can make your own key and use it to create a certificate signing request (CSR) that you send to the CA. Regardless of the process, what you get back is a signed certificate that you use to create a certificate chain. -## Purchasing a certificate +The certificate chain starts with the certificate from the last tool that signed the manifest (known as the "end-entity") followed by the certificate that signed it, and so on, back to the original CA issuer. This enables a validating application to determine that the manifest is valid because the certificate chain goes back to a trusted root certificate authority. -To create or modify Content Credentials, you must have a valid X.509 v3 security certificate and key that conform to the requirements laid out in the [C2PA specification](https://c2pa.org/specifications/specifications/2.0/specs/C2PA_Specification.html#x509_certificates). You must purchase a certificate from a certificate authority (CA). There are many CAs; some popular ones are listed in [Getting started](getting-started.mdx#getting-a-security-certificate). +### Certificate signing requests (CSRs) -The process to purchase a certificate and key is different for each CA: You might be able to simply click a "Buy" button on the CA's website. Or your can make your own key and use it to create a certificate signing request (CSR) that you send to the CA. Regardless of the process, what you get back is a signed certificate that you use to create a certificate chain. +A CSR is just an unsigned certificate that's a template for the certificate that you're requesting. The CA creates a new certificate with the parameters specified in the CSR, and signs it with their root certificate, which makes it a valid certificate. -The certificate chain starts with the certificate from the last tool that signed the manifest (known as the "end-entity") followed by the certificate that signed it, and so on, back to the original CA issuer. This enables a validating application to determine that the manifest is valid because the certificate chain goes back to a trusted root certificate authority. +A CSR comprises a public key, as well as ["distinguished name" information](https://knowledge.digicert.com/general-information/what-is-a-distinguished-name) that identifies the individual or organization requesting the certificate. The distinguished name includes a common name, organization, city, state, country, and e-mail address. Not all of these fields are required and will vary depending with the assurance level of the desired certificate. + +:::tip +For the C2PA [Verify tool](https://verify.contentauthenticity.org/) to display your organization name in the Content Credentials, your CSR must include the "O" or Organization Name attribute in the distinguished name information. +::: + +You sign the CSR with your private key; this proves to the CA that you have control of the private key that corresponds to the public key included in the CSR. Once the requested information in a CSR passes a vetting process and domain control is established, the CA may sign the public key to indicate that it can be publicly trusted. + +## Certificate requirements + +A signing certificate and key (credentials) must conform to the requirements in the [C2PA specification Trust Model section](https://c2pa.org/specifications/specifications/2.1/specs/C2PA_Specification.html#_trust_model). The certificate must: + +- Follow the public key infrastructure (PKI) X.509 V3 specification. +- Have the Key Usage (KU) extension, which must be marked as critical. +- Assert the `digitalSignature` bit. +- Have the Extended Key Usage (EKU) extension. If the Basic Constraints extension is absent or the certificate authority (CA) Boolean is not asserted, the EKU must be non-empty. + - The `anyExtendedKeyUsageEKU` field (2.5.29.37.0) must not be present. + - If the configuration store does not contain a list of EKUs, a certificate that signs C2PA manifests must be valid for the `id-kp-emailProtection` (1.3.6.1.5.5.7.3.4) purpose and/or the `id-kp-documentSigning` (1.3.6.1.5.5.7.3.36) purpose. + +### Extended key usage (EKU) fields + +You must select at least one of the extended key usage (EKU) fields that specify what the certificate can be used for: **email protection** and **document signing**. Applications that use the CAI SDK won't accept the certificate unless it has one of these EKUs. + +### Organization name + +If you want the C2PA [Verify tool](https://verify.contentauthenticity.org/) to display your organization name in the Content Credentials, your certificate must include the "O" or [Organization Name attribute](https://www.alvestrand.no/objectid/2.5.4.10.html) (OID value 2.5.4.10) in the distinguished name information. The CA may require some validation steps to prove you are part of that organization (details vary by CA). ### Signature types @@ -69,22 +83,10 @@ The following table describes the signature algorithms and types that the CAI SD | `id-RSASSA-PSS` - ASN1 OID: secp521r1 | RSA-PSS | ES512\* | [RFC 5758 section 3.2](https://www.rfc-editor.org/rfc/rfc5758.html#section-3.2) | | `id-Ed25519` | EdDSA (Edwards-Curve DSA) with SHA-512 (SHA-2) and Curve25519 | Ed25519 instance ONLY. | [RFC 8410 section 3](https://www.rfc-editor.org/rfc/rfc8410.html#section-3) | -:::info - - * ES256, ES384, and ES512 signatures must be in IEEE P1363 format. -The information in this table is based on the [C2PA specification Trust Model section](https://c2pa.org/specifications/specifications/2.1/specs/C2PA_Specification.html#_trust_model). The C2PA specification also covers two other certificates for timestamp responses and OCSP certificate revocation, which are not covered here. - -### Certificate signing requests (CSRs) - -A CSR is just an unsigned certificate that's a template for the certificate that you're requesting. The CA creates a new certificate with the parameters specified in the CSR, and signs it with their root certificate, which makes it a valid certificate. - -A CSR comprises a public key, as well as ["distinguished name" information](https://knowledge.digicert.com/general-information/what-is-a-distinguished-name) that identifies the individual or organization requesting the certificate. The distinguished name includes a common name, organization, city, state, country, and e-mail address. Not all of these fields are required and will vary depending with the assurance level of the desired certificate. +--- -:::tip -For the C2PA [Verify tool](https://verify.contentauthenticity.org/) to display your organization name in the Content Credentials, your CSR must include the "O" or Organization Name attribute in the distinguished name information. See [below](#organization-name) for details. -::: +The information in this table is based on the [C2PA specification Trust Model section](https://c2pa.org/specifications/specifications/2.1/specs/C2PA_Specification.html#_trust_model). The C2PA specification also covers two other certificates for timestamp responses and OCSP certificate revocation, which are not covered here. -You sign the CSR with your private key; this proves to the CA that you have control of the private key that corresponds to the public key included in the CSR. Once the requested information in a CSR passes a vetting process and domain control is established, the CA may sign the public key to indicate that it can be publicly trusted. diff --git a/docs/signing/index.md b/docs/signing/index.md index 97876b00..36ab928e 100644 --- a/docs/signing/index.md +++ b/docs/signing/index.md @@ -7,11 +7,13 @@ title: Signing and certificates Be sure to read [Getting started](getting-started.mdx#signing-and-certificates) for some basic background on public-key infrastructure (PKI) technology, certificates, and signing manifests. ::: -As you're developing an application that uses the CAI SDK, there are three ways to sign manifest claims: -1. [**Initial prototyping and development**](test-certs.md): Use the test certificates and keys included with the SDK libraries to sign claims. These certs and keys are provided for convenience, but aren't valid for actual signing. -1. [**Local/internal testing**](local-signing.md): Once your code is working with the test certs and keys, you're ready to purchase your own certificate from a certificate authority (CA) using your private key. Then for internal testing, your application can use the certificate and key *locally* (i.e. directly from the file system) to sign manifest claims; however, this is NOT safe in production. -1. [**Production testing/deployment**](prod-cert.mdx): To secure your private key for use in a publicly-accessible production application, store it in a hardware security module (HSM) or key management service (KMS). Then your application can access it securely in production. +As you're developing an application that uses the CAI SDK, there are three ways to sign manifest claims, depending on where you are in your development process: +1. **Initial prototyping and development**: Use the test certificates and keys included with the SDK libraries to sign claims. These certs and keys are provided for convenience, but aren't valid for actual signing. For more information, see [Using test certificates](test-certs.md). +1. **Local/internal testing**: Once your code is working with the test certs and keys: + - [Purchase your own certificate](get-cert.md) from a certificate authority (CA). + - Then your application can [use the certificate and key *locally*](local-signing.md) (directly from the file system) to sign manifest claims; however, this is NOT safe in production. +1. **Production testing/deployment**: To secure your private key for use in a publicly-accessible production application, store it in a hardware security module (HSM) or key management service (KMS) where your application can access it securely . -:::warning +:::note Best practices for handling keys and certificates are beyond the scope of this documentation. Always protect your private keys with the highest level of security; for example, never share them through insecure channels such as email. -::: \ No newline at end of file +::: diff --git a/docs/signing/local-signing.md b/docs/signing/local-signing.md index b92c3acc..9044595b 100644 --- a/docs/signing/local-signing.md +++ b/docs/signing/local-signing.md @@ -9,14 +9,6 @@ To sign a claim in a C2PA manifest you need an end-entity certificate that compl Trust lists connect the end-entity certificate that signed a manifest back to the originating root CA. This is accomplished by supplying the subordinate public X.509 certificates forming the trust chain (the public X.509 certificate chain). If those are not supplied, you can use a private credential store to validate the certificate trust chain. If you do not supply a certificate chain or trust list, validators may reject the manifest. See the C2PA specification for more details. -### Extracting the certificate - -To work with the certificate, you need to extract it. When the CAI SDK adds Content Credentials to an asset, it incorporates the certificate (including the associated public key) into the manifest. - -:::warning Important -The _private key_ associated with the certificate is extremely sensitive. Always treat it with the highest security to ensure your credentials are not compromised. If someone does obtain your private key, they will be able to sign C2PA manifests and other content on your behalf without your consent. -::: - ## Signing a manifest The simplest way to add a C2PA manifest to an asset file and sign it is by using C2PA Tool (`c2patool`). You can run C2PA Tool manually from the command line (for example, during development) and more generally from any executable program that can call out to the shell, such as a Node.js application as shown in the [c2patool Node.js service example](../c2pa-node-example). @@ -26,16 +18,12 @@ Similarly, using the Rust SDK, you can [add a manifest to an asset file](https:/ The prerelease libraries for [Node.js](../c2pa-node), [Python](../c2pa-python), and [C++/C](../c2pa-c) can also add and sign a manifest. :::warning Warning -Accessing a private key and certificate directly from the file system is fine during development, but doing so in production is not ecure. Instead use a Key Management Service (KMS) or a hardware security module (HSM) to access the certificate and key; for example as show in the [C2PA Python Example](https://github.com/contentauth/c2pa-python-example). +Accessing a private key and certificate directly from the file system is fine during development, but doing so in production is not secure. Instead use a Key Management Service (KMS) or a hardware security module (HSM) to access the certificate and key; For more information, see [Using a certificate in production](prod-cert.mdx). ::: ## Example -Here is an example of generating a C2PA-compliant set of credentials using [GlobalSign](http://globalsign.com/) certificate authority (CA). -GlobalSign is just one of many CAs. For a list of some others, see [Getting a security certificate](#getting-a-security-certificate) above. - - -Credential management is a complex topic and different for every organization. See [above](#overview) for links to best practices. +Here is an example of generating a C2PA-compliant set of credentials using [GlobalSign](http://globalsign.com/) certificate authority (CA). GlobalSign is just one of many CAs. For a list of some others, see [Getting a security certificate](get-cert.md#certificate-authorities-cas). :::note This example uses an inexpensive personal certificate, which is fine for development and testing, but for production use an enterprise certificate is strongly recommended. An enterprise certificate is required for [Verify](https://verify.contentauthenticity.org/) to display your organization name when for signed assets. @@ -51,6 +39,7 @@ The rest of this tutorial uses OpenSSL (a set of cryptographic utilities). If Op ### Step 2: Extract the certificate and key +To work with the certificate, you need to extract it. When the CAI SDK adds Content Credentials to an asset, it incorporates the certificate (including the associated public key) into the manifest. Use the commands below to extract the key and certificate chain. If prompted, enter the password that was used to generate the `.pfx` file. :::tip @@ -117,7 +106,7 @@ Certificate: . ``` -You now have all the needed information to configure C2PA Tool for manifest signing. Edit your [manifest store file](c2patool/docs/manifest.md) to add the following fields that are specific to C2PA Tool: +You now have all the needed information to configure C2PA Tool for manifest signing. Edit your [manifest store file](../c2patool/docs/manifest.md) to add the following fields that are specific to C2PA Tool: ```json "alg": "ps256", @@ -127,7 +116,7 @@ You now have all the needed information to configure C2PA Tool for manifest sign The `private_key` and `sign_cert` properties must be full paths to the key and certificate chain files generated above. -You can now use C2PA Tool [to add a manifest to an image or other asset file](c2patool/docs/usage.md#adding-a-manifest-to-an-asset-file). The command will be something like this: +You can now use C2PA Tool [to add a manifest to an image or other asset file](../c2patool/docs/usage.md#adding-a-manifest-to-an-asset-file). The command will be something like this: ``` c2patool -m my_manifest.json -o signed_image.jpg my_image.jpg @@ -136,7 +125,7 @@ c2patool -m my_manifest.json -o signed_image.jpg my_image.jpg The example above uses the information in `my_manifest.json` to add a new manifest to output `signed_image.jpg` using source `my_image.jpg`. The manifest will be signed using the PS256 signature algorithm with private key `mykey.pem`. The manifest will contain the trust chain specified in `mycerts.pem`. :::warning -This example accesses the private key and certificate directly from the file system, which is fine during development, but is not secure for use in production. Instead, use a hardware security module (HSM) or a Key Management Service (KMS); for example as show in the [C2PA Python Example](c2pa-python-example/readme.md). +This example accesses the private key and certificate directly from the file system, which is fine during development, but is not secure for production use. For more information, see [Using a certificate in production](prod-cert.mdx). ::: ### Confirm it worked diff --git a/docs/signing/prod-cert.mdx b/docs/signing/prod-cert.mdx index 9b2b534a..9bcd686d 100644 --- a/docs/signing/prod-cert.mdx +++ b/docs/signing/prod-cert.mdx @@ -5,10 +5,12 @@ title: Using a signing certificate in production Accessing a private key and certificate [directly from the local file system](local-signing.md) is fine during development, but doing so in production is not secure. Instead use one or both of: -- **A key management service** (KMS), a system used to securely store and manage cryptographic keys, including generation, storage, rotation, and revocation. -- **A hardware security module** (HSM), a physical device that attaches directly to a server to securely manage and perform operations on cryptographic keys. +- A **key management service** (KMS), to securely store and manage cryptographic keys, including generation, storage, rotation, and revocation. Popular KMS providers include [Amazon KMS](https://aws.amazon.com/kms/), [Google Cloud Key Management](https://cloud.google.com/security/products/security-key-management), and [Azure Key Vault](https://azure.microsoft.com/en-us/products/key-vault). +- A **hardware security module** (HSM), a physical device that attaches directly to a server to securely manage and perform operations on cryptographic keys. -:::warning +## Best practices + +:::note Best practices for handling keys and certificates are beyond the scope of this documentation. Always protect your private keys with the highest level of security; for example, never share them through insecure channels such as email. ::: @@ -18,6 +20,12 @@ Some useful references for handling keys and certificates include: - [Key Management Guidelines](https://csrc.nist.gov/Projects/Key-Management/Key-Management-Guidelines) from the National Institute of Standards and Technology, US Department of Commerce. - [Protect your private keys](https://www.ncsc.gov.uk/collection/in-house-public-key-infrastructure/pki-principles/protect-your-private-keys) from the UK National Cyber Security Centre. +## Pre-production steps + +Because using a KMS can be complex, you may want to start by using a local "mock" service such as LocalStack (for Amazon KMS). Doing this enables you to test your code before you set up a production KMS. + +You can also create a self-signed certificate for development purposes. The resulting manifests signed with this certificate won't be trusted, but you can use it to run the application to see how it works before purchasing a real certificate from a CA. + ## The C2PA Python example The [c2pa-python-example](c2pa-python-example/readme.md) app provides an example of constructing a certificate signing request (CSR) and of using [Amazon KMS](https://aws.amazon.com/kms/). From 469e9741e5d445d823637faa99fd3913db91b4c3 Mon Sep 17 00:00:00 2001 From: Rand McKinney Date: Thu, 3 Apr 2025 16:20:08 -0700 Subject: [PATCH 05/10] Add and fix redirects --- docs/prod-cert-redirect.mdx | 10 ++++++++++ docs/signing-manifests-redirect.mdx | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 docs/prod-cert-redirect.mdx diff --git a/docs/prod-cert-redirect.mdx b/docs/prod-cert-redirect.mdx new file mode 100644 index 00000000..38b0158a --- /dev/null +++ b/docs/prod-cert-redirect.mdx @@ -0,0 +1,10 @@ +--- +id: prod-cert +title: Redirect +--- + +import { Redirect } from '@docusaurus/router'; + + + +This page will be redirected to `https://opensource.contentauthenticity.org/docs/signing/prod-cert`. diff --git a/docs/signing-manifests-redirect.mdx b/docs/signing-manifests-redirect.mdx index 0e66fb40..c29b2b39 100644 --- a/docs/signing-manifests-redirect.mdx +++ b/docs/signing-manifests-redirect.mdx @@ -5,6 +5,6 @@ title: Redirect import { Redirect } from '@docusaurus/router'; - + This page will be redirected to `https://opensource.contentauthenticity.org/docs/manifest/signing-manifests`. From 11073b8d462794e2c163ac2932a695540eac7ba5 Mon Sep 17 00:00:00 2001 From: Rand McKinney Date: Fri, 4 Apr 2025 10:20:45 -0700 Subject: [PATCH 06/10] Polish edits, check links --- docs/signing/get-cert.md | 10 ++++------ docs/signing/index.md | 6 +++--- docs/signing/local-signing.md | 4 +--- docs/signing/prod-cert.mdx | 2 +- docs/signing/test-certs.md | 17 +++++++++-------- docs/verify.mdx | 10 +++++++--- 6 files changed, 25 insertions(+), 24 deletions(-) diff --git a/docs/signing/get-cert.md b/docs/signing/get-cert.md index 6c6d9e36..54e928a4 100644 --- a/docs/signing/get-cert.md +++ b/docs/signing/get-cert.md @@ -11,9 +11,7 @@ To sign manifest claims, you must have an X.509 v3 security certificate and key ## Certificate authorities (CAs) -To create or modify Content Credentials, you must purchase a signing certificate from a certificate authority (CA). - -There are many CAs that issue certificates. Some popular ones include: +You must purchase a signing certificate from a certificate authority (CA). There are many CAs that issue certificates. Some popular ones include: - GlobalSign: [S/MIME email signing](https://shop.globalsign.com/en/secure-email), [document signing](https://shop.globalsign.com/en/document-signing) - IdenTrust: [S/MIME email signing](https://www.identrust.com/digital-certificates/secure-email-smime), [document signing](https://www.identrust.com/digital-certificates/document-signing) @@ -49,7 +47,7 @@ You sign the CSR with your private key; this proves to the CA that you have cont ## Certificate requirements -A signing certificate and key (credentials) must conform to the requirements in the [C2PA specification Trust Model section](https://c2pa.org/specifications/specifications/2.1/specs/C2PA_Specification.html#_trust_model). The certificate must: +A signing certificate and key (credentials) must conform to the requirements in the [C2PA specification X.509 Certificates section](https://c2pa.org/specifications/specifications/2.1/specs/C2PA_Specification.html#x509_certificates); specifically, it must: - Follow the public key infrastructure (PKI) X.509 V3 specification. - Have the Key Usage (KU) extension, which must be marked as critical. @@ -70,6 +68,8 @@ If you want the C2PA [Verify tool](https://verify.contentauthenticity.org/) to d The following table describes the signature algorithms and types that the CAI SDK supports. You must supply credentials (certificates and keys) that correspond to the signing algorithm (`signatureAlgorithm`). Signing/validation will fail if the the supplied credentials don't support the signature type. +This table is provided for convenience, and is based on information in the [C2PA specification](https://c2pa.org/specifications/specifications/2.1/specs/C2PA_Specification.html#x509_certificates). The specification is authoritative; refer to it for more details. The C2PA specification also covers two other certificates for timestamp responses and OCSP certificate revocation, which are not covered here. + | Certificate `signatureAlgorithm` | Description | Recommended signature type | RFC Reference | | -------------------------------- | ------------ | -------------------------- | ------------- | | `ecdsa-with-SHA256` | ECDSA with SHA-256 | ES256\* | [RFC 5758 section 3.2](https://www.rfc-editor.org/rfc/rfc5758.html#section-3.2) | @@ -85,8 +85,6 @@ The following table describes the signature algorithms and types that the CAI SD * ES256, ES384, and ES512 signatures must be in IEEE P1363 format. ---- -The information in this table is based on the [C2PA specification Trust Model section](https://c2pa.org/specifications/specifications/2.1/specs/C2PA_Specification.html#_trust_model). The C2PA specification also covers two other certificates for timestamp responses and OCSP certificate revocation, which are not covered here. diff --git a/docs/signing/index.md b/docs/signing/index.md index 36ab928e..9ad8a156 100644 --- a/docs/signing/index.md +++ b/docs/signing/index.md @@ -9,9 +9,9 @@ Be sure to read [Getting started](getting-started.mdx#signing-and-certificates) As you're developing an application that uses the CAI SDK, there are three ways to sign manifest claims, depending on where you are in your development process: 1. **Initial prototyping and development**: Use the test certificates and keys included with the SDK libraries to sign claims. These certs and keys are provided for convenience, but aren't valid for actual signing. For more information, see [Using test certificates](test-certs.md). -1. **Local/internal testing**: Once your code is working with the test certs and keys: - - [Purchase your own certificate](get-cert.md) from a certificate authority (CA). - - Then your application can [use the certificate and key *locally*](local-signing.md) (directly from the file system) to sign manifest claims; however, this is NOT safe in production. +1. **Local/internal testing**: Once your code is working with the test certs and keys, you can move on to: + - [Purchase your own certificate](get-cert.md) from a certificate authority (CA). + - Change your application to [use the certificate and key *locally*](local-signing.md) (directly from the file system) to sign manifest claims; however, this is NOT safe in production. 1. **Production testing/deployment**: To secure your private key for use in a publicly-accessible production application, store it in a hardware security module (HSM) or key management service (KMS) where your application can access it securely . :::note diff --git a/docs/signing/local-signing.md b/docs/signing/local-signing.md index 9044595b..0b12ff00 100644 --- a/docs/signing/local-signing.md +++ b/docs/signing/local-signing.md @@ -13,9 +13,7 @@ Trust lists connect the end-entity certificate that signed a manifest back to th The simplest way to add a C2PA manifest to an asset file and sign it is by using C2PA Tool (`c2patool`). You can run C2PA Tool manually from the command line (for example, during development) and more generally from any executable program that can call out to the shell, such as a Node.js application as shown in the [c2patool Node.js service example](../c2pa-node-example). -Similarly, using the Rust SDK, you can [add a manifest to an asset file](https://docs.rs/c2pa/latest/c2pa/#example-adding-a-manifest-to-a-file), referencing the certificate and private key file. For a simple example of creating and signing a manifest from a C program, see the [c2c2pa repository](https://github.com/contentauth/c2c2pa). - -The prerelease libraries for [Node.js](../c2pa-node), [Python](../c2pa-python), and [C++/C](../c2pa-c) can also add and sign a manifest. +Similarly, using the Rust SDK, you can [add a manifest to an asset file](https://docs.rs/c2pa/latest/c2pa/#example-adding-a-manifest-to-a-file), referencing the certificate and private key file. The prerelease libraries for [Node.js](../c2pa-node), [Python](../c2pa-python), and [C++/C](../c2pa-c) can also add and sign a manifest. :::warning Warning Accessing a private key and certificate directly from the file system is fine during development, but doing so in production is not secure. Instead use a Key Management Service (KMS) or a hardware security module (HSM) to access the certificate and key; For more information, see [Using a certificate in production](prod-cert.mdx). diff --git a/docs/signing/prod-cert.mdx b/docs/signing/prod-cert.mdx index 9bcd686d..2065b087 100644 --- a/docs/signing/prod-cert.mdx +++ b/docs/signing/prod-cert.mdx @@ -22,7 +22,7 @@ Some useful references for handling keys and certificates include: ## Pre-production steps -Because using a KMS can be complex, you may want to start by using a local "mock" service such as LocalStack (for Amazon KMS). Doing this enables you to test your code before you set up a production KMS. +Because using a KMS can be complex, you may want to start by using a local "mock" service (such as LocalStack for Amazon KMS) as illustrated in the [c2pa-python-example](c2pa-python-example/readme.md#using-localstack). Doing this enables you to test your code before you set up a production KMS. You can also create a self-signed certificate for development purposes. The resulting manifests signed with this certificate won't be trusted, but you can use it to run the application to see how it works before purchasing a real certificate from a CA. diff --git a/docs/signing/test-certs.md b/docs/signing/test-certs.md index 7aa9dbd5..1488061c 100644 --- a/docs/signing/test-certs.md +++ b/docs/signing/test-certs.md @@ -3,17 +3,18 @@ id: test-certs title: Using test certificates --- -For development and testing, C2PA Tool, the Rust library, and the CAI prerelease libraries include one or more [test certificates](signing-certs.md#test-certificates) and private keys for use during development. While these test certificates and keys are useful during development and testing, for production deployment you must use your own private key and certificate. - -The [Rust library `sdk/tests/fixtures/certs/` folder](https://github.com/contentauth/c2pa-rs/tree/main/sdk/tests/fixtures/certs) contains certificates and signing keys for many of the supported signature types [described below](prod-cert.mdx#signature-types). - -The CAI prerelease libraries also provide a subset of test certificates in each repository's `tests/fixtures` folder. The Node.js library even provides a [`CreateTestSigner()`](https://github.com/contentauth/c2pa-node/blob/main/docs/README.md#createtestsigner) convenience function to create a local signer instance using the test certificate. - The CAI SDK does not allow you to use a self-signed certificate to sign a manifest. +For initial development and testing, the SDK provides example *test certificates* and private keys: +- The [Rust library `sdk/tests/fixtures/certs/` folder](https://github.com/contentauth/c2pa-rs/tree/main/sdk/tests/fixtures/certs) contains certificates and signing keys for many of the supported [signature types](get-cert.md#signature-types). +- The prerelease libraries (Node.js, Python, and C++) provide a subset of test certificates in each repository's `tests/fixtures` folder. The Node.js library even provides a [`CreateTestSigner()`](https://github.com/contentauth/c2pa-node/blob/main/docs/README.md#createtestsigner) convenience function to create a local signer instance using the test certificate. + :::warning Warning -The test certificates are for use during development and testing only. Do not use them in production! +While these test credentials are useful during development, you must [get your own certificate](get-cert.md) and use your own private key for production deployment. ::: -Although not recommended due to complexity and difficulty, you can create your own certificates for development and testing. Follow the requirements in the C2PA Technical Specification [Credential Types](https://c2pa.org/specifications/specifications/1.4/specs/C2PA_Specification.html#_credential_types) and [Digital Signatures](https://c2pa.org/specifications/specifications/1.4/specs/C2PA_Specification.html#_digital_signatures) sections. +Although not recommended due to complexity and difficulty, you can create your own certificates for development and testing. Follow the requirements in the C2PA Technical Specification [X.509 Certificates](https://c2pa.org/specifications/specifications/2.1/specs/C2PA_Specification.html#x509_certificates) and [Digital Signatures](https://c2pa.org/specifications/specifications/2.1/specs/C2PA_Specification.html#_digital_signatures) sections. + +For manifest claims signed with one of the test certificates, the C2PA Verify tool will display the message "The Content Credential issuer couldn't be recognized." See [Using the Verify tool](../verify.mdx#signing-information) for more information. + diff --git a/docs/verify.mdx b/docs/verify.mdx index 14874770..b144a01c 100644 --- a/docs/verify.mdx +++ b/docs/verify.mdx @@ -166,9 +166,9 @@ For example, suppose you downloaded a file from Adobe Stock and renamed it `my_s } ``` -**Signing information** +#### Signing information -If the Content Credential was signed by a certificate that is NOT on the [known certificate list](verify-known-cert-list), such as the CAI test certificate in the SDK, then Verify displays "Unrecognized" at the top of this section with this notice: +If the Content Credential was signed by a certificate that is NOT on the [known certificate list](verify-known-cert-list), such as one of the SDK's [test certificates](signing/test-certs.md), then Verify displays "Unrecognized" at the top of this section with this notice: import verify_unknown_source from '../static/img/verify-cc-unknown-source.png'; @@ -177,7 +177,11 @@ import verify_unknown_source from '../static/img/verify-cc-unknown-source.png'; style={{ width: '283px', display: 'block', margin: '10px auto' }} /> -However, if the Content Credential was signed by a certificate on the [known certificate list](verify-known-cert-list), then this section displays the name of the issuer of the claim signature from the `signature_info.issuer` property in the active manifest, as shown in the example snippet below. It shows the organization name only if the signing certificate includes the "O" or [Organization Name attribute](https://www.alvestrand.no/objectid/2.5.4.10.html) (OID value 2.5.4.10) in the certificate's distinguished name information. +However, if the Content Credential was signed by a certificate on the [known certificate list](verify-known-cert-list), then this section displays the name of the issuer of the claim signature from the `signature_info.issuer` property in the active manifest, as shown in the example snippet below. + +:::note +This section shows the organization name only if the signing certificate includes the "O" or [Organization Name attribute](https://www.alvestrand.no/objectid/2.5.4.10.html) (OID value 2.5.4.10) in the certificate's distinguished name information. +::: For signers on the known certificate list, this section also displays the time of the claim signature from the `signature_info.time` property in the active manifest, as shown in the example snippet below. The date is converted from UTC to the local time zone. From 593ce069c505ff07945fb13e8083ac3e8a135c7f Mon Sep 17 00:00:00 2001 From: Rand McKinney Date: Wed, 9 Apr 2025 12:19:18 -0700 Subject: [PATCH 07/10] Comments from MF --- docs/getting-started.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/getting-started.mdx b/docs/getting-started.mdx index aee3a161..8fe6a85c 100644 --- a/docs/getting-started.mdx +++ b/docs/getting-started.mdx @@ -76,9 +76,9 @@ A signed digital certificate verifies the authenticity of an entity, such as a s ## Signing and certificates -A manifest attached to an asset contains information about the origin of the asset, such as the name of the tool that created it (for example, Photoshop) and the name of the _actor_ who created or modified it. Each time someone edits or updates the asset using a tool that supports CAI, it adds a new manifest with the actions taken and the certificate of the tool/site; this becomes the _active manifest_, which then references any prior manifests as ingredients. +A manifest attached to an asset contains information about the origin of the asset, such as the name of the tool that created it (for example, Photoshop) and the name of the _actor_ who created or modified it. Then editing the asset using a supporting tool or site adds a new manifest (indicating the actions taken) that is signed with the certificate of the tool/site; this becomes the _active manifest_, which then references any prior manifests as ingredients. -Each manifest is digitally signed with the application's or client's credentials. To enable validation of the credentials, the manifest also includes the signing certificate chain. The "chain" of certificates starts with the certificate from the last tool that signed the manifest (known as the "end-entity") followed by the certificate that signed it, and so on, back to the original CA issuer. A user can trust that the manifest is valid because there is a "trust chain" that goes back to a trusted root certificate authority. That's why you need to acquire a security certificate from a legitimate certificate authority. +Each manifest is digitally signed with the application's or client's credentials. To enable validation of the credentials, the manifest also includes the signing certificate chain. The "chain" of certificates starts with the certificate from the last tool that signed the manifest (known as the "end-entity") followed by the certificate that signed it, and so on, back to the original CA issuer on the trust list. A user can trust that the manifest is valid because there is a "trust chain" that goes back to a trusted root certificate authority. That's why you need to acquire a security certificate from a legitimate certificate authority. In practice, to use a certificate with the CAI SDK, follow this process: From 55973b7f04a981ffbcbed6b9202edb6e8d27de26 Mon Sep 17 00:00:00 2001 From: Rand McKinney Date: Wed, 16 Apr 2025 11:03:20 -0700 Subject: [PATCH 08/10] Input from Maurice, general clarifications --- docs/signing/local-signing.md | 80 ++++++++++++++++++----------------- 1 file changed, 41 insertions(+), 39 deletions(-) diff --git a/docs/signing/local-signing.md b/docs/signing/local-signing.md index 0b12ff00..c3802ca5 100644 --- a/docs/signing/local-signing.md +++ b/docs/signing/local-signing.md @@ -21,32 +21,34 @@ Accessing a private key and certificate directly from the file system is fine du ## Example -Here is an example of generating a C2PA-compliant set of credentials using [GlobalSign](http://globalsign.com/) certificate authority (CA). GlobalSign is just one of many CAs. For a list of some others, see [Getting a security certificate](get-cert.md#certificate-authorities-cas). +[Getting a certificate](get-cert.md) provides a general overview of getting a signing certificate from a certificate authority (CA). + +Here is an example of getting signing credentials using [GlobalSign](http://globalsign.com/) certificate authority (CA) and then using them with C2PA Tool. GlobalSign is just one of many CAs. For a list of some others, see [Getting a security certificate](get-cert.md#certificate-authorities-cas). :::note -This example uses an inexpensive personal certificate, which is fine for development and testing, but for production use an enterprise certificate is strongly recommended. An enterprise certificate is required for [Verify](https://verify.contentauthenticity.org/) to display your organization name when for signed assets. +This example uses an inexpensive personal certificate, which is fine for development and testing, but in production, an enterprise certificate is strongly recommended. An enterprise certificate is required for [Verify](https://verify.contentauthenticity.org/) to display your organization name when for signed assets. ::: -### Step 1: Purchase credentials +### 1. Purchase credentials -This example uses a [PersonSign1](https://shop.globalsign.com/en/secure-email) certificate from GlobalSign that contains KU and EKU values required to sign C2PA manifests. +The following is an example of using a [PersonSign1](https://shop.globalsign.com/en/secure-email) certificate from GlobalSign that contains KU and EKU values required to sign C2PA manifests. -Follow the instructions to purchase and download your `.pfx` file. This file is a PKCS12 container that holds your certificate chain and private signing key. Other certificate providers may have alternate ways of providing your private key and certificate and may include only the end-entity certificate and so you must manually download the rest of the certificate chain. +Follow the CA's instructions to purchase and download your `.pfx` file. This file is a PKCS12 container that holds your certificate chain and private signing key. Other certificate providers may have alternate ways of providing your private key and certificate and may include only the end-entity certificate and so you must manually download the rest of the certificate chain. The rest of this tutorial uses OpenSSL (a set of cryptographic utilities). If OpenSSL is not installed on your system, see [OpenSSL](https://www.openssl.org/source/) for the source distribution or the [list of unofficial binary distributions](https://wiki.openssl.org/index.php/Binaries). -### Step 2: Extract the certificate and key +### 2. Extract credentials To work with the certificate, you need to extract it. When the CAI SDK adds Content Credentials to an asset, it incorporates the certificate (including the associated public key) into the manifest. Use the commands below to extract the key and certificate chain. If prompted, enter the password that was used to generate the `.pfx` file. :::tip Make sure you are using a recent version of OpenSSL. -:::tip +::: #### Troubleshooting errors -In this step, OpenSSL may report errors when extracting the key or certificate chain. In many cases, if OpenSSL generates the output file, you can ignore the messages. However, in some cases you may need to add `-legacy` to the command for it to work properly. +In this step, OpenSSL may report errors when extracting the key or certificate chain. In many cases, if OpenSSL generates the output file, you can ignore the messages. For example, the following error message means the `.pfx` was encrypted with an older standard: @@ -66,50 +68,50 @@ openssl pkcs12 -in mycertfile.pfx -nocerts -out mykey.pem -nodes Check to make sure the above command generated a `.pem` file and it's not an empty file. For more information, see [Troubleshooting errors](#troubleshooting-errors) above. ::: -#### Extract the certificate chain +#### Extract certificate chain -For many certificate providers, the `.pfx` file contains not just your certificate but the complete certificate trust chain. When the `.pfx` file does not contain the certificate chain, you can obtain it from your provider. +For many certificate providers, the `.pfx` file contains not just your certificate but the complete certificate trust chain, which you can extract with a command like this: ```shell -openssl pkcs12 -in mycertfile.pfx -nokeys -out mycerts.pem +openssl pkcs12 -in mycertfile.pfx -nokeys -out mycerts.pub ``` -### Step 3: Use credentials with C2PA Tool +When the `.pfx` file does not contain the certificate chain, you can obtain it from your provider. + +### 3. Determine signature algorithm + +To use the credentials extracted above you must know the signature types they support. Typically, you'll already know this information or the certificate provider will provide it. -To use the credentials extracted above you must know the signature types they support. Typically, the certificate provider will provide this information. If it is not, enter this OpenSSL command to dump certificate information: +You can also enter this OpenSSL command to dump information about the public key used with the certificate: ```shell -openssl x509 -inform PEM -in mycerts.pem -text +openssl x509 -inform PEM -in mycerts.pub -text ``` -This command produces a text summary of the certificate properties, as shown in the example below. Look for a line containing `Signature Algorithm`. See the table above to determine the corresponding signature type. For this example with a certificate issued by GlobalSign, `Signature Algorithm: sha256WithRSAEncryption` corresponds to the PS256 signature type. +Where `mycerts.pub` is the file containing the certificate chain from signing certificate to the last certificate before the root CA, concatenated. + +This command produces a text summary of the certificate properties, as shown in the example below. Look for a line containing `Signature Algorithm`. The public key indicates the signature algorithm used. See the table in [Getting a certificate](get-cert.md#signature-types) to determine the corresponding signature type. + +For this example with a certificate issued by GlobalSign, `Signature Algorithm: sha256WithRSAEncryption` corresponds to the PS256 signature type. ``` Certificate: - Data: - Version: 3 (0x2) - Serial Number: - 73:0d:01:c3:04:06:62:e4:60:0a:0b:0c - Signature Algorithm: sha256WithRSAEncryption - Issuer: C = BE, O = GlobalSign nv-sa, CN = GlobalSign GCC R3 PersonalSign 1 CA 2020 - Validity - Not Before: Oct 13 13:33:02 2022 GMT - Not After : Oct 14 13:33:02 2023 GMT - Subject: CN = someuser@someemail.com, emailAddress = someuser@someemail.com - Subject Public Key Info: - Public Key Algorithm: rsaEncryption - Public-Key: (2048 bit) -. -. -. + Data: + Version: 3 (0x2) + Serial Number: + 74:72:be:13:0c:8f:bf:c4:81:56:f7:5f:35:24:0e:9a:9b:8e:9b:5b + Signature Algorithm: sha256WithRSAEncryption +... ``` +### 4. Test with C2PA Tool + You now have all the needed information to configure C2PA Tool for manifest signing. Edit your [manifest store file](../c2patool/docs/manifest.md) to add the following fields that are specific to C2PA Tool: ```json "alg": "ps256", "private_key": "mykey.pem", -"sign_cert": "mycerts.pem" +"sign_cert": "mycerts.pub" ``` The `private_key` and `sign_cert` properties must be full paths to the key and certificate chain files generated above. @@ -120,13 +122,13 @@ You can now use C2PA Tool [to add a manifest to an image or other asset file](.. c2patool -m my_manifest.json -o signed_image.jpg my_image.jpg ``` -The example above uses the information in `my_manifest.json` to add a new manifest to output `signed_image.jpg` using source `my_image.jpg`. The manifest will be signed using the PS256 signature algorithm with private key `mykey.pem`. The manifest will contain the trust chain specified in `mycerts.pem`. +The example above uses the information in `my_manifest.json` to add a new manifest to output `signed_image.jpg` using source `my_image.jpg`. The manifest will be signed using the PS256 signature algorithm with private key `mykey.pem`. The manifest will contain the trust chain specified in `mycerts.pub`. :::warning This example accesses the private key and certificate directly from the file system, which is fine during development, but is not secure for production use. For more information, see [Using a certificate in production](prod-cert.mdx). ::: -### Confirm it worked +### 4. Confirm it worked Use C2PA Tool to confirm that you successfully signed the asset. Enter a command like this: @@ -139,13 +141,13 @@ This command displays the manifest attached to `signed_image.jpg` and should inc ```json ... "signature_info": { - "cert_serial_number": "012345678901234567890123456789", - "time": "2023-11-02T17:18:14+00:00" - }, - "label": "urn:uuid:0b9bc2b8-6d66-4258-9fed-694c30abcdef" + "cert_serial_number": "012345678901234567890123456789", + "time": "2023-11-02T17:18:14+00:00" +}, + "label": "urn:uuid:0b9bc2b8-6d66-4258-9fed-694c30abcdef" ... ``` :::info -You can also use [Verify](https://contentcredentials.org/verify) to confirm that your image was signed, but if you used a personal certificate (not an organization certificate) then Verify won't show detailed information about the credential used. +You can also use [Verify](https://contentcredentials.org/verify) to confirm that your image was signed, but if you used a personal certificate (not an organization certificate) then [Verify won't show the organization name](get-cert.md#organization-name) and if your certificate is not on the [known certificate list](../trust-list.mdx), Verify [displays the message](../verify.mdx#title-and-signing-information) "The Content Credential issuer couldn't be recognized...." ::: From 88dc56a7e47d3a9f83bf36074dcd2364c87bcbca Mon Sep 17 00:00:00 2001 From: Rand McKinney Date: Wed, 16 Apr 2025 13:07:42 -0700 Subject: [PATCH 09/10] change openssl output example to show cert alg per Maurice --- docs/signing/local-signing.md | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/docs/signing/local-signing.md b/docs/signing/local-signing.md index c3802ca5..7688619c 100644 --- a/docs/signing/local-signing.md +++ b/docs/signing/local-signing.md @@ -95,13 +95,21 @@ This command produces a text summary of the certificate properties, as shown in For this example with a certificate issued by GlobalSign, `Signature Algorithm: sha256WithRSAEncryption` corresponds to the PS256 signature type. ``` -Certificate: - Data: - Version: 3 (0x2) - Serial Number: - 74:72:be:13:0c:8f:bf:c4:81:56:f7:5f:35:24:0e:9a:9b:8e:9b:5b - Signature Algorithm: sha256WithRSAEncryption -... +Validity + Not Before: Jun 10 18:46:28 2022 GMT + Not After : Aug 26 18:46:28 2030 GMT +Subject: C=US, ST=CA, L=Somewhere, O=C2PA Test Signing Cert, OU=FOR TESTING_ONLY, CN=C2PA Signer +Subject Public Key Info: + Public Key Algorithm: rsassaPss + Public-Key: (4096 bit) + Modulus: + ... + Exponent: 65537 (0x10001) + PSS parameter restrictions: + Hash Algorithm: SHA2-256 + Mask Algorithm: MGF1 with SHA2-256 + Minimum Salt Length: 32 + Trailer Field: 0x1 (default) ``` ### 4. Test with C2PA Tool From 7ed60225f8d140aa63d848205143e938ee50e5e7 Mon Sep 17 00:00:00 2001 From: Rand McKinney Date: Thu, 17 Apr 2025 09:14:11 -0700 Subject: [PATCH 10/10] Clarify sig alg info --- docs/signing/local-signing.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/signing/local-signing.md b/docs/signing/local-signing.md index 7688619c..03c26db3 100644 --- a/docs/signing/local-signing.md +++ b/docs/signing/local-signing.md @@ -90,9 +90,9 @@ openssl x509 -inform PEM -in mycerts.pub -text Where `mycerts.pub` is the file containing the certificate chain from signing certificate to the last certificate before the root CA, concatenated. -This command produces a text summary of the certificate properties, as shown in the example below. Look for a line containing `Signature Algorithm`. The public key indicates the signature algorithm used. See the table in [Getting a certificate](get-cert.md#signature-types) to determine the corresponding signature type. +This command produces a text summary of the certificate properties, as shown in the example below. Look for a line containing `Public Key Algorithm` since the public key indicates the signature algorithm used. See the table in [Getting a certificate](get-cert.md#signature-types) to determine the corresponding signature type. -For this example with a certificate issued by GlobalSign, `Signature Algorithm: sha256WithRSAEncryption` corresponds to the PS256 signature type. +For this example with a certificate issued by GlobalSign, `Public Key Algorithm: rsassaPss` corresponds to the "RSASSA-PSS with SHA-256" or `sha256WithRSAEncryption` signature algorithm. A example snippet of this output looks something like this: ``` Validity