# 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](/peer-to-peer/0052.md) identity certificates. We define a set of additional messages that extend the [BRC-1](/wallet/0001.md) 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](/peer-to-peer/0052.md) 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](/peer-to-peer/0052.md) certificates, enabling wider adoption and integration of [BRC-52](/peer-to-peer/0052.md) certificates within the ecosystem.

## Status Note

BRC-53 is historical as an application-to-wallet method set. Current wallet certificate behavior is specified by [BRC-100](/wallet/0100.md) and [BRC-52](/peer-to-peer/0052.md). New implementations use `acquireCertificate`, `listCertificates`, `proveCertificate`, and `relinquishCertificate`; the older `createCertificate` and `findCertificates` naming is deprecated.

## Specification

We define two new sets of messages to be sent over the abstract [BRC-1](/wallet/0001.md) messaging layer:

### Certificate Creation Request

An application may request a wallet to create a [BRC-52](/peer-to-peer/0052.md) certificate by providing the following parameters:

| Field                | Description                                                                       |
| -------------------- | --------------------------------------------------------------------------------- |
| `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](/wallet/0002.md) 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](/peer-to-peer/0052.md) 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:

| Field         | Description                                                                                                                                                                                  |
| ------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `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:

```json
{
  "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](/peer-to-peer/0052.md) certificate by providing the following parameters:

| Field                       | Description                                                                 |
| --------------------------- | --------------------------------------------------------------------------- |
| `certificate`               | The [BRC-52](/peer-to-peer/0052.md) 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](/peer-to-peer/0052.md)) 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](/peer-to-peer/0052.md) 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:

| Field         | Description                                                                                                                                                                             |
| ------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `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:

```json
{
  "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](/peer-to-peer/0031.md) 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](/peer-to-peer/0031.md) 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](/peer-to-peer/0052.md) certificate, if the signing process is successful.

## Implementations

These processes are represented in current form by `bsv-blockchain/ts-sdk` BRC-100 certificate methods and `bsv-blockchain/wallet-toolbox` certificate storage and permission behavior. Legacy `createCertificate` references are retained only for historical context.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://bsv.brc.dev/wallet/0053.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
