Certificate Creation and Revelation

Ty Everett (ty@projectbabbage.com)

Abstract

We define methods for an application to request that a wallet create and prove BRC-52 identity certificates. We define a set of additional messages that extend the BRC-1 application-to-wallet messaging layer with this functionality. We specify the functionality to be performed by the wallet as part of these processes, including a standard methodology for wallets to contact identity certificate certifiers over HTTP and carry out the signing of these documents. To keep users in control over how their data is processed and used, we allow for the wallet to obtain user consent prior to carrying out these operations.

Motivation

The BRC-52 identity certificate standard provides a decentralized, privacy-centric solution to digital identity, allowing users to selectively reveal their identity data. However, without a standard method for applications to create and prove these certificates, wallet support will be limited. BRC-53 provides a set of standardized methods for applications to request and interact with BRC-52 certificates, enabling wider adoption and integration of BRC-52 certificates within the ecosystem.

Specification

We define two new sets of messages to be sent over the abstract BRC-1 messaging layer:

Certificate Creation Request

An application may request a wallet to create a BRC-52 certificate by providing the following parameters:

FieldDescription

certificateType

The type of certificate to create.

fieldObject

An object containing the fields to be added to the certificate.

certifierUrl

The URL of the certifier responsible for signing the certificate.

certifierPublicKey

The public identity key of the certifier responsible for signing the certificate.

The wallet will then carry out the following steps:

  1. Initialize a BRC-53 client with the primary identity key of the wallet.

  2. Generate a client nonce.

  3. Request the validationKey and serialNumber from the certifier by making a BRC-53-enabled HTTPS POST request to the certifierUrl's /initialRequest endpoint with the client nonce.

  4. Validate the received serialNumber and validationKey using the client and server nonces.

  5. Encrypt the fields of the fieldObject using BRC-2 encryption and store the concealed fields and encrypted field revelation keys in the fields and keyring objects, respectively.

  6. Create a Certificate Signing Request (CSR) containing the certificate type, nonces, validation key, serial number, fields, and keyring.

  7. Send the CSR to the certifier's /signCertificate endpoint via an HTTP POST request.

  8. Receive and verify the signed certificate's authenticity.

  9. Store the signed certificate in the wallet's data store (how the wallet stores its data is beyond the scope of this specification).

Certificate Creation Response

The response sent back over the abstract messaging layer from the wallet to the application will constitute a valid, fully-signed BRC-52 identity certificate with no keyring.

Certificate Creation Error

If the Bitcoin wallet is unable to fulfill the Certificate Creation Request for any reason, we specify that it should respond with a JSON-formatted Certificate Creation Error. The fields for the object are specified as follows:

FieldDescription

status

This should always be a string comprising "error".

code

A machine-readable error code. Extensions to this standard can define specific error codes and standardize additional fields. Codes are strings, for example "ERR_CERTIFIER_REJECTED_CSR".

description

All errors must have a human-readable description field that describes the error. This allows the application to represent the error for the user.

One example of a Certificate Creation Error is given below:

{
  "status": "error",
  "code": "ERR_CERTIFIER_REJECTED_CSR",
  "description": "The certifier has rejected the CSR and refused to sign the certificate."
}

Certificate Proof Request

An application may request a wallet to prove a BRC-52 certificate by providing the following parameters:

FieldDescription

certificate

The BRC-52 certificate to be proven.

fieldsToReveal

An array containing the names of the fields to be revealed to the verifier.

verifierPublicIdentityKey

The public identity key of the verifier.

The wallet will then carry out the following steps:

  1. Verify the authenticity of the provided certificate.

  2. Ensure that the application and the verifier have been granted access to the requested certificate fields (optional permissions checks).

  3. Decrypt the encrypted field revelation keys using the wallet's primary identity key.

  4. Encrypt the decrypted field revelation keys for the verifier using the verifierPublicIdentityKey.

  5. Add the encrypted field revelation keys to the certificate field revelation keyring (as defined in BRC-52) object.

  6. Attach the field revelation keyring to the certificate.

  7. Return the certificate with the attached field revelation keyring for presentation to the verifier for field examination.

Certificate Proof Response

The response sent back over the abstract messaging layer from the wallet to the application will constitute a valid, fully-signed BRC-52 identity certificate with the attached field revelation keyring for the verifier.

Certificate Proof Error

If the Bitcoin wallet is unable to fulfill the Certificate Proof Request for any reason, we specify that it should respond with a JSON-formatted Certificate Proof Error. The fields for the object are specified as follows:

FieldDescription

status

This should always be a string comprising "error".

code

A machine-readable error code. Extensions to this standard can define specific error codes and standardize additional fields. Codes are strings, for example "ERR_PERMISSION_DENIED".

description

All errors must have a human-readable description field that describes the error. This allows the application to represent the error for the user.

One example of a Certificate Proof Error is given below:

{
  "status": "error",
  "code": "ERR_PERMISSION_DENIED",
  "description": "The user denied the request to reveal these fields to this verifier at this time."
}

Wallet-to-Certifier Interface

The wallet and certifier communicate in a standard way over a BRC-31 protected HTTPS interface to facilitate the requesting and signing of a certificate. Here, we specify the requirements and fields for these communications.

We require that the wallet engages in the BRC-31 authentication process with the certifier, and we further require that the wallet authenticate using the same key which is the subject of the certificate issuance process. This provides a way for the certifier to know that the person making the request is the person who will be receiving the identity certificate.

Initial Request

The wallet initiates the communication with the certifier by sending an initial request. The initial request includes a client nonce, generated randomly by the wallet. The request is sent to the /initialRequest endpoint using the HTTP POST method.

Request fields

  • clientNonce: A randomly generated 32-byte string in base64 format.

The certifier processes the initial request and generates two nonces: serialNonce and validationNonce. The certifier calculates the serialNumber and validationKey by hashing the concatenation of clientNonce with the respective nonces. The certifier then returns these values in the response.

Response fields

  • validationKey: A base64 encoded string calculated by hashing the concatenation of clientNonce and validationNonce using SHA256.

  • serialNumber: A base64 encoded string calculated by hashing the concatenation of clientNonce and serialNonce using SHA256.

  • validationNonce: A base64 encoded nonce generated by the certifier.

  • serialNonce: A base64 encoded nonce generated by the certifier.

Certificate Signing Request

After receiving and validating the values from the initial request, the wallet creates a Certificate Signing Request (CSR) and sends it to the /signCertificate endpoint using the HTTP POST method.

Request fields

  • messageType: The string "certificateSigningRequest".

  • type: The type of certificate to create.

  • clientNonce: The client nonce generated by the wallet during the initial request.

  • serverSerialNonce: The serial nonce received from the certifier in the initial request.

  • serverValidationNonce: The validation nonce received from the certifier in the initial request.

  • validationKey: The validation key received from the certifier in the initial request.

  • serialNumber: The serial number received from the certifier in the initial request.

  • fields: An object containing encrypted fields of the certificate.

  • keyring: An object containing encrypted field revelation keys, revealed from the subject to the certifier.

The certifier processes the CSR and signs the certificate using its private signing key. The signed certificate is then returned to the wallet in the response.

Response fields

  • status: The status of the signing process, either "success" or "error".

  • description: A description of the error, if applicable.

  • code: An error code, if applicable.

  • certificate: The signed BRC-52 certificate, if the signing process is successful.

Implementations

These processes have been implemented into the createCertificate and proveCertificate functions of the Babbage SDK. The Computing with Integrity kernel (currently proprietary) implements the wallet-to-certifier communications protocol, and CoolCert implements the certifier side of the protocol.

Last updated