# Peeringhub STI-ACME Server

Peeringhub operates a STI-ACME that is fully complaint to RFC 8555.  Any Stir/Shaken Service Provider can subscribe to Peeringhub's CA service, and gain access to Peeringhub's ACME Server to obtain Stir/Shaken Certificate.&#x20;

{% hint style="info" %}
You will need to have your own OCN and obtain an approved Stir/Shaken Service Provider Status from STI-PA ( iConnectiv ) before you can generate your Stir/Shaken certification.  If you are not sure how to do that, please refer our Step-by-Step Guide at <https://www.linkedin.com/pulse/stir-shaken-compliance-101-deadline-looming-peeringhub-io/?trackingId=PUVz3GbVSRa4Md1iOLBIhw%3D%3D>
{% endhint %}

## Getting Started

Stir/Shaken Service Provider can subscribe to Peeringhub's CA service via Peeringhub's automatic portal.  After you complete online subscription process, your OCN will be whitelisted to Peeringhub's ACME server for automatic issuance of Stir/Shaken certificate.&#x20;

### Guides: Jump right in

Follow our handy guides to get started on the basics as quickly as possible:

{% content-ref url="/pages/NHwioUECeFoAO21XGsCm" %}
[Broken mention](broken://pages/NHwioUECeFoAO21XGsCm)
{% endcontent-ref %}

{% content-ref url="/pages/fklyE590oyJakSy1HQlN" %}
[Generating Certificate](/guides/generating-certificate)
{% endcontent-ref %}

{% content-ref url="/pages/ZADt04l2gpJ1lO54AvNQ" %}
[Getting Support](/guides/getting-support)
{% endcontent-ref %}

{% hint style="info" %}
**Good to know:** Peeringhub's support team can also generate your certificate manually for you.
{% endhint %}

###


# Stir/Shaken Compliance Guide

#### **Step 1 – You Need to Get an Operating Company Number**

The National Extension Carrier Association ([NECA](https://www.neca.org/)) is responsible for distributing Operating Company Numbers (OCNs).

All information for applying for your OCN can be gleaned from their website.

In short, their application process requires you to submit the following:

1\.    Your interconnection agreement with an upstream service provider

2\.    A copy of an invoice with one of your customers

3\.    A state sealed copy of your articles of association

4\.    Other administrative information.

NECA charges a standard fee of $475 for each OCN application. If you need an expedited service with a 3 day turnaround time it costs $600. &#x20;

To start this process, go to <https://www.neca.org/>. Click on the Contact Us page. Locate the helpdesk email and email the helpdesk requesting an application form.  Once you receive the form, you just need to fill it in and provide the requested information.  &#x20;

#### **Step 2 - You Need to Register with the Secure Telephony Industry Public Administrator (STI-PA)**

[Iconectiv](https://iconectiv.com/calling-number-verification-service) is the STI Public Administrator.

You need to register with iconectiv as an authorized carrier, after which you will be provided with a service provider code token.

Registration is simple and can be found on the [iconective policy administrator website](https://authenticate.iconectiv.com/).

You should click on "Getting Started" under Service Provider section:

<figure><img src="/files/vaGMee1vXo4pQnQVyEkZ" alt=""><figcaption></figcaption></figure>

Then, you can click on Begin Registration button and start to fill out the application:

<figure><img src="/files/GsUE5i5TkrfZiOntisf5" alt=""><figcaption></figcaption></figure>

You will be required to submit the following:

·         FCC Form 499A

·         Your OCN

·         Your billing contact details

You will be contacted via email for authorization and further information. &#x20;

It normally takes 1 - 2 days for iconectiv to respond to your online application.  You will be provided with a test plan to fill out.  This test plan is to help you to familiarize yourself with the UI and API provided by iconectiv. &#x20;

If you need help in conducting and filling out the test plan, you can always contact Peeringhub to give you assistance.&#x20;

Once you submit your test plan, your service provider status should be approved very quickly.

Once approved, you will be added to the website, and service providers will be notified of your certification. &#x20;

In-depth documentation on how to register as a Stir/Shaken Service Provider from iConectiv is available [here](https://authenticate.iconectiv.com/sites/authenticate/files/2021-10/Service_Provider_Guidelines_Issue_6.pdf).&#x20;

#### **Step 3 – You Need to Secure a Token**

Peeringhub can help you secure a token from iConective.

Should you prefer to go it on your own, iConective does have a [guideline](https://authenticate.iconectiv.com/sites/authenticate/files/2021-10/RespOrg_Guidelines_Issue_1.pdf) which spells out what you need to do, in which case you will need to:

* Upgrade your software to the necessary spec
* Run performance tests with iConective
* Complete the rest of the STI-PA application process.

&#x20;**Step 4 - Get Yourself a Certificate**

Once you have received your token, you will be required to submit the token and a certificate signing request to the Certifying Authority (CA).

Assuming you have done enough to qualify, the CA will issue you a STIR/SHAKEN certificate. The certificate confirms that you are now fully compliant.

As Peeringhub, we would assist you throughout the process.  You can contact Peeringhub to open an account via email [ca-request@peeringhub.io](http://mailto:ca-request@peeringhub.io/).

**Step 5 – Declare That You Have Complied With STIR/SHAKEN Requirements**

The final step is to change your status to being fully compliant.

You do this by logging into the [FCC's Robocall Mitigation Database](https://fccprod.servicenowservices.com/rmd?id=rmd_welcome) and setting your status to Full STIR/SHAKEN compliance.


# Q and A on STI Test Plan

<table><thead><tr><th width="130.33333333333331">Test Plan ID</th><th width="244">Tes Plan Description</th><th>What To Do </th></tr></thead><tbody><tr><td>STI-PA-TC-005</td><td>SP Portal First Time Login</td><td>Access to http://<a href="http://stg-authenticatereg.iconectiv.com/">stg-authenticatereg.iconectiv.com</a> to check if you can login.  If you can login successfully, then you can specify your test result as "Expected Result was observed."</td></tr><tr><td>STI-PA-TC-006</td><td>CA Portal First Time Login</td><td>Ignore </td></tr><tr><td>STI-PA-TC-007</td><td>SP Portal Normal Login</td><td>Logout from <a href="https://stg-authenticateapp.iconectiv.com/login"> </a><a href="https://stg-authenticateapp.iconectiv.com/login">https://stg-authenticateapp.iconectiv.com/login</a> and attempt to log back into the site again.  If you can login successfully, then you can specify your test result as "Expected Result was observed."</td></tr><tr><td>STI-PA-TC-008</td><td>CA Portal Normal Login</td><td>Ignore </td></tr><tr><td>STI-PA-TC-009</td><td>Password Reset</td><td>Go to  <a href="https://stg-authenticateapp.iconectiv.com/login">https://stg-authenticateapp.iconectiv.com/login</a> and click on "Forgot Password?"  If you are able to change password, then you can specify your test result as "Expected Result was observed."</td></tr><tr><td>STI-PA-TC-012</td><td>Create Additional SP Admin Users</td><td>Login to  <a href="https://stg-authenticateapp.iconectiv.com/login">https://stg-authenticateapp.iconectiv.com/login</a> and go to "User" page.  You should try to create a new Admin User for your Service Provider account.  If you are able to create a new SP Admin User, then you can specify your test result as "Expected Result was observed."</td></tr><tr><td>STI-PA-TC-013</td><td>Create SP API User</td><td>Login to  <a href="https://stg-authenticateapp.iconectiv.com/login">https://stg-authenticateapp.iconectiv.com/login</a> and go to "User" page.  You should try to create a new API User for your Service Provider account.  In the Create User page, there is an option for "API User" and you should select that.  If you are able to create a new SP API User, then you can specify your test result as "Expected Result was observed."</td></tr><tr><td>STI-PA-TC-014</td><td>Add additional SPC to an existing account</td><td>Login to  <a href="https://stg-authenticateapp.iconectiv.com/login">https://stg-authenticateapp.iconectiv.com/login</a> to create a new SPC.</td></tr><tr><td>STI-PA-TC-018</td><td>Add new STI-CA Root Certificate; also includes retrieval of caList</td><td>Ignore</td></tr><tr><td>STI-PA-TC-019</td><td>1) Obtain STI-PA public certificate; 2) Verify caList signature</td><td>Downloading Trust CA List using URL: https://authenticate-api-stg.iconectiv.com/api/v1/ca-list<br> <br> <br></td></tr><tr><td>STI-PA-TC-020</td><td>Remove an STI-CA root certificate; verify caList is updated</td><td>Ignore</td></tr><tr><td>STI-PA-TC-021</td><td>Verify CRL URL is contained in the SPCToken response</td><td>Sending SPC request using URL: https://authenticate-api-stg.iconectiv.com/api/v1/account/211K/token<br></td></tr><tr><td>STI-PA-TC-022</td><td>SP can revoke an STI cerficiate; verify revoked certificate is added to CRL</td><td>Login to <a href="https://stg-authenticateapp.iconectiv.com/login"> </a><a href="https://stg-authenticateapp.iconectiv.com/login">https://stg-authenticateapp.iconectiv.com/login</a> and go to Revoke Certificate page.  You need to verify you can revoke a certificate that you created.  When you signup with Peeringhub, you will be able to use Peeringhub's staging environment to create staging certificate and then use the iConnectiv portal to revoke the created certificate. </td></tr><tr><td>STI-PA-TC-023</td><td>CA can revoke an STI cerficiate; verify revoked certificate is added to CRL</td><td>Ignore</td></tr><tr><td>STI-PA-TC-024</td><td>CRL Download; verify the CRL signature</td><td>Downloading CRL from iConnectiv staging server with the following API: https://authenticate-api-stg.iconectiv.com/download/v1/crl<br></td></tr><tr><td>STI-PA-TC-025</td><td>SPC Token request</td><td>Sending SPC request using the following URL: https://authenticate-api-stg.iconectiv.com/api/v1/account/&#x3C;OCN>/token/  <br></td></tr><tr><td>STI-PA-TC-026</td><td>verify SPC Token JWT; use x5u URL to download the STI-PA public cert</td><td>Validating SPC signature using API : https://authenticate-api-stg.iconectiv.com/download/v1/certificate/certificateId_97574.crt <br><br></td></tr></tbody></table>


# STI-PA-TC-026

verify SPC Token JWT; use x5u URL to download the STI-PA public cert

\== Processing JWT header: {"alg":"ES256","typ":"JWT","x5u":"<https://authenticate-api-stg.iconectiv.com/download/v1/certificate/certificateId\\_97574.crt"}&#x20>;

\== Using x5u: <https://authenticate-api-stg.iconectiv.com/download/v1/certificate/certificateId\\_97574.crt&#x20>;

\== serial=EB19391AA7FB12C8B2E88E8F4826021F&#x20;

\== issuer= /C=US/ST=NJ/L=Bridgewater/O=STI-PA/CN=STI-PA Root Certificate&#x20;

\== subject= /L=Bridgewater/ST=NJ/CN=STI-PA SPC-281K Token/C=US/O=STI-PA&#x20;

\== Using Root CA:&#x20;

\== serial=59DC7495C9F0634912D63D6A3282A155&#x20;

\== issuer= /C=US/ST=NJ/L=Bridgewater/O=STI-PA/CN=STI-PA Root Certificate&#x20;

\== subject= /C=US/ST=NJ/L=Bridgewater/O=STI-PA/CN=STI-PA Root Certificate&#x20;

\== Validating certificate over Root CA: PASSED&#x20;

\== Validating JWT signature: PASSED == Success


# STI-PA-TC-021

Verify CRL URL is contained in the SPCToken response

You can send SPC Token request with the following API:

```
https://authenticate-api-stg.iconectiv.com/api/v1/account/281K/token/
```

Your request data should be as follows:

```
{ "atc": 
  { "tktype": "TNAuthList", 
     "tkvalue": "MAigBhzzMjgxSw==", 
     "ca": false, 
     "fingerprint":  "SHA256 49:55:78:7F:34:14:81:67:99:48:DC:54:21:DA:F4:79:C7:41:29:06:BF:A5:38:DF:9E:03:97:6A:2C:53:CC:3B" 
     }}
```

In the request data, "tktype" and "ca" are fixed value.

You will get back the following data from server:

```
{"status":"success",
"message":"SPC token for spc: 111K is created successfully",
"token":"eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCIsIng1dSI6Imh0dHBzOi8vYXV0aGVudGljYXRlLWFwaS1zdGcuaWNvbmVjdGl2LmNvbS9kb3dubG9hZC92MS9jZXJ0aWZpY2F0ZS9jZXJ0aWZpY2F0ZUlkXzk3NTc0LmNydCJ9.eyJleHAiOjE2ODk5MTkwNjMsImp0aSI6IjUxOTE3NWNiLTY5OTgtNDA3NC05YWVhLTBkYTUxNzVhMTYyMiIsImF0YyI6eyJ0a3R5cGUiOiJUTkF1dGhMaXN0IiwidGt2YWx1ZSI6Ik1BaWdCaFlFTWpneFN3PT0iLCJjYSI6ZmFsc2UsImZpbmdlcnByaW50IjoiU0hBMjU2IDQ5OjU1Ojc4OjdGOjQyOjE3OjgxOjY3Ojk5OjQ4OkRDOjU0OjIxOkRBOkY0Ojc5OkM3OjQxOjI5OjA2OkJGOkE1OjM4OkRGOjlFOjAxOjk3OjZBOjJDOjUzOkNDOjNCIn19.yZsMAjzQ0fBx4hUQBR-E-exUwRHrFn4_utPuSJrraJYjI2K3eCfjNwVuMSCkAx9MQrUofB0d9hmDnZ_AblOCUQ",
"crl":"https://authenticate-api-stg.iconectiv.com/download/v1/crl"}
```

The recovered SPC Token is as follows:

```
{"alg":"ES256","typ":"JWT",
"x5u":"https://authenticate-api-stg.iconectiv.com/download/v1/certificate/certificateId_973374.crt"}
{"exp":1689919063,"jti":"519175cb-6998-4074-9aea-0da5175a1622","atc":{"tktype":"TNAuthList","tkvalue":"MAigBh33jgxSw==",
"ca":false,
"fingerprint":"SHA256 22:33:78:7F:42:17:81:45:99:3:DC:54:21:DA:F4:79:C7:41:29:06:BF:A5:38:DF:9E:01:97:6A:2C:53:CC:3B"}}
                
```

## How to generate "tkvalue"

tkvalue is a base64-encoded X509 extension and you can create it using openssl CLI tool with the following steps:

Step 1: Create ssl .conf file

```
cat << EOF > tnauthlist.conf
asn1=SEQUENCE:tn_auth_list
[tn_auth_list]
field1=EXP:0,IA5:<UPPERCASE OCN>
EOF
```

Step 2: Create extension

```
openssl asn1parse -genconf tnauthlist.conf -noout -out tnauthlist.der
```

Step 3:  Encode

```
cat tnauthlist.der | base64
```

Here is a full example:

```
% cat << EOF > tnauthlist.conf
asn1=SEQUENCE:tn_auth_list
[tn_auth_list]
field1=EXP:0,IA5:818H
EOF

% openssl asn1parse -genconf tnauthlist.conf -noout -out tnauthlist.der

% cat tnauthlist.der | base64
MAigBhYEODE4SA==
```

## How to generate "fingerprint"

Firstly, you need to create a private key using the following command:

```
openssl ecparam -genkey -name prime256v1 -out ./private_key.pem
```

The above command will create your private key and store it in a file called "private\_key.pem."

After you create your own private key, then you can generate fingerprint with the following commands:

```
% openssl ec -pubout -inform PEM -outform DER -in ./private.key.pem 2> /dev/null | openssl sha256 | awk '{ gsub(/.{2}/,"&:",$2); print "SHA256 " toupper(substr($2, 1, length($2) - 1))  }'

SHA256 D8:FC:D2:1E:52:7E:85:A5:DB:34:1F:0A:0A:67:17:55:70:9A:A1:50:34:16:BF:E6:E5:AB:AD:84:73:73:E8:A8
```

<br>


# STI-PA-TC-019

1\) Obtain STI-PA public certificate; 2) Verify caList signature

To obtain the list of CA List Signature, you use this API:

```
https://authenticate-api-stg.iconectiv.com/api/v1/ca-list

```

You should get back response like this:

```
{"status":"success","message":"STI-CA trustList request is successful","caList":"eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCIsIng1dSI6Imh0dHBzOi8vYXV0aGVudGljYXRlLWFwaS1zdGcuaWNvbmVjdGl2LmNvbS9kb3dubG9hZC92MS9jZXJ0aWZpY2F0ZS9jZXJ0aWZpY2F0ZUlkXzE1NS5jcnQifQ.eyJ2ZXJzaW9uIjoiMS4wIiwic2VxdWVuY2UiOjg3NCwiZXhwIjoxNjYwNzE4ODk3LCJ0cnVzdExpc3QiOlsiLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tXG5NSUlDQmpDQ0FheWdBd0lCQWdJUVdkeDBsY253WTBrUzFqMXFNb0toVlRBS0JnZ3Foa2pPUFFRREFqQmpNUXN3XG5DUVlEVlFRR0V3SlZVekVMTUFrR0ExVUVDQXdDVGtveEZEQVNCZ05WQkFjTUMwSnlhV1JuWlhkaGRHVnlNUTh3XG5EUVlEVlFRS0RBWlRWRWt0VUVFeElEQWVCZ05WQkFNTUYxTlVTUzFRUVNCU2IyOTBJRU5sY25ScFptbGpZWFJsXG5NQjRYRFRFNU1UQXdOREV4TkRFeU0xb1hEVEk1TVRBd05ERXlOREV5TTFvd1l6RUxNQWtHQTFVRUJoTUNWVk14XG5DekFKQmdOVkJBZ01BazVLTVJRd0VnWURWUVFIREF0Q2NtbGtaMlYzWVhSbGNqRVBNQTBHQTFVRUNnd0dVMVJKXG5MVkJCTVNBd0hnWURWUVFEREJkVFZFa3RVRUVnVW05dmRDQkRaWEowYVdacFkyRjBaVEJaTUJNR0J5cUdTTTQ5XG5BZ0VHQ0NxR1NNNDlBd0VIQTBJQUJDWWxrWmZ0alRKNUxqbktTRzRFZDRXZGpzMnlBNGk2SXNyS0VwNTVyb0ttXG5ZcGJuaTJNV1M3Q0IxWE16TzYyaC84bSs2dHV1OXpEc3g3N2NzRVhwYnBhalFqQkFNQThHQTFVZEV3RUIvd1FGXG5NQU1CQWY4d0hRWURWUjBPQkJZRUZBNWtQUExZK1ppSG9lcmRFdUhwdnZmWWJQMDhNQTRHQTFVZER3RUIvd1FFXG5Bd0lCaGpBS0JnZ3Foa2pPUFFRREFnTklBREJGQWlFQTZIeWR3cTFHMnFWOVFGUmZHdHBTSTJla1o3K05uUWV5XG5zTEFUdlRZVU9wOENJQ2FyOGcxSEpiL0V2akk1THc1U3UwWHFBelVYcFJ5WHI2ZWhMdldlUi9OT1xuLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLSIsIi0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLVxuTUlJQ0JqQ0NBYXVnQXdJQkFnSUNEaDh3REFZSUtvWkl6ajBFQXdJRkFEQk5NUXN3Q1FZRFZRUUdFd0pWVXpFVVxuTUJJR0ExVUVDaE1MVkUxUFFrbE1SUzFWVTBFeEtEQW1CZ05WQkFNVEgxUk5UMEpKVEVVdFVGSlBSQzFTVDA5VVxuTFZOVVNWSlRTRUZMUlU0dFJVTXdIaGNOTVRrd09URTVNakF4TWpBeVdoY05ORFF3T1RFNE1qQXhNakF5V2pCTlxuTVFzd0NRWURWUVFHRXdKVlV6RVVNQklHQTFVRUNoTUxWRTFQUWtsTVJTMVZVMEV4S0RBbUJnTlZCQU1USDFSTlxuVDBKSlRFVXRVRkpQUkMxU1QwOVVMVk5VU1ZKVFNFRkxSVTR0UlVNd1dUQVRCZ2NxaGtqT1BRSUJCZ2dxaGtqT1xuUFFNQkJ3TkNBQVNrQnZCNC92OUs2ZTJnSkVTaVBMRlRXMEhXOXUxdEpWYUQrQUY3U0xrRlVwSGo4OWxxVDVtK1xudjNQb0JidDZOakVhY3NsNm43cTM3cEdmYnJBOEp6eGJvM2t3ZHpBZkJnTlZIU01FR0RBV2dCU0Q2VzZicE9PdFxuODZNZk9EUXdubjZoUzdzSjF6QWRCZ05WSFE0RUZnUVVnK2x1bTZUanJmT2pIemcwTUo1K29VdTdDZGN3RGdZRFxuVlIwUEFRSC9CQVFEQWdHbU1CRUdBMVVkSUFRS01BZ3dCZ1lFVlIwZ0FEQVNCZ05WSFJNQkFmOEVDREFHQVFIL1xuQWdFQk1Bd0dDQ3FHU000OUJBTUNCUUFEUndBd1JBSWdUaW1IWkVtREoxcVkrTm9PRTB2V2piRkdDL0FCQjF2U1xua0lGbkFNdS94YVVDSUVGOXlQdzNtRkMwVEE0RGlQdFI0bWQ1MTZ5WjgybUxuVy8rZWtkVTFiR2hcbi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0iLCItLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS1cbk1JSUNVRENDQWZXZ0F3SUJBZ0lKQUprZ3lHZ3hSNGtOTUFvR0NDcUdTTTQ5QkFNQ01JR0tNUXN3Q1FZRFZRUUdcbkV3SlZVekVUTUJFR0ExVUVDQXdLUTJGc2FXWnZjbTVwWVRFU01CQUdBMVVFQnd3SlUyRnVJRVJwWldkdk1Sc3dcbkdRWURWUVFLREJKVFlXNXpZWGtnUTI5eWNHOXlZWFJwYjI0eEVqQVFCZ05WQkFzTUNWTmhibk5oZVNCRFFURWhcbk1COEdBMVVFQXd3WVUwaEJTMFZPSUZOaGJuTmhlU0JTYjI5MElFTkJJRlZUTUI0WERUSXdNRGd5TVRBeE1qSXdcbk5Gb1hEVFF3TURneE5qQXhNakl3TkZvd2dZb3hDekFKQmdOVkJBWVRBbFZUTVJNd0VRWURWUVFJREFwRFlXeHBcblptOXlibWxoTVJJd0VBWURWUVFIREFsVFlXNGdSR2xsWjI4eEd6QVpCZ05WQkFvTUVsTmhibk5oZVNCRGIzSndcbmIzSmhkR2x2YmpFU01CQUdBMVVFQ3d3SlUyRnVjMkY1SUVOQk1TRXdId1lEVlFRRERCaFRTRUZMUlU0Z1UyRnVcbmMyRjVJRkp2YjNRZ1EwRWdWVk13V1RBVEJnY3Foa2pPUFFJQkJnZ3Foa2pPUFFNQkJ3TkNBQVNPa1Rxb2dHUXNcbjg4ZklaRWtTV0ZPckJpUUhoVjEwWWVuWnI4NkJta1liMTMxblBFOEFKVkYzZGlvamFmUVlNS0tGZFA4cUE0aHNcbnNCeFc5eVc5aUc4UG8wSXdRREFkQmdOVkhRNEVGZ1FVQ3E3L2x2Q2JRYU85MzMyL2JkcEZxT2dFRzdrd0R3WURcblZSMFRBUUgvQkFVd0F3RUIvekFPQmdOVkhROEJBZjhFQkFNQ0FnUXdDZ1lJS29aSXpqMEVBd0lEU1FBd1JnSWhcbkFQVFRtMHd3eVZqTHJyd2wyMGtiT2dOTU5WakF3THRjdjZDbnhXaG9UMjB1QWlFQXVjOXJCaDR1K3M5R0JLVTZcblIyUFhGblE3Vmlac1p5WjV1eXJQOFZZL2Rqbz1cbi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0iLCItLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS1cbk1JSUNERENDQWJLZ0F3SUJBZ0lRWkh1UThHenBoNTlyOXNySzRGVm93REFLQmdncWhrak9QUVFEQWpCbU1Rc3dcbkNRWURWUVFHRXdKVlV6RVRNQkVHQTFVRUNoTUtWSEpoYm5OT1pYaDFjekVpTUNBR0ExVUVDeE1aUTJWeWRHbG1cbmFXTmhkR2x2YmlCQmRYUm9iM0pwZEdsbGN6RWVNQndHQTFVRUF4TVZWSEpoYm5OT1pYaDFjeUJTYjI5MElFTkJcbklFY3lNQjRYRFRJd01URXdOREF3TURBd01Gb1hEVFExTVRFd016SXpOVGsxT1Zvd1pqRUxNQWtHQTFVRUJoTUNcblZWTXhFekFSQmdOVkJBb1RDbFJ5WVc1elRtVjRkWE14SWpBZ0JnTlZCQXNUR1VObGNuUnBabWxqWVhScGIyNGdcblFYVjBhRzl5YVhScFpYTXhIakFjQmdOVkJBTVRGVlJ5WVc1elRtVjRkWE1nVW05dmRDQkRRU0JITWpCWk1CTUdcbkJ5cUdTTTQ5QWdFR0NDcUdTTTQ5QXdFSEEwSUFCT1JGQ2pVZlg4MUpYTmNNRlN6cG9mVEpzbTlNQU9NVXhEbHpcbi9hREs5dnpqaVpmbFVrZFpBOVoxZ3ZlU2NrNVBteU14bUlpT0oyVFN3OTZibk9qOTZvZWpRakJBTUE4R0ExVWRcbkV3RUIvd1FGTUFNQkFmOHdEZ1lEVlIwUEFRSC9CQVFEQWdFR01CMEdBMVVkRGdRV0JCUjNuVit4UHZvOVUyWGZcbnJWZ0JSdkcwYm1KbXRqQUtCZ2dxaGtqT1BRUURBZ05JQURCRkFpQWVNT3NHaWZUWVFsOHRiUVRibnM4cTUwUXZcbjJCaTNLZ0x2SkRCRmpFT0Nkd0loQU9kMkVoNXYzb3hRdmpvVE9yaFBBVDFGWGVEMzR2K3JMN2lkTDRMQmtrZ2hcbi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0iLCItLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS1cbk1JSUNEVENDQWJTZ0F3SUJBZ0lVU1J0R0tLd011MitpRDQ1VjdLUFEwdG00S3Ewd0NnWUlLb1pJemowRUF3SXdcblpURUxNQWtHQTFVRUJoTUNWVk14RGpBTUJnTlZCQWdNQlZSbGVHRnpNUkV3RHdZRFZRUUhEQWhHZENCWGIzSjBcbmFERVJNQThHQTFVRUNnd0lSMEpUUkZSbFkyZ3hJREFlQmdOVkJBTU1GMGRDVTBSVVpXTm9JRk5JUVV0RlRpQlNcbmIyOTBJRU5CTUI0WERUSXhNRFV3TlRFNU1EVXlNMW9YRFRReE1EUXpNREU1TURVeU0xb3daVEVMTUFrR0ExVUVcbkJoTUNWVk14RGpBTUJnTlZCQWdNQlZSbGVHRnpNUkV3RHdZRFZRUUhEQWhHZENCWGIzSjBhREVSTUE4R0ExVUVcbkNnd0lSMEpUUkZSbFkyZ3hJREFlQmdOVkJBTU1GMGRDVTBSVVpXTm9JRk5JUVV0RlRpQlNiMjkwSUVOQk1Ga3dcbkV3WUhLb1pJemowQ0FRWUlLb1pJemowREFRY0RRZ0FFcThSWVUzV2NBd2dZSXJ4ZXErZmRIUzlCQm5CWWdYMkxcbmdNbS9iTHhJUmVGeklQK0h3YUdVMVI5VXFESXJ5ZHR0TGdyL2RFTWdaYVhKK1Z5RkVld0xBYU5DTUVBd0hRWURcblZSME9CQllFRkpjWHJDUTZMei9SdUN6SmYzMG9aZ29TUGpLNk1BOEdBMVVkRXdFQi93UUZNQU1CQWY4d0RnWURcblZSMFBBUUgvQkFRREFnSUVNQW9HQ0NxR1NNNDlCQU1DQTBjQU1FUUNJRUtpUFF2bGFBYlhXYmdUQTMweUxYSFdcbnZZd2RlNWJLTmJnNkY5OFg4cE5WQWlBS01aZEZ4eElWSFhmS21Scm1OL0dLYlBSN3AyOWlOKysyZXV2WDA0U1dcbjhRPT1cbi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0iLCItLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS1cbk1JSUNCekNDQWE2Z0F3SUJBZ0lRU0pVLzFldmNiYjNCbEdnc21veEt0akFLQmdncWhrak9QUVFEQWpCa01Rc3dcbkNRWURWUVFHRXdKVlV6RVpNQmNHQTFVRUNoTVFWSEpoYm5OT1pYaDFjeXdnU1c1akxqRVBNQTBHQTFVRUN4TUdcblUwaEJTMFZPTVNrd0p3WURWUVFERXlCVWNtRnVjMDVsZUhWekxDQkpibU11SUZOSVFVdEZUaUJTYjI5MElFTkJcbk1UQWVGdzB5TVRBNE1qQXdNREF3TURCYUZ3MDBNVEE0TVRreU16VTVOVGxhTUdReEN6QUpCZ05WQkFZVEFsVlRcbk1Sa3dGd1lEVlFRS0V4QlVjbUZ1YzA1bGVIVnpMQ0JKYm1NdU1ROHdEUVlEVlFRTEV3WlRTRUZMUlU0eEtUQW5cbkJnTlZCQU1USUZSeVlXNXpUbVY0ZFhNc0lFbHVZeTRnVTBoQlMwVk9JRkp2YjNRZ1EwRXhNRmt3RXdZSEtvWklcbnpqMENBUVlJS29aSXpqMERBUWNEUWdBRUpXcVp1bmwzK1RPdkc1djFCN3FBOC90L0xMaEFUeFNxWnp0OEVPVlhcbjY3dHJWL1U5VW9jWmM4VTZNVm0zeVJnME1TRW84RC8zQnI0bzduSlRIemtjTGFOQ01FQXdEd1lEVlIwVEFRSC9cbkJBVXdBd0VCL3pBT0JnTlZIUThCQWY4RUJBTUNBQVl3SFFZRFZSME9CQllFRkpxTVNobWZaTVJlTTdZcGpCYktcbnA3Z1FTeTViTUFvR0NDcUdTTTQ5QkFNQ0EwY0FNRVFDSUNyMytoTm1TcXVVSGtOc3BnVDV0Q2kvZnZsTWdITXhcblYwQnR2N1REWHV1dkFpQXE2YlVNeDdqc3lkTllKRWpkNklXQmZQMzZ3MG45Y1J3anhVR1NoK1Fld0E9PVxuLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLSIsIi0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLVxuTUlJQ0h6Q0NBY1NnQXdJQkFnSVFkYk1rSFAvUW43OGRtZ2R4ZUx2MGRqQUtCZ2dxaGtqT1BRUURBakJ2TVFzd1xuQ1FZRFZRUUdFd0pWVXpFZU1Cd0dBMVVFQ2hNVlVtbGlZbTl1SUVOdmJXMTFibWxqWVhScGIyNXpNU0F3SGdZRFxuVlFRTEV4ZERaWEowYVdacFkyRjBhVzl1SUVGMWRHaHZjbWwwZVRFZU1Cd0dBMVVFQXhNVlUwaEJTMFZPSUZKcFxuWW1KdmJpQlNiMjkwSUVOQk1CNFhEVEl4TURVeE16QXdNREF3TUZvWERUUTJNRFV4TWpJek5UazFPVm93YnpFTFxuTUFrR0ExVUVCaE1DVlZNeEhqQWNCZ05WQkFvVEZWSnBZbUp2YmlCRGIyMXRkVzVwWTJGMGFXOXVjekVnTUI0R1xuQTFVRUN4TVhRMlZ5ZEdsbWFXTmhkR2x2YmlCQmRYUm9iM0pwZEhreEhqQWNCZ05WQkFNVEZWTklRVXRGVGlCU1xuYVdKaWIyNGdVbTl2ZENCRFFUQlpNQk1HQnlxR1NNNDlBZ0VHQ0NxR1NNNDlBd0VIQTBJQUJDWTZHblZUV01zNFxuRlM4M25lOHZwOWh6NkYxVmsrdGhSREdwU2IxamFMYThaV2hVdFZiY1Vmb0UvMWJ3M2tzcER5anVHMCtqa0pVYVxuS3FFbVFrWW5ET1NqUWpCQU1BOEdBMVVkRXdFQi93UUZNQU1CQWY4d0RnWURWUjBQQVFIL0JBUURBZ0VHTUIwR1xuQTFVZERnUVdCQlM3YmhhU0Z3WU5rbU4rd1pReU5lVnUwZFVVWkRBS0JnZ3Foa2pPUFFRREFnTkpBREJHQWlFQVxudWNDSmk1VnZ2MHhIV0FyNkdYenlpWnFHL2JpTCtjcmNyMUpIVkNtTWJ4SUNJUUM4d2twT1dPNERKcEEzTjU0aVxuZzJ4Q3A1ZHNvaWliRjRCSng2NGdZQ1pMd3c9PVxuLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLSIsIi0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLVxuTUlJQ1BUQ0NBZVNnQXdJQkFnSUlSdjdCM0d3NnhYQXdDZ1lJS29aSXpqMEVBd0l3Y1RFb01DWUdBMVVFQXd3ZlRtVjBUblZ0WW1WeVxuSUZOSVFVdEZUaUJTYjI5MElGUnlhV0ZzSUVOQk1URUxNQWtHQTFVRUJoTUNWVk14RmpBVUJnTlZCQW9NRFU1bGRFNTFiV0psY2lCSlxuYm1NeElEQWVCZ05WQkFzTUYxVlRJRk5JUVV0RlRpQlVjbWxoYkNCVFpYSjJhV05sTUI0WERUSXhNVEl3T1RFMU1ERXpOVm9YRFRRMlxuTVRJd016RTFNREV6TlZvd2NURW9NQ1lHQTFVRUF3d2ZUbVYwVG5WdFltVnlJRk5JUVV0RlRpQlNiMjkwSUZSeWFXRnNJRU5CTVRFTFxuTUFrR0ExVUVCaE1DVlZNeEZqQVVCZ05WQkFvTURVNWxkRTUxYldKbGNpQkpibU14SURBZUJnTlZCQXNNRjFWVElGTklRVXRGVGlCVVxuY21saGJDQlRaWEoyYVdObE1Ga3dFd1lIS29aSXpqMENBUVlJS29aSXpqMERBUWNEUWdBRUZlMnRNRkU4ajI2cWw4bldiWkU2V2k3Y1xuZFZHejhqaHE2V2pneDJZRXN1OWxnUXd4aElWU0RtUUdNcTUyMjVrNUQyZXBEblhJdjZtL0N5UFBoLzJUa0tObU1HUXdFZ1lEVlIwVFxuQVFIL0JBZ3dCZ0VCL3dJQkF6QU9CZ05WSFE4QkFmOEVCQU1DQWdRd0h3WURWUjBqQkJnd0ZvQVVXdmxwTTlIenFlNGNyUEtlOUdrelxuZHBBcmVrNHdIUVlEVlIwT0JCWUVGRnI1YVRQUjg2bnVIS3p5bnZScE0zYVFLM3BPTUFvR0NDcUdTTTQ5QkFNQ0EwY0FNRVFDSUJMd1xuaVVhSjF6ejFwVGFTZ0pCcDFoNUc1ODgwYnpyd29EWDFRNWhnY0xoNEFpQnhxOVN6UVQ5cUMrWTJRbXlMQlNVL2s0L1ArTzlFaUlOOFxuMTlseDZobVY5QT09XG4tLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tIl19.geNHXaR1iliif9hVtsDR5FDKIEBcbRPnVfMNcyeyTiAJCsXc3z2rpP-QBrz3rwji65sZB8sMHZlAYRa09zM1rQ"}
```


# STI-PA-TC-024

CRL Download; verify the CRL signature

You can get the list of CRL from server with the following API:

```
https://authenticate-api-stg.iconectiv.com/download/v1/crl
```

You should get back data from server as follows:

```
-----BEGIN X509 CRL-----
MIIPyzCCD3ICAQEwCgYIKoZIzj0EAwIwVjEUMBIGA1UEBwwLQnJpZGdld2F0ZXIx
CzAJBgNVBAgMAk5KMRMwEQYDVQQDDApTVEktUEEgQ1JMMQswCQYDVQQGEwJVUzEP
MA0GA1UECgwGU1RJLVBBFw0yMjA3MjAxOTAwNDRaFw0yMjA3MjExOTAwNDRaMIIO
DTCBkQIJAMRzV8BBFGlSFw0yMDAyMjQyMDIzMDFaMHUwCgYDVR0VBAMKAQAwZwYD
VR0dAQH/BF0wW6RZMFcxFjAUBgNVBAMMDTE5Mi4xNjguMzAuNjExEDAOBgNVBAoM
B1N0cmF0dXMxDjAMBgNVBAcMddBsYW5vMQ4wDAYDVQQIDAVUZXhhczELMAkGA1UE
BhMCVVMwgaYCEQCxaemSeTxloRS3U0UNjm13Fw0yMDAzMDIyMDU4MDdaMIGBMAoG
A1UdFQQDCgEBMHMGA1UdHQEB/wRpMGekZTBjMSAwHgYDVQQDDBdTVEktUEEgUm9v
dCBDZXJ0aWZpY2F0ZTEPMA0GA1UECgwGU1RJLVBBMRQwEgYDVQQHDAtCcmlkZ2V3
YXRlcjELMAkGA1UECAwCTkoxCzAJBgNVBAYTAlVTMIHIAhQoqhCeiOomO5XQYiAv
5cWxdyyYXxcNMjAwNDA3MTE0NzQ3WjCBaaaKBgNVHRUEAwoBADCBkQYDVR0dAQH/
BIGGMIGDpIGAMH4xCzAJBgNVBAYTAlVTMSkwJwYDVQQKDCBOZXVzdGFyIEluZm9y
bWF0aW9uIFNlcnZpY2VzIEluYzEZMBcGA1UECwwQd3d3LmNjaWQubmV1c3RhcjEp
MCcGA1UEAwwgTmV1c3RhciBDZXJ0aWZpZWQgQ2FsbGVyIElEIENBLTEwgaUCEFk9
zDGEQmKnCz7s5GqVsFcXDTIwMDQxNzIwNDYwMlowgYEwCgYDVR0VBAMKAQEwcwYD
VR0dAQH/BGkwZ6RlMGMxIDAeBgNVBAMMF1NUSS1QQSBSb290IENlcnRpZmljYXRl
MQ8wDQYDVQQKDAZTVEktUEExFDASBgNVBAcMC0JyaWRnZXdhdGVyMQswCQYDVQQI
DAJOSjELMAkGA1UEBhMCVVMwgYACAg4fFw0yMDA0MjIxNzI3NDZaMGswCgYDVR0V
BAMKAQEwXQYDVR0dAQH/BFMwUaRPME0xKDAmBgNVBAMMH1RNT0JJTEUtUFJPRC1S
T09ULVNUSVJTSEFLRU4tRUMxFDASBgNVBAoMC1RNT0JJTEUtVVNBMQswCQYDVQQG
EwJVUzCBpwIQC5McOtY5Z+pnI7/Dr5r0SxcNMjAxMjAyMjAxNzM2WjCBgzAKBgNV
HRUEAwoBATB1BgNVHR0BAf8EazBppGcwZTEkMCIGA1UEAwwbRGlnaUNlcnQgQXNz
dXJlZCBJRCBSb290IEcyMRkwFwYDVQQLDBB3d3cuZGlnaWNlcnQuY29tMRUwEwYD
VQQKDAxEaWdpQ2VydCBJbmMxCzAJBgNVBAYTAlVTMGcCBgF5Gq76QRcNMjEwNDI5
MTYwMDAwWjBOMAoGA1UdFQQDCgEEMEAGA1UdHQEB/wQ2MDSkMjAwMQswCQYDVQQG
EwJVUzEQMA4GA1UECgwHTGl2ZVZveDEPMA0GA1UEAwwGRmFrZUNBMIGmAhEA6Iln
0n6szHL0K/YpzKXedRcNMjEwNjA0MjA1NzM4WjCBgTAKBgNVHRUEAwoBATBzBgNV
HR0BAf8EaTBnpGUwYzEgMB4GA1UEAwwXU1RJLVBBIFJvb3QgQ2VydGlmaWNhdGUx
DzANBgNVBAoMBlNUSS1QQTEUMBIGA1UEBwwLQnJpZGdld2F0ZXIxCzAJBgNVBAgM
Ak5KMQswCQYDVQQGEwJVUzCBlQIDeQEIFw0yMTA3MTMxOTE3MDhaMH8wCgYDVR0V
BAMKAQQwcQYDVR0dAQH/BGcwZaRjMGExKjAoBgNVBAMMIUNhbGxTaGFwZXIgU0hB
S0VOIEludGVybWVkaWF0ZSBDQTETMBEGA1UECgwKQ2FsbFNoYXBlcjERMA8GA1UE
CAwITWFyeWxhbmQxCzAJBgNVBAYTAlVTMIGLAgREAESZFw0yMTA3MjIxNjAyNTVa
MHQwCgYDVR0VBAMKAQAwZgYDVR0dAQH/BFwwWqRYMFYxHzAdBgNVBAMMFkNvbWNh
c3QgU0hBS0VOIFJvb3QgQ0ExDDAKBgNVBAoMA0FNWDELMAkGA1UEBwwCSksxCzAJ
BgNVBAgMAk1JMQswCQYDVQQGEwJVUzCBjAIFWIiFVlgXDTIxMDcyMzE0MTg1OFow
dDAKBgNVHRUEAwoBADBmBgNVHR0BAf8EXDBapFgwVjEfMB0GA1UEAwwWQ29tY2Fz
dCBTSEFLRU4gUm9vdCBDQTEMMAoGA1UECgwDQU1YMQswCQYDVQQHDAJKSzELMAkG
A1UECAwCTUkxCzAJBgNVBAYTAlVTMIHQAhRnd/072ocDy1U7lPFmq9EaY5z7MRcN
MjEwNzI4MjI1NTA0WjCBqDAKBgNVHRUEAwoBCTCBmQYDVR0dAQH/BIGOMIGLpIGI
MIGFMSUwIwYJKoZIhvcNAQkBFhZuby1yZXBseUBjYWxsdG9vbHMuY29tMRYwFAYD
VQQDDA1jYWxsdG9vbHMuY29tMRkwFwYDVQQKDBBDYWxsIFRvb2xzLCBJbmMuMQ8w
DQYDVQQHDAZJcnZpbmUxCzAJBgNVBAgMAkNBMQswCQYDVQQGEwJVUzBYAgEBFw0y
MTA5MDcwNTU4MzNaMEQwCgYDVR0VBAMKAQMwNgYDVR0dAQH/BCwwKqQoMCYxETAP
BgNVBAoMCFFDYWxsIENBMREwDwYDVQQDDAhRQ2FsbCBDQTCBpgIRAKIJMk+3RJaN
Nz9nou6Y2jYXDTIxMTIxMDAxMDM0MVowgYEwCgYDVR0VBAMKAQAwcwYDVR0dAQH/
BGkwZ6RlMGMxIDAeBgNVBAMMF1NUSS1QffBSb290IENlcnRpZmljYXRlMQ8wDQYD
VQQKDAZTVEktUEExFDASBgNVBAcMC0JyaWRnZXdhdGVyMQswCQYDVQQIDAJOSjEL
MAkGA1UEBhMCVVMwgasCFEkbRiisDLtvog+OVeyj0NLZuCqtFw0yMjA1MDUxNjAx
NDhaMIGDMAoGA1UdFQQDCgEAMHUGA1UdHQEB/wRrMGmkZzBlMSAwHgYDVQQDDBdH
QlNEVGVjaCBTSEFLRU4gUm9vdCBDQTERMA8GA1UECgwIR0JTRFRlY2gxETAPBgNV
BAcMCEZ0IFdvcnRoMQ4wDAYDVQQIDAVUZXhhczELMAkGA1UEBhMCVVMwVQICJwsX
DTIyMDUyNDIwMjgzNVowQDAKBgNVHRUEAwoBBDAyBgNVHR0BAf8EKDAmpCQwIjET
MBEGA1UEAwwKVHJ1c3RlZCBDQTELMAkGA1UEBhMCVVMwgawCCEb+wdxsOsVwFw0y
MjA2MDcxNTUwMDlaMIGQMAoGA1UdFQQDCgEAMIGBBgNVHR0BAf8EdzB1pHMwcTEg
MB4GA1UECwwXVVMgU0hBS0VOIFRyaWFsIFNlcnZpY2UxFjAUBgNVBAoMDU5ldE51
bWJlciBJbmMxCzAJBgNVBAYTAlVTMSgwJgYDVQQDDB9OZXROdW1iZXIgU0hBS0VO
IFJvb3QgVHJpYWwgQ0ExMIGlAhBZ3HSVyfBjSRLWPWoygqFVFw0yMjA2MDcxNTUx
MzdaMIGBMAoGA1UdFQQDCgEAMHMGA1UdHQEB/wRpMGekZTBjMSAwHgYDVQQDDBdT
VEktUEEgUm9vdCBDZXJ0aWZpY2F0ZTEPMA0GA1UECgwGU1RJLVBBMRQwEgYDVQQH
DAtCcmlkZ2V3YXRlcjELMAkGA1UECAwCTkoxCzAJBgNVBAYTAlVTMIHfAgJpBBcN
MjIwNjE4MDExNDM0WjCByTAKBgNVHRUEAwoBCTCBugYDVR0dAQH/BIGvMIGspIGp
MIGmMSIwIAYJKoZIhvcNAQkBFhNuby1yZXBseUByb290Q0EudGxkMSkwJwYDVQQD
DCBTVElSL1NIQUtFTiBTZWxmLVNpZ25pbmcgUm9vdCBDQTEpMCcGA1UECgwgU1RJ
Ui9TSEFLRU4gU2VsZi1TaWduaW5nIFJvb3QgQ0ExEDAOBgNVBAcMB0F0bGFudGEx
CzAJBgNVBAgMAkdBMQswCQYDVQQGEwJVUzCBlgIBABcNMjIwNjIxMjAzNjQ5WjCB
gTAKBgNVHRUEAwoBAjBzBgNVHR0BAf8EaTBnpGUwYzExMC8GA1UECwwoR28gRGFk
ZHkgQ2xhc3MgMiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEhMB8GA1UECgwYVGhl
IEdvIERhZGR5IEdyb3VwLCBJbmMuMQswCQYDVQQGEwJVUzCB0AIUQpx8cHEeOCDw
uOHerm/zJiJkO/kXDTIyMDcwNjE5MjYwM1owgagwCgYDVR0VBAMKAQAwgZkGA1Ud
HQEB/wSBjjCBi6SBiDCBhTEwMC4GA1UEAwwnU0hBS0VOIFNhbnNheSBJbnRlcm1l
ZGlhdGUgQ0EgVVMgV0VTVCAxMRIwEAYDVQQLDAlTYW5zYXkgQ0ExGzAZBgNVBAoM
ElNhbnNheSBDb3Jwb3JhdGlvbjETMBEGA1UECAwKQ2FsaWZvcm5pYTELMAkGA1UE
BhMCVVMwgeYCFA2jkywttqz8o3hHNpnYqeBHJwR8Fw0yMjA3MDcxMzI1MDJaMIG+
MAoGA1UdFQQDCgEEMIGvBgNVHR0BAf8EgaQwgaGkgZ4wgZsxKDAmBgkqhkiG9w0B
CQEWGXRlY2hub2xvZ3lAc2ltcGx5Y2FzdC5jb20xFzAVBgNVBAMMDnNpbXBseWNh
c3QuY29tMRMwEQYDVQQLDApPcGVyYXRpb25zMRMwEQYDVQQKDApTaW1wbHlDYXN0
MRIwEAYDVQQHDAlEYXJ0bW91dGgxCzAJBgNVBAgMAk5TMQswCQYDVQQGEwJDQaCB
2TCB1jBPBgNVHRwBAf8ERTBDoD6gPIY6aHR0cHM6Ly9hdXRoZW50aWNhdGUtYXBp
LXN0Zy5pY29uZWN0aXYuY29tL2Rvd25sb2FkL3YxL2NybIQB/zALBgNVHRQEBAIC
AvIwdgYIKwYBBQUHAQEEajBoMGYGCCsGAQUFBzAChlpodHRwczovL2F1dGhlbnRp
Y2F0ZS1hcGktc3RnLmljb25lY3Rpdi5jb20vZG93bmxvYWQvdjEvY2VydGlmaWNh
dGUvY2VydGlmaWNhdGVJZF8yNjM1NS5jcnQwCgYIKoZIzj0EAwIDRwAwRAIgQBy+
Hl2vhB3q/QPVRscc2JvqaEj1ZB/H5gfStEkTgVYCIHMX7etueEJG6ILNxZg8YOch
ZttXgJI+qPa4AxFMaOqr
-----END X509 CRL-----
 == Retrieved CRL:
Certificate Revocation List (CRL):
        Issuer: /L=Bridgewater/ST=NJ/CN=STI-PA CRL/C=US/O=STI-PA
Revoked Certificates:
    Serial Number: C47357C041146952
        Revocation Date: Feb 24 20:23:01 2020 GMT
            X509v3 Certificate Issuer: critical
                DirName:/CN=192.168.30.61/O=Stratus/L=Plano/ST=Texas/C=US
    Serial Number: B169E992793C65A114B753450D8E6D77
        Revocation Date: Mar  2 20:58:07 2020 GMT
            X509v3 Certificate Issuer: critical
                DirName:/CN=STI-PA Root Certificate/O=STI-PA/L=Bridgewater/ST=NJ/C=US
    Serial Number: 28AA109E88EA263B95D062202FE5C5B1772C985F
        Revocation Date: Apr  7 11:47:47 2020 GMT
            X509v3 Certificate Issuer: critical
                DirName:/C=US/O=Neustar Information Services Inc/OU=www.ccid.neustar/CN=Neustar Certified Caller ID CA-1
    Serial Number: 593DCC31844262A70B3EECE46A95B057
        Revocation Date: Apr 17 20:46:02 2020 GMT
            X509v3 Certificate Issuer: critical
                DirName:/CN=STI-PA Root Certificate/O=STI-PA/L=Bridgewater/ST=NJ/C=US
    Serial Number: 0E1F
        Revocation Date: Apr 22 17:27:46 2020 GMT
            X509v3 Certificate Issuer: critical
                DirName:/CN=TMOBILE-PROD-ROOT-STIRSHAKEN-EC/O=TMOBILE-USA/C=US
    Serial Number: 0B931C3AD63967EA6723BFC3AF9AF44B
        Revocation Date: Dec  2 20:17:36 2020 GMT
            X509v3 Certificate Issuer: critical
                DirName:/CN=DigiCert Assured ID Root G2/OU=www.digicert.com/O=DigiCert Inc/C=US
    Serial Number: 01791AAEFA41
        Revocation Date: Apr 29 16:00:00 2021 GMT
            X509v3 Certificate Issuer: critical
                DirName:/C=US/O=LiveVox/CN=FakeCA
    Serial Number: E88967D27EACCC72F42BF629CCA5DE75
        Revocation Date: Jun  4 20:57:38 2021 GMT
            X509v3 Certificate Issuer: critical
                DirName:/CN=STI-PA Root Certificate/O=STI-PA/L=Bridgewater/ST=NJ/C=US
    Serial Number: 790108
        Revocation Date: Jul 13 19:17:08 2021 GMT
            X509v3 Certificate Issuer: critical
                DirName:/CN=CallShaper SHAKEN Intermediate CA/O=CallShaper/ST=Maryland/C=US
    Serial Number: 44004499
        Revocation Date: Jul 22 16:02:55 2021 GMT
            X509v3 Certificate Issuer: critical
                DirName:/CN=Comcast SHAKEN Root CA/O=AMX/L=JK/ST=MI/C=US
    Serial Number: 5888855658
        Revocation Date: Jul 23 14:18:58 2021 GMT
            X509v3 Certificate Issuer: critical
                DirName:/CN=Comcast SHAKEN Root CA/O=AMX/L=JK/ST=MI/C=US
    Serial Number: 6777FD3BDA8703CB553B94F166ABD11A639CFB31
        Revocation Date: Jul 28 22:55:04 2021 GMT
            X509v3 Certificate Issuer: critical
                DirName:/emailAddress=no-reply@calltools.com/CN=calltools.com/O=Call Tools, Inc./L=Irvine/ST=CA/C=US
    Serial Number: 01
        Revocation Date: Sep  7 05:58:33 2021 GMT
            X509v3 Certificate Issuer: critical
                DirName:/O=QCall CA/CN=QCall CA
    Serial Number: A209324FB744968D373F67A2EE98DA36
        Revocation Date: Dec 10 01:03:41 2021 GMT
            X509v3 Certificate Issuer: critical
                DirName:/CN=STI-PA Root Certificate/O=STI-PA/L=Bridgewater/ST=NJ/C=US
    Serial Number: 491B4628AC0CBB6FA20F8E55ECA3D0D2D9B82AAD
        Revocation Date: May  5 16:01:48 2022 GMT
            X509v3 Certificate Issuer: critical
                DirName:/CN=GBSDTech SHAKEN Root CA/O=GBSDTech/L=Ft Worth/ST=Texas/C=US
    Serial Number: 270B
        Revocation Date: May 24 20:28:35 2022 GMT
            X509v3 Certificate Issuer: critical
                DirName:/CN=Trusted CA/C=US
    Serial Number: 46FEC1DC6C3AC570
        Revocation Date: Jun  7 15:50:09 2022 GMT
            X509v3 Certificate Issuer: critical
                DirName:/OU=US SHAKEN Trial Service/O=NetNumber Inc/C=US/CN=NetNumber SHAKEN Root Trial CA1
    Serial Number: 59DC7495C9F0634912D63D6A3282A155
        Revocation Date: Jun  7 15:51:37 2022 GMT
            X509v3 Certificate Issuer: critical
                DirName:/CN=STI-PA Root Certificate/O=STI-PA/L=Bridgewater/ST=NJ/C=US
    Serial Number: 6904
        Revocation Date: Jun 18 01:14:34 2022 GMT
            X509v3 Certificate Issuer: critical
                DirName:/emailAddress=no-reply@rootCA.tld/CN=STIR/SHAKEN Self-Signing Root CA/O=STIR/SHAKEN Self-Signing Root CA/L=Atlanta/ST=GA/C=US
    Serial Number: 00
        Revocation Date: Jun 21 20:36:49 2022 GMT
            X509v3 Certificate Issuer: critical
                DirName:/OU=Go Daddy Class 2 Certification Authority/O=The Go Daddy Group, Inc./C=US
    Serial Number: 429C7C70711E3820F0B8E1DEAE6FF32622643BF9
        Revocation Date: Jul  6 19:26:03 2022 GMT
            X509v3 Certificate Issuer: critical
                DirName:/CN=SHAKEN Sansay Intermediate CA US WEST 1/OU=Sansay CA/O=Sansay Corporation/ST=California/C=US
    Serial Number: 0DA3932C2DB6ACFCA378473699D8A9E04727047C
        Revocation Date: Jul  7 13:25:02 2022 GMT
            X509v3 Certificate Issuer: critical
                DirName:/emailAddress=technology@simplycast.com/CN=simplycast.com/OU=Operations/O=SimplyCast/L=Dartmouth/ST=NS/C=CA
```

## Validate CRL Signature

You use the following API to get signature:

```
https://authenticate-api-stg.iconectiv.com/download/v1/certificate/certificateId_26355.crt
```

Server should response with:

```
-----BEGIN CERTIFICATE-----
MIICPDCCAeKgAwIBAgIRAJsp7BpDDvw8gxcT4n8MGGEwCgYIKoZIzj0EAwIwYzEL
MAkGA1UEBhMCVVMxCzAJBgNVBAgMAk5KMRQwEgYDVQQHDAtCcmlkZ2V3YXRlcjEP
MA0GA1UECgwGU1RJLVBBMSAwHgYDVQQDDBdTVEktUEEgUm9vdCBDZXJ0aWZpY2F0
ZTAeFw0yMDExMTEyMzMyMTJaFw0yMzExMTIwMDMyMTJaMFYxFDASBgNVBAcTC0Jy
aWRnZXdhdGVyMQswCQYDVQQIEwJOSjETMBEGA1UEAxMKU1RJLVBBIENSTDELMAkG
A1UEBhMCVVMxDzANBgNVBAoTBlNUSS1QQTBZMBMGByqGSM49AgEGCCqGSM49AwEH
A0IABKIAr1yTIx/vfEK3gHC9iwSaRHZn+5jo2dDQ7/+T8eGcV7aJu9KJ3lcMDxvj
1LUCD3i3GNylH0jHck6SCj/BwimjgYMwgYAwEgYDVR0TAQH/BAgwBgEB/wIBADAf
BgNVHSMEGDAWgBQOZDzy2PmYh6Hq3RLh6b732Gz9PDAdBgNVHQ4EFgQUbqZpgTbk
+j4bB1owEa6o8H6xHhkwDgYDVR0PAQH/BAQDAgGGMBoGA1UdIAEB/wQQMA4wDAYK
YIZIAYb/CQEBATAKBggqhkjOPQQDAgNIADBFAiEAuaAu3ylCL8/Kad7VKdv/O4vw
5QnV79xdiFc2jExdRmYCIGDlBQXhQzCJNSXxvqBnqkW/SkQ3mo/DP4LyC8NkNsew
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIICBjCCAaygAwIBAgIQWdx0lcnwY0kS1j1qMoKhVTAKBggqhkjOPQQDAjBjMQsw
CQYDVQQGEwJVUzELMAkGA1UECAwCTkoxFDASBgNVBAcMC0JyaWRnZXdhdGVyMQ8w
DQYDVQQKDAZTVEktUEExIDAeBgNVBAMMF1NUSS1QQSBSb290IENlcnRpZmljYXRl
MB4XDTE5MTAwNDExNDEyM1oXDTI5MTAwNDEyNDEyM1owYzELMAkGA1UEBhMCVVMx
CzAJBgNVBAgMAk5KMRQwEgYDVQQHDAtCcmlkZ2V3YXRlcjEPMA0GA1UECgwGU1RJ
LVBBMSAwHgYDVQQDDBdTVEktUEEgUm9vdCBDZXJ0aWZpY2F0ZTBZMBMGByqGSM49
AgEGCCqGSM49AwEHA0IABCYlkZftjTJ5LjnKSG4Ed4Wdjs2yA4i6IsrKEp55roKm
Ypbni2MWS7CB1XMzO62h/8m+6tuu9zDsx77csEXpbpajQjBAMA8GA1UdEwEB/wQF
MAMBAf8wHQYDVR0OBBYEFA5kPPLY+ZiHoerdEuHpvvfYbP08MA4GA1UdDwEB/wQE
AwIBhjAKBggqhkjOPQQDAgNIADBFAiEA6Hydwq1G2qV9QFRfGtpSI2ekZ7+NnQey
sLATvTYUOp8CICar8g1HJb/EvjI5Lw5Su0XqAzUXpRyXr6ehLvWeR/NO
-----END CERTIFICATE-----
```

### Using x5u:&#x20;

serial=9B29EC1A430EFC3C831713E27F0C1861&#x20;

issuer= /C=US/ST=NJ/L=Bridgewater/O=STI-PA/CN=STI-PA Root Certificate&#x20;

subject= /L=Bridgewater/ST=NJ/CN=STI-PA CRL/C=US/O=STI-PA ==&#x20;

### Using Root CA:&#x20;

serial=59DC7495C9F0634912D63D6A3282A155&#x20;

issuer= /C=US/ST=NJ/L=Bridgewater/O=STI-PA/CN=STI-PA Root Certificate&#x20;

subject= /C=US/ST=NJ/L=Bridgewater/O=STI-PA/CN=STI-PA Root Certificate


# STI-PA-TC-022

SP can revoke an STI certificate; verify revoked certificate is added to CRL

## Creating a STI certificate

In this test case, you should try to create a certificate using Peeringhub's staging environment and then attempt to revoke it in iConnective's staging UI.&#x20;

You can see the full details on how to generate a test certificate using Peeringhub's staging ACME server.  The [instruction](/guides/generating-certificate) for ordering a certificate in staging environment is same as in production environment.  The only difference is that the staging ACME server URL is&#x20;

```
https://stica-dev.peeringhub.io
```

## Revoking a STI certificate

After your certificate is created, you can revoke it by going into iConnective staging portal&#x20;

![](/files/GPKViAmk2YgyOgAonDK5)

&#x20;

{% hint style="info" %}
The iConnectiv STI staging portal url is <https://stg-authenticateapp.iconectiv.com/>
{% endhint %}


# STI-PA-TC-025

SPC Token request

You can use the following API to obtain SPC Token:

```
https://authenticate-api-stg.iconectiv.com/api/v1/account/281K/token/
```

Your request data should be like this:

```
{ "atc": 
 { "tktype": "TNAuthList", 
   "tkvalue": "MAigBhYEMjgxSw==", 
   "ca": false, 
   "fingerprint": "SHA256 49:55:78:7F:42:17:33:67:99:48:DC:54:21:DA:F4:79:C7:41:29:06:BF:A5:38:DF:9E:01:97:6A:2C:53:CC:3B"
    }}
```

Server should response with:

```
{"status":"success",
"message":"SPC token for spc: 111K is created successfully",
"token":"eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXdddddSI6Imh0dHBzOi8vYXV0aGVudGljYXRlLWFwaS1zdGcuaWNvbmVjdGl2LmNvbS9kb3dubG9hZC92MS9jZXJ0aWZpY2F0ZS9jZXJ0aWZpY2F0ZUlkXzk3NTc0LmNydCJ9.eyJleHAiOjE2ODk5MTkwNjMsImp0aSI6IjUxOTE3NWNiLTY5OTgtNDA3NC05YWVhLTBkYTUxNzVhMTYyMiIsImF0YyI6eyJ0a3R5cGUiOiJUTkF1dGhMaXN0IiwidGt2YWx1ZSI6Ik1BaWdCaFlFTWpneFN3PT0iLCJjYSI6ZmFsc2UsImZpbmdlcnByaW50IjoiU0hBMjU2IDQ5OjU1Ojc4OjdGOjQyOjE3OjgxOjY3Ojk5OjQ4OkRDOjU0OjIxOkRBOkY0Ojc5OkM3OjQxOjI5OjA2OkJGOkE1OjM4OkRGOjlFOjAxOjk3OjZBOjJDOjUzOkNDOjNCIn19.yZsMAjzQ0fBx4hUQBR-E-exUwRHrFn4_utPuSJrraJYjI2K3eCfjNwVuMSCkAx9MQrUofB0d9hmDnZ_AblOCUQ",
"crl":"https://authenticate-api-stg.iconectiv.com/download/v1/crl"}
```


# Purchase Subscription

Once you become an approved Sitr/Shaken Service Provider, you can sign up to Peeringhub's CA service to start ordering certificate.

To registration url is <http://portal.peeringhub.io&#x20>;

After your registration is completed, you will receive a confirmation email.


# Generating Certificate

Peeringhub provides multiple methods for obtaining a Stir/Shaken Certificate. You may use Peeringhub's Web UI, Linux Command Line Client, Python tools, or the standard ACME API protocol. These methods are described in this section.


# Web UI

You can generate your STIR/SHAKEN certificate through the Peeringhub.io web portal, which is the easiest way to do so.

To complete this process, follow these two steps:

1. **Generate your private key**
2. **Generate your certificate**

Both steps can be accomplished via the Web UI at <http://portal.peeringhub.io>.

#### Step 1: Generate a Private Key

To generate your private key:

* Navigate to the **STIR/SHAKEN Certificate** section.
* Click on **Private Key**.
* Then, click the **"Create New"** button in the top-right corner to generate a new private key.

<figure><img src="/files/8rYu0zenffOaONPFoprL" alt=""><figcaption></figcaption></figure>

You can generate as many private keys as needed. When creating a STIR/SHAKEN certificate, you can select one of your previously generated private keys.

To download a private key, simply click on the **Download** icon next to it. You will need these private keys to sign your calls.

<figure><img src="/files/xWEUt9RVFRh9hsdtYeMz" alt=""><figcaption></figcaption></figure>

#### Step 2: Generate a STIR/SHAKEN Certificate

To generate your STIR/SHAKEN certificate:

1. Navigate to the **STIR/SHAKEN Certificate** section.
2. Click the **"Create New"** button in the top-right corner.

<figure><img src="/files/wfTJVdSVs9FsGPpOhdRV" alt=""><figcaption></figcaption></figure>

* A pop-up window will appear, allowing you to select a private key for your STIR/SHAKEN certificate. Additionally, you will need to enter your **iConnective** username and password.

<figure><img src="/files/4FYz8qYCvko9WqQKNFNc" alt=""><figcaption></figcaption></figure>

* Click the **"Generate Now"** button to create your certificate.

{% hint style="info" %}
Your STI-PA Username and Password should be albe to be login to <http://authenticateapp.iconectiv.com&#x20>;

If your **STI-PA** (Secure Telephone Identity Policy Administrator) username and password are invalid, you will be unable to generate a STIR/SHAKEN certificate. To ensure successful certificate generation, please verify that your STI-PA credentials are accurate and active. If you haven't registered with the STI-PA yet, you'll need to complete their registration process to obtain valid credentials.
{% endhint %}

#### Step 3: Obtain your Certificate URL

You can see all your generated Stir/Shaken Certificate.  Under CR URL, you can use it to sign call with. &#x20;

<figure><img src="/files/K9tvVqajjOErkmCaPFqM" alt=""><figcaption></figcaption></figure>


# Renew Stir/Shaken Certificate

When your STIR/SHAKEN certificate expires, you can simply click the **"Renew"** button to renew it.

<figure><img src="/files/pTPqRTmQHAEhUlDpVp2l" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
You can renew your STIR/SHAKEN certificate as long as your account remains active and has not reached its expiration date.
{% endhint %}


# ACME protocol reference

This is a general description of the ACME protocol for STIR/SHAKEN ACME servers. For the comprehensive reference see RFC 8555 and ATIS-1000080 v4.

The steps, required to issue a new STIR/SHAKEN certificate for Service Providers (SP), are:

1. List ACME server directory
2. Acquire nonce
3. Authorize on the server; Ensure that the account is active
4. Place a new order
5. Get challenge
6. Submit challenge response
7. Upload CSR
8. Download certificate&#x20;


# Protocol Overview

Communications between an ACME client and an ACME server are done over HTTPS, using JSON Web Signature (JWS), defined in RFC 7515.

JWS must be in a Flattened JSON Serialization format, and must include a protected header, a payload and a signature:

```
{
  "protected" : "<base64url-encoded header>"
  "payload" : "<base64url-encoded payload>",
  "signature" : "<base64url-encoded signature>"
}
```

JWS protected header should contain a set parameters:

* "alg" - identifies the encryption algorithm (must be "ES256")
* "nonce" - a fresh nonce value, retrieved from the ACME server
* "url" - the requested URL (including hostname)
* "kid" - ACME Account URL

Example of a JWS protected header:

```
{
  "alg" : "ES256",
  "nonce" : "B851691E46EC4EC88424473F8D0BBBD5",
  "url" : "https://stica.peeringhub.io/acme/new-order",
  "kid": "https://stica.peeringhub.io/acme/acct/45DF152CDB284EEF987FAE35C3A77FD8"
}
```

JWS payload should be a base64url-encoded JSON object, or an empty string. The content of JWS payload depends on the type of the request. Detached payloads are not allowed.

JWS signature must be created from the protected header concatenated with the payload (if exists):

* String to sign: `<base64url-encoded header>` + `.` + `<base64url-encoded payload>`
* If payload is empty: `<base64url-encoded header>`

JWS signature must be created with an EC P-256 key, associated with the ACME account, using SHA256withECDSA algorithm. ACME server does not support other encryption algorithms, as well as Elliptic Curves others than P-256.


# List server directory

To get the list of functions, supported by the server, and their URL, ACME client must send a GET request to the ACME server base URL:

```
GET https://stica.peeringhub.io/acme

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Content-Length: 247
{
  "newNonce" : "https://stica.peeringhub.io/acme/new-nonce",
  "newAccount" : "https://stica.peeringhub.io/acme/new-account",
  "newOrder" : "https://stica.peeringhub.io/acme/new-order",
  "keyChange" : "https://stica.peeringhub.io/acme/key-change"
}
```

List of the supported functions and their URLs are not standard, and may change over time. Requests below in this document must be sent to the corresponding URL from the received list.


# Get nonce

JWS header must contain a fresh nonce, received from the ACME server. Each nonce value can be used only once, and only within a limited period of time (usually 1 hour). To acquire a new nonce value, send a HEAD or a GET request to the newNonce URL. ACME server shall return an empty response with a newly generated nonce string in a Replay-Nonce header.

```
HEAD https://stica.peeringhub.io/acme/new-nonce

HTTP/1.1 200 OK
Replay-Nonce: ABECF2EDB773493ABC9C6E000420DBEC
Content-Length: 0
```

ACME server should generate a fresh nonce value in reply to every HTTP request, described in this document. The new nonce value should be included into Replay-Nonce header.


# Account creation & Authorization

## ACME account

Account on the ACME server is represented by an ACME Account URL, which must be included in every JWS header ("kid" parameter). To acquire the ACME Account URL, ACME client must go through the authorization process.

## ACME Account creation and authorization

To perform the authorization, ACME client must send a EC P-256 public key, associated with the ACME account. If account with such key does not exist on the server, it will be created.

Public keys must be sent to the ACME server in JWK format (RFC 7517):

```
{
  "kty" : "EC",
  "crv" : "P-256",
  "x" : "<EC pubkey X point>",
  "y" : "<EC pubkey Y point>",
  "kid" : "<Human-readable Key Identifier string>"
}
```

To authorize on the ACME server, send a POST request to the newAccount URL with JWK in protected header (instead of "kid"), and an empty payload:

```
POST https://stica.peeringhub.io/acme/new-account
Content-Type: application/jose+json
Content-Length: 512
{
  "protected" : BASE64URL(
    {
      "alg" : "ES256",
      "nonce" : "ABECF2EDB773493ABC9C6E000420DBEC",
      "url" : "https://stica.peeringhub.io/acme/new-account",
      "jwk": {
        "kty" : "EC",
        "crv" : "P-256",
        "x" : "4nHODmypbnfKdJd-IxbMsLwOtJqC0fPysqKFu8cssEY",
        "y" : "u5McBHfPXkFvlHtFM38GEmMiv2owHxPawpWfH17Y0MY",
        "kid" : "My key"
      }
    }
  ),
  "payload" : "",
  "signature" : "<base64url-encoded signature>"
}
```

If account with such key already exists, ACME server shall return an empty 200 OK reply with the ACME Account URL in the Location header:

```
HTTP/1.1 200 OK
Replay-Nonce: 86CB00B0430D4C71B2D156B2AE785353
Location: https://stica.peeringhub.io/acme/acct/6A1AD155B73D45448E7B832888C3EF54
Content-Length: 0
```

Otherwise, a new account should be created, and ACME server shall send back a 201 Created reply with the ACME Account object.

```
HTTP/1.1 201 Created
Replay-Nonce: 7BDB37ADEB3C41E8A95BADEB1A3CE38C
Location: https://stica.peeringhub.io/acme/acct/6A1AD155B73D45448E7B832888C3EF54
Content-Type: application/json; charset=utf-8
Content-Length: 106
{
  "status" : "valid",
  "orders" : "https://stica.peeringhub.io/acme/orders/6A1AD155B73D45448E7B832888C3EF54"
}
```

It's also possible to check, whether the ACME Account with such key exists on the server, without creating one. For this, ACME client must put a "onlyReturnExisting" boolean parameter into the JWS payload:

```
POST https://stica.peeringhub.io/acme/new-account
Content-Type: application/jose+json
Content-Length: 512
{
  "protected" : BASE64URL(
    {
      "alg" : "ES256",
      "nonce" : "ABECF2EDB773493ABC9C6E000420DBEC",
      "url" : "https://stica.peeringhub.io/acme/new-account",
      "jwk": {
        "kty" : "EC",
        "crv" : "P-256",
        "x" : "4nHODmypbnfKdJd-IxbMsLwOtJqC0fPysqKFu8cssEY",
        "y" : "u5McBHfPXkFvlHtFM38GEmMiv2owHxPawpWfH17Y0MY",
        "kid" : "My key"
      }
    }
  ),
  "payload" : BASE64URL(
    {
      "onlyReturnExisting" : true
    }
  ),
  "signature" : "<base64url-encoded signature>"
}
```

If ACME Account with such key cannot be found, ACME server should reply with a 400 Bad Request and "accountDoesNotExist" error:

```
HTTP/1.1 400 Bad Request
Replay-Nonce: 29FC5BFA9F1748FEBC77D8CA7F3DE1FF
Content-Type: application/json; charset=utf-8
Content-Length: 57
{
  "type" : "urn:ietf:params:acme:error:accountDoesNotExist"
}
```


# Get ACME account status

ACME Account URL shall never be changed. So it's not strictly necessary to go through the authorization process each time, if the URL is already known.

However, it might be required to get the actual status of the ACME Account. In order to do so, ACME client must send a POST request with an empty payload to the ACME Account URL:

```
POST https://stica.peeringhub.io/acme/acct/6A1AD155B73D45448E7B832888C3EF54
Content-Type: application/jose+json
Content-Length: 429
{
  "protected" : BASE64URL(
    {
      "alg" : "ES256",
      "nonce" : "E48E837729264688A335A0092370EF3B",
      "url" : "https://stica.peeringhub.io/acme/acct/6A1AD155B73D45448E7B832888C3EF54",
      "kid" : "https://stica.peeringhub.io/acme/acct/6A1AD155B73D45448E7B832888C3EF54"
    }
  ),
  "payload": "",
  "signature" : "<base64url-encoded signature>"
}
```

ACME server should reply with an ACME Account object, which includes a status, and orders URL, from which client may retrieve a list of active certificate orders.

```
HTTP/1.1 200 OK
Replay-Nonce: 60D446A8AEB04EB5BF28219E746CE4E3
Content-Type: application/json; charset=utf-8
Content-Length: 106
{
  "status" : "valid",
  "orders" : "https://stica.peeringhub.io/acme/orders/6A1AD155B73D45448E7B832888C3EF54"
}
```

Possible values of the ACME Account status are:

* "valid" - account is active
* "deactivated" - disabled by the user
* "revoked" - disabled by the server


# Order a new certificate

This section will cover the steps necessary to create a Stir/Shaken certificate.

## Certificate private key

A private key for the certificate must be created using EC P-256 algorithm. This can be done using OpenSSL library for the selected programming language, or using the CLI tool:

```
openssl ecparam -genkey -name prime256v1 -out ./private_key.pem
```

ACME server does not support other encryption algorithms, as well as other types of Elliptic Curves.

## TNAuthList

Every STIR/SHAKEN SP certificate must include a TNAuthList extension (OID 1.3.6.1.5.5.7.1.26), defined in RFC 8226.

The extension should contain a unique Service Provider account code (OCN):

```
asn1=SEQUENCE:tn_auth_list
[tn_auth_list]
field1=EXP:0,IA5:<OCN>
```

TNAuthList value, used in the ACME HTTP requests, is a base64-encoded extension ASN.1 object.

For example, for OCN 616H X509v3 extension will be:

```
asn1=SEQUENCE:tn_auth_list
[tn_auth_list]
field1=EXP:0,IA5:616H
```

And the base64-encoded TNAuthList value for HTTP requests:

```
MAigxxYEODE4SA==
```

## How to generate "TNAuthList value"

tkvalue is a base64-encoded X509 extension and you can create it using openssl CLI tool with the following steps:

Step 1: Create ssl .conf file

```
cat << EOF > tnauthlist.conf
asn1=SEQUENCE:tn_auth_list
[tn_auth_list]
field1=EXP:0,IA5:<UPPERCASE OCN>
EOF
```

Step 2: Create extension

```
openssl asn1parse -genconf tnauthlist.conf -noout -out tnauthlist.der
```

Step 3:  Encode

```
cat tnauthlist.der | base64
```

Here is a full example:

```
% cat << EOF > tnauthlist.conf
asn1=SEQUENCE:tn_auth_list
[tn_auth_list]
field1=EXP:0,IA5:818H
EOF

% openssl asn1parse -genconf tnauthlist.conf -noout -out tnauthlist.der

% cat tnauthlist.der | base64
MAigBhYEODE4SA==
```

## Order creation

To submit a new certificate order, ACME client should send a POST request to the newOrder URL with a set of parameters in the payload:

* identifiers (mandatory) - contains TNAuthList value
* notBefore (optional) - desired notBefore value of the created certificate
* notAfter (optional) - desired notAfter value

Mandatory parameter "identifiers" must be a JSON array with a single TNAuthList value object:

```
{
  "type" : "TNAuthList",
  "value" : "MAigxxxxxDE4SA=="
}
```

Optional parameters notBefore and notAfter should have a RFC 3339 timestamp format (`2022-01-15T00:00:01Z`). If not set, certificate will be issued with the default lifespan of 1 year.

Example of the New Order request:

```
POST https://stica.peeringhub.io/acme/new-order

Content-Type: application/jose+json
Content-Length: 572
{
  "protected" : BASE64URL(
    {
      "alg" : "ES256",
      "nonce" : "497685E333B24DEFBEDEB5D5A595FF28",
      "url" : "https://stica.peeringhub.io/acme/new-order",
      "kid" : "https://stica.peeringhub.io/acme/acct/6A1AD155B73D45448E7B832888C3EF54"
    }
  ),
  "payload" : BASE64URL(
    {
      "identifiers" : [{ "type" : "TNAuthList", "value" : "MAigBhYEODE4SA==" }],
      "notBefore" : "2022-08-08T21:48:20Z",
      "notAfter" : "2022-08-08T21:53:20Z"
    }
  ),
  "signature" : "<base64url-encoded signature>"
}
```

On success, ACME server should return a new ACME Order object, and ACME Order URL in the Location header:

```
HTTP/1.1 201 Created
Location: https://stica.peeringhub.io/acme/order/0E22FC02933D42BC86A64425BB20D4B0
Replay-Nonce: 51029A7B34EC4F2280ECD2A6EC4E3C04
Content-Type: application/json; charset=utf-8
Content-Length: 395
{
  "status" : "pending",
  "expires" : "2022-08-09T21:49:43Z",
  "identifiers" : [{ "type" : "TNAuthList", "value" : "MAigBhYEODE4SA==" }],
  "notBefore" : "2022-08-08T21:48:20Z",
  "notAfter" : "2022-08-08T21:53:20Z",
  "error" : null,
  "authorizations" : [ "https://stica.peeringhub.io/acme/authz/D55D90F2F6854D2CBB2E9C4A2E6EC4DB" ],
  "finalize" : "https://stica.peeringhub.io/acme/order/0E22FC02933D42BC86A64425BB20D4B0/finalize"
}
```

ACME Client may get the ACME Order object by sending a POST request with an empty payload to the ACME order URL:

```
POST https://stica.peeringhub.io/acme/order/0E22FC02933D42BC86A64425BB20D4B0

Content-Type: application/jose+json
Content-Length: 430
{
  "protected" : BASE64URL(
    {
      "alg": "ES256",
      "nonce": "B106476126104951AC9177221C508154",
      "url": "https://stica.peeringhub.io/acme/order/0E22FC02933D42BC86A64425BB20D4B0",
      "kid": "https://stica.peeringhub.io/acme/acct/6A1AD155B73D45448E7B832888C3EF54"
    }
  ),
  "payload" : "",
  "signature" : "<base64url-encoded signature>"
}
```

ACME Order object should contain:

* Order status
* Expiration time
* ACME Order Challenge URL in the "authorizations" array
* CSR submission URL in the "finalize" parameter

The possible values of the ACME Order status are:

* "pending" - waiting for challenge submission
* "ready" - user has passed the challenge; waiting for CSR submission
* "processing" - creating a certificate
* "valid" - certificate is ready for downloading
* "invalid" - indicates an error

On failure, the "error" parameter must contain a problem document in a format, described in RFC 7807. The full list of registered error types can be found in the IANA database: <https://www.iana.org/assignments/acme/acme.xhtml>

## Challenge

After submitting a new order, ACME client must acquire ACME Order Challenge, using URL from "authorizations" array of ACME order object.

```
POST https://stica.peeringhub.io/acme/authz/D55D90F2F6854D2CBB2E9C4A2E6EC4DB
Content-Type: application/jose+json
Content-Length: 430
{
  "protected" : BASE64URL(
    {
      "alg": "ES256",
      "nonce": "51029A7B34EC4F2280ECD2A6EC4E3C04",
      "url": "https://stica.peeringhub.io/acme/authz/D55D90F2F6854D2CBB2E9C4A2E6EC4DB",
      "kid": "https://stica.peeringhub.io/acme/acct/6A1AD155B73D45448E7B832888C3EF54"
    }
  ),
  "payload" : "",
  "signature" : "<base64url-encoded signature>"
}
```

Server should reply with an ACME Challenge object:

```
HTTP/1.1 200 OK
Replay-Nonce: 46660A480C68453EBB4553C46979B18D
Content-Type: application/json; charset=utf-8
Content-Length: 319
{
  "status": "pending",
  "expires": "2022-08-09T21:49:43Z",
  "identifier": {
    "type": "TNAuthList",
    "value": "MAigBhYEODE4SA=="
  },
  "challenges": [
    {
      "type": "tkauth-01",
      "tkauth-type": "atc",
      "url": "https://stica.peeringhub.io/acme/authz/D55D90F2F6854D2CBB2E9C4A2E6EC4DB/0",
      "token": "45C55E0C1F224377A2DC43915715F426",
      "status": "pending"
    }
  ]
}
```

ACME Challenge object must contain a submission URL, and the current status of the ACME Challenge, which can be one of:

* "pending" - waiting for the challenge submission
* "processing" - validating submitted data
* "valid" - user has successfully passed the challenge
* "invalid" - an error has occurred during challenge processing

If status is "invalid", the "error" parameter must identify the rejection reason.

The "url" parameter represents ACME Challenge Submission URL.

## Challenge submission

To prove ownership of the STI-SP account, ACME client must submit a fresh SPC token to the ACME Challenge Submission URL.

SPC token is a JWT (RFC 7519), signed by the STI Policy Administrator (Iconectiv) with mandatory parameters in the payload:

* TNAuthList list value
* CA flag (whether this SPC token is suitable for issuing End-Entity certificates, or for issuing CA certificates)
* SHA256 fingerprint of the ACME Account key

SPC token payload example for regular (End-Entity) certificates:

```
{
  "exp": 1660523818,
  "jti": "980b0430-1e88-4f0f-91e8-749ad9251851",
  "atc": {
    "tktype": "TNAuthList",
    "tkvalue": "MAigBhYEODE4SA==",
    "ca": false,
    "fingerprint": "SHA256 D8:FC:D2:1E:52:7E:85:A5:DB:34:1F:0A:0A:67:17:55:70:9A:A1:50:34:16:BF:E6:E5:AB:AD:84:73:73:E8:A8"
  }
}
```

ACME client must submit a SPC token to the Challenge submission URL:

```
POST https://stica.peeringhub.io/acme/authz/D55D90F2F6854D2CBB2E9C4A2E6EC4DB/0
Content-Type: application/jose+json
Content-Length: 1236
{
  "protected" : BASE64URL(
    {
      "alg": "ES256",
      "nonce": "46660A480C68453EBB4553C46979B18D",
      "url": "https://stica.peeringhub.io/acme/authz/D55D90F2F6854D2CBB2E9C4A2E6EC4DB/0",
      "kid": "https://stica.peeringhub.io/acme/acct/6A1AD155B73D45448E7B832888C3EF54"
    }
  ),
  "payload" : BASE64URL(
    {
      "atc": "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCIsIng1dSI6Imh0dHBzOi8vYXV0aGVudGljYXRlLWFwaS1zdGcuaWNvbmVjdGl2LmNvbS9kb3dubG9hZC92MS9jZXJ0aWZpY2F0ZS9jZXJ0aWZpY2F0ZUlkXzk4MTYwLmNydCJ9.eyJleHAiOjE2NjA2MDAyMTUsImp0aSI6IjdkOGYzY2VhLTEwMzUtNDA2OC1hMjg1LThkMzg3ODJkNmU4MSIsImF0YyI6eyJ0a3R5cGUiOiJUTkF1dGhMaXN0IiwidGt2YWx1ZSI6Ik1BaWdCaFlFT0RFNFNBPT0iLCJjYSI6ZmFsc2UsImZpbmdlcnByaW50IjoiU0hBMjU2IEQ4OkZDOkQyOjFFOjUyOjdFOjg1OkE1OkRCOjM0OjFGOjBBOjBBOjY3OjE3OjU1OjcwOjlBOkExOjUwOjM0OjE2OkJGOkU2OkU1OkFCOkFEOjg0OjczOjczOkU4OkE4In19.mfplwqUd3Usc6cRmduAQQrkJm8Va1dEDkkBB8ev5x5y7IOcwizpQ940PXkv007QQrcH2SdrJcEZzpJf2EY4l0A"
    }
  ),
  "signature" : "<base64url-encoded signature>"
}
```

On successful submission, ACME server should return 200 OK reply with the ACME Challenge object. Status of the ACME Challenge must be changed to "processing":

```
HTTP/1.1 200 OK
Replay-Nonce: 642DE0D7551E496EADC181C6FC0D1A79
Content-Type: application/json; charset=utf-8
Content-Length: 307
{
  "status": "processing",
  "expires": null,
  "identifier": {
    "type": "TNAuthList",
    "value": "MAigBhYEODE4SA=="
  },
  "challenges": [
    {
      "type": "tkauth-01",
      "tkauth-type": "atc",
      "url": "https://stica.peeringhub.io/acme/authz/D55D90F2F6854D2CBB2E9C4A2E6EC4DB/0",
      "token": "45C55E0C1F224377A2DC43915715F426",
      "status": "processing"
    }
  ]
}
```

ACME client should poll ACME Challenge object, until status of the challenge changes. It's also possible to monitor status by polling ACME Order object.

## CSR submission

Upon challenge validation, ACME Order status must be changed to "ready". Now ACME client should submit a CSR, which will be used to create a certificate.

The CSR for Service Providers must follow these rules:

* CSR must contain a TNAuthList X509v3 extension (OID 1.3.6.1.5.5.7.1.26)
* Country (DN: C) must be set to "US"
* Organization (DN: O) must be non-empty
* Common Name (DN: CN) parameter must contain the word "SHAKEN" and OCN

CSR cannot contain CRL Distribution Points others than the official PA CRL: <https://authenticate-api.iconectiv.com/download/v1/crl>

If CRL Distribution Points are not included in the CSR, they will be added automatically by the ACME server.

CSR example for Service Providers:

```
Certificate Request:
    Data:
        Version: 3 (0x2)
        Subject: C = US, O = My Company, CN = My Company SHAKEN 818H
        Subject Public Key Info:
            Public Key Algorithm: id-ecPublicKey
                Public-Key: (256 bit)
                pub:
                    04:e2:71:ce:0e:6c:a9:6e:77:ca:74:97:7e:23:16:
                    cc:b0:bc:0e:b4:9a:82:d1:f3:f2:b2:a2:85:bb:c7:
                    2c:b0:46:bb:93:1c:04:77:cf:5e:41:6f:94:7b:45:
                    33:7f:06:12:63:22:bf:6a:30:1f:13:da:c2:95:9f:
                    1f:5e:d8:d0:c6
                ASN1 OID: prime256v1
                NIST CURVE: P-256
        Attributes:
        Requested Extensions:
            X509v3 Basic Constraints: critical
                CA:FALSE
            1.3.6.1.5.5.7.1.26:
                0.....818H
            X509v3 CRL Distribution Points:

                Full Name:
                  URI:https://authenticate-api.iconectiv.com/download/v1/crl
                CRL Issuer:
                  DirName:L = Bridgewater, ST = NJ, CN = STI-PA CRL, C = US, O = STI-PA

    Signature Algorithm: ecdsa-with-SHA256
         30:45:02:21:00:de:7f:3c:b2:81:ac:ab:df:ce:fb:47:02:34:
         d2:4e:1b:da:32:cc:6f:e3:87:0f:20:ba:7a:fd:81:04:69:cb:
         1a:02:20:53:70:5a:9f:20:de:56:bc:14:ea:9d:c8:5e:1a:04:
         df:80:43:5e:25:9b:29:6d:33:a5:90:d1:ae:19:3f:8c:d8
```

The URL to upload CSR can be found in the "finalize" parameter of the ACME Order object.

```
POST https://stica.peeringhub.io/acme/order/0E22FC02933D42BC86A64425BB20D4B0/finalize
Content-Type: application/jose+json
Content-Length: 1329
{
  "protected" : BASE64URL(
    {
      "alg": "ES256",
      "nonce": "7D36B55C9F9349269AD08024868D72F0",
      "url": "https://stica.peeringhub.io/acme/order/0E22FC02933D42BC86A64425BB20D4B0/finalize",
      "kid": "https://stica.peeringhub.io/acme/acct/6A1AD155B73D45448E7B832888C3EF54"
    }
  ),
  "payload" : BASE64URL(
    {
      "csr" : "MIIB5zCCAY0CAQIwQzELMAkGA1UEBhMCVVMxEzARBgNVBAoMCk15IENvbXBhbnkxHzAdBgNVBAMMFk15IENvbXBhbnkgU0hBS0VOIDgxOEgwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATicc4ObKlud8p0l34jFsywvA60moLR8_KyooW7xyywRruTHAR3z15Bb5R7RTN_BhJjIr9qMB8T2sKVnx9e2NDGoIHnMIHkBgkqhkiG9w0BCQ4xgdYwgdMwDAYDVR0TAQH_BAIwADAWBggrBgEFBQcBGgQKMAigBhYEODE4SDCBqgYDVR0fBIGiMIGfMIGcoD6gPIY6aHR0cHM6Ly9hdXRoZW50aWNhdGUtYXBpLXN0Zy5pY29uZWN0aXYuY29tL2Rvd25sb2FkL3YxL2NybKJapFgwVjEUMBIGA1UEBwwLQnJpZGdld2F0ZXIxCzAJBgNVBAgMAk5KMRMwEQYDVQQDDApTVEktUEEgQ1JMMQswCQYDVQQGEwJVUzEPMA0GA1UECgwGU1RJLVBBMAoGCCqGSM49BAMCA0gAMEUCIQDefzyygayr3877RwI00k4b2jLMb-OHDyC6ev2BBGnLGgIgU3BanyDeVrwU6p3IXhoE34BDXiWbKW0zpZDRrhk_jNg"
    }
  ),
  "signature" : "<base64url-encoded signature>"
}
```

On success, ACME server should return 200 OK with the ACME Order object. The status of the order must be changed to "processing".

```
HTTP/1.1 200 OK
Replay-Nonce: 756289D54E5F41A08C8D6C3A38DCB4C2
Content-Type: application/json; charset=utf-8
Content-Length: 380
{
  "status" : "processing",
  "expires" : null,
  "identifiers" : [{ "type" : "TNAuthList", "value" : "MAigBhYEODE4SA==" }],
  "notBefore" : "2022-08-08T21:48:20Z",
  "notAfter" : "2022-08-08T21:53:20Z",
  "error" : null,
  "authorizations" : [
    "https://stica.peeringhub.io/acme/authz/D55D90F2F6854D2CBB2E9C4A2E6EC4DB"
  ],
  "finalize" : "https://stica.peeringhub.io/acme/order/0E22FC02933D42BC86A64425BB20D4B0/finalize"
}
```

ACME client should poll ACME Order object until status of the order changes.

## Certificate downloading

When ACME Order was successfully processed, status of the order should change to "valid", and URL to download the certificate must appear in the "certificate" parameter of the ACME Order object:

```
{
  "status": "valid",
  "expires": "2022-08-15T21:49:43Z",
  "identifiers": [
    {
      "type": "TNAuthList",
      "value": "MAigBhYEODE4SA=="
    }
  ],
  "notBefore": "2022-08-08T21:48:20Z",
  "notAfter": "2022-08-08T21:53:20Z",
  "error": null,
  "authorizations": [
    "https://stica.peeringhub.io/acme/authz/D55D90F2F6854D2CBB2E9C4A2E6EC4DB"
  ],
  "finalize": "https://stica.peeringhub.io/acme/order/0E22FC02933D42BC86A64425BB20D4B0/finalize",
  "certificate": "https://stica.peeringhub.io/acme/cert/2AC5775167C04A34A140033CD5DF4088"
}
```

To download the certificate, ACME client must send a POST request with an empty payload to the Certificate URL:

```
POST https://stica.peeringhub.io/acme/cert/2AC5775167C04A34A140033CD5DF4088
Content-Type: application/jose+json
Content-Length: 429
{
  "protected" : BASE64URL(
    {
      "alg": "ES256",
      "nonce": "B536FD57B6874F6AB0128D7F75AC57C8",
      "url": "https://stica.peeringhub.io/acme/cert/2AC5775167C04A34A140033CD5DF4088",
      "kid": "https://stica.peeringhub.io/acme/acct/6A1AD155B73D45448E7B832888C3EF54"
    }
  ),
  "payload" : "",
  "signature" : "<base64url-encoded signature>"
}

HTTP/1.1 200 OK
Replay-Nonce: 5E8226C64D4A46D39E177E9A48A48757
Content-Type: application/pem-certificate-chain
Content-Length: 2250
-----BEGIN CERTIFICATE-----
MIIDBTCCAqugAwIBAgIRAKE+kaZYDgRX2HxVA0XC4hQwCgYIKoZIzj0EAwIwgYAx
CzAJBgNVBAYTAlVTMRcwFQYDVQQKDA5QZWVyaW5naHViIEluYzEiMCAGA1UECwwZ
Q2VydGlmaWNhdGlvbiBBdXRob3JpdGllczE0MDIGA1UEAwwrUGVlcmluZ2h1YiBJ
bmMgU0hBS0VOIEludGVybWVkaWF0ZSBDQSBERVYgMTAeFw0yMjA4MDgyMTQ4MjBa
Fw0yMjA4MDgyMTUzMjBaMEMxCzAJBgNVBAYTAlVTMRMwEQYDVQQKDApNeSBDb21w
YW55MR8wHQYDVQQDDBZNeSBDb21wYW55IFNIQUtFTiA4MThIMFkwEwYHKoZIzj0C
AQYIKoZIzj0DAQcDQgAE4nHODmypbnfKdJd+IxbMsLwOtJqC0fPysqKFu8cssEa7
kxwEd89eQW+Ue0UzfwYSYyK/ajAfE9rClZ8fXtjQxqOCAUAwggE8MA4GA1UdDwEB
/wQEAwIHgDAMBgNVHRMBAf8EAjAAMB0GA1UdDgQWBBSZPHgWeG3E41G0jPamaOCs
qzdnwzAfBgNVHSMEGDAWgBQi3nU+1F4Iav8BHOp948c5U0KXBTAXBgNVHSAEEDAO
MAwGCmCGSAGG/wkBAQEwFgYIKwYBBQUHARoECjAIoAYWBDgxOEgwgaoGA1UdHwSB
ojCBnzCBnKA+oDyGOmh0dHBzOi8vYXV0aGVudGljYXRlLWFwaS1zdGcuaWNvbmVj
dGl2LmNvbS9kb3dubG9hZC92MS9jcmyiWqRYMFYxFDASBgNVBAcMC0JyaWRnZXdh
dGVyMQswCQYDVQQIDAJOSjETMBEGA1UEAwwKU1RJLVBBIENSTDELMAkGA1UEBhMC
VVMxDzANBgNVBAoMBlNUSS1QQTAKBggqhkjOPQQDAgNIADBFAiEA0PT6Q4T+MmpJ
LoU+L72OaxbeyR4kJ8CtxcIGi0zC3SYCIF/BeD/1rlmHz9tsFi6npCMrtVJW1SQi
Dn7X5e9EsoDh
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIDHzCCAsSgAwIBAgIQcuK74nt/PaLZWsRJjaJ2KTAKBggqhkjOPQQDAjB2MQsw
CQYDVQQGEwJVUzEXMBUGA1UECgwOUGVlcmluZ2h1YiBJbmMxIjAgBgNVBAsMGUNl
cnRpZmljYXRpb24gQXV0aG9yaXRpZXMxKjAoBgNVBAMMIVBlZXJpbmdodWIgSW5j
IFNIQUtFTiBST09UIENBIERFVjAeFw0yMjA0MjUyMzQ4MjBaFw0zMjA0MjIyMzQ4
MjBaMIGAMQswCQYDVQQGEwJVUzEXMBUGA1UECgwOUGVlcmluZ2h1YiBJbmMxIjAg
BgNVBAsMGUNlcnRpZmljYXRpb24gQXV0aG9yaXRpZXMxNDAyBgNVBAMMK1BlZXJp
bmdodWIgSW5jIFNIQUtFTiBJbnRlcm1lZGlhdGUgQ0EgREVWIDEwWTATBgcqhkjO
PQIBBggqhkjOPQMBBwNCAARydOBhM+X8nK9TqzW57TVn+ulVnSLWERRAlYCWQGkA
jMBsmQYI5Aw3ULim76WEzyZUJKOyCYLPcyaiqKa7It/Qo4IBJzCCASMwDgYDVR0P
AQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFCLedT7UXghq/wEc
6n3jxzlTQpcFMB8GA1UdIwQYMBaAFCdr86ngPMbyxZYnJzBTcRR6B5CvMBcGA1Ud
IAQQMA4wDAYKYIZIAYb/CQEBATCBpgYDVR0fBIGeMIGbMIGYoDqgOIY2aHR0cHM6
Ly9hdXRoZW50aWNhdGUtYXBpLmljb25lY3Rpdi5jb20vZG93bmxvYWQvdjEvY3Js
olqkWDBWMQswCQYDVQQGEwJVUzELMAkGA1UECAwCTkoxFDASBgNVBAcMC0JyaWRn
ZXdhdGVyMQ8wDQYDVQQKDAZTVEktUEExEzARBgNVBAMMClNUSS1QQSBDUkwwCgYI
KoZIzj0EAwIDSQAwRgIhAKuc7n7u9ukR+BnJFtNUt3y0nAsxaBjZ06CWfneMmtvp
AiEA//1yCI+VNLXLnmutrq83R3x3m8bJnobZj7A0/PM3ZQI=
-----END CERTIFICATE-----
```

Note, that the Certificate URL is not public, and can only be accessed with a signed POST request.

## Review the certificate

The created certificate must have:

* A valid lifespan (notBefore and notAfter parameters)
* The requested Common Name
* TNAuthList extension
* CRL extension with URL of the official PA CRL
* Basic Constraints extension, which identifies the type of the certificate (End-Entity or SCA)
* 2.16.840.1.114569.1.1.1 certificate policy

```
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            a1:3e:91:a6:58:0e:04:57:d8:7c:55:03:45:c2:e2:14
        Signature Algorithm: ecdsa-with-SHA256
        Issuer: C = US, O = Peeringhub Inc, OU = Certification Authorities, CN = Peeringhub Inc SHAKEN Intermediate CA
        Validity
            Not Before: Aug  8 21:48:20 2022 GMT
            Not After : Aug  8 21:53:20 2022 GMT
        Subject: C = US, O = My Company, CN = My Company SHAKEN 818H
        Subject Public Key Info:
            Public Key Algorithm: id-ecPublicKey
                Public-Key: (256 bit)
                pub:
                    04:e2:71:ce:0e:6c:a9:6e:77:ca:74:97:7e:23:16:
                    cc:b0:bc:0e:b4:9a:82:d1:f3:f2:b2:a2:85:bb:c7:
                    2c:b0:46:bb:93:1c:04:77:cf:5e:41:6f:94:7b:45:
                    33:7f:06:12:63:22:bf:6a:30:1f:13:da:c2:95:9f:
                    1f:5e:d8:d0:c6
                ASN1 OID: prime256v1
                NIST CURVE: P-256
        X509v3 extensions:
            X509v3 Key Usage: critical
                Digital Signature
            X509v3 Basic Constraints: critical
                CA:FALSE
            X509v3 Subject Key Identifier:
                99:3C:78:16:78:6D:C4:E3:51:B4:8C:F6:A6:68:E0:AC:AB:37:67:C3
            X509v3 Authority Key Identifier:
                keyid:22:DE:75:3E:D4:5E:08:6A:FF:01:1C:EA:7D:E3:C7:39:53:42:97:05

            X509v3 Certificate Policies:
                Policy: 2.16.840.1.114569.1.1.1

            1.3.6.1.5.5.7.1.26:
                0.....818H
            X509v3 CRL Distribution Points:

                Full Name:
                  URI:https://authenticate-api.iconectiv.com/download/v1/crl
                CRL Issuer:
                  DirName:L = Bridgewater, ST = NJ, CN = STI-PA CRL, C = US, O = STI-PA

    Signature Algorithm: ecdsa-with-SHA256
         30:45:02:21:00:d0:f4:fa:43:84:fe:32:6a:49:2e:85:3e:2f:
         bd:8e:6b:16:de:c9:1e:24:27:c0:ad:c5:c2:06:8b:4c:c2:dd:
         26:02:20:5f:c1:78:3f:f5:ae:59:87:cf:db:6c:16:2e:a7:a4:
         23:2b:b5:52:56:d5:24:22:0e:7e:d7:e5:ef:44:b2:80:e1
```


# List active orders

All completed orders are available on the server for at least 1 week. ACME client can list all active orders using the URL from the "orders" item of the ACME Account object:

```
POST https://stica.peeringhub.io/acme/orders/6A1AD155B73D45448E7B832888C3EF54
Content-Type: application/jose+json
Content-Length: 432
{
  "protected" : BASE64URL(
    {
      "alg": "ES256",
      "nonce": "A1D5D59169B8441B939843C0605BCD28",
      "url": "https://stica.peeringhub.io/acme/orders/6A1AD155B73D45448E7B832888C3EF54",
      "kid": "https://stica.peeringhub.io/acme/acct/6A1AD155B73D45448E7B832888C3EF54"
    }
  ),
  "payload" : "",
  "signature" : "<base64url-encoded signature>"
}
```

ACME server must return an array of ACME Order URL strings:

```
HTTP/1.1 200 OK
Replay-Nonce: 5962FB340B1D4C61B7E402513F018460
Content-Type: application/json; charset=utf-8
Content-Length: 168
{
  "orders": [
    "https://stica.peeringhub.io/acme/order/B572A9240F244CCB8716CC5B6853A22D",
    "https://stica.peeringhub.io/acme/order/0E22FC02933D42BC86A64425BB20D4B0"
  ]
}
```

Failed orders are kept available for at least one day.


# Key change

User is able to change the public key, associated with the ACME Account, without losing the history of orders. To do so, ACME client must send a new key to the keyChange URL.

The JWS must be signed with the old key. JWS payload must contain a base64url-encoded "inner JWS" with the new key in the protected header, and the old key in the payload. The "inner JWS" must be signed with the new key.

```
POST https://stica.peeringhub.io/acme/key-change
Content-Type: application/jose+json
Content-Length: 1464
{
  "protected" : BASE64URL(
    {
      "alg": "ES256",
      "nonce": "BCFAB5246CC547FDBDBFB07251E73A40",
      "url": "https://stica.peeringhub.io/acme/key-change",
      "kid": "https://stica.peeringhub.io/acme/acct/6A1AD155B73D45448E7B832888C3EF54"
    }
  ),
  "payload" : BASE64URL(
    {
      "protected" : BASE64URL(
        {
          "alg": "ES256",
          "jwk": {
            "kty": "EC",
            "crv": "P-256",
            "x": "I-3Vr9qBQJR7GOgRJ7uWj_6t0AO-Nh5fZnXZSzgOHsI",
            "y": "4Qhp5jZI3v8lwYDK9FJNzUN3fvL_FeeeSMb2vHlOzSI",
            "kid": "NEW KEY"
          },
          "url": "https://stica.peeringhub.io/acme/key-change"
        }
      ),
      "payload" : BASE64URL(
        {
          "account": "https://stica.peeringhub.io/acme/acct/6A1AD155B73D45448E7B832888C3EF54",
          "oldKey": {
            "kty": "EC",
            "crv": "P-256",
            "x": "4nHODmypbnfKdJd-IxbMsLwOtJqC0fPysqKFu8cssEY",
            "y": "u5McBHfPXkFvlHtFM38GEmMiv2owHxPawpWfH17Y0MY",
            "kid": "OLD key"
          }
        }
      ),
      "signature" : "<base64url-encoded signature created with the NEW key>"
    }
  ),
  "signature" : "<base64url-encoded signature created with the OLD key>"
}
```

On success, server must return an empty 200 OK reply:

```
HTTP/1.1 200 OK
Replay-Nonce: 367CB73114264084A3BA0087AD97E88E
Content-Length: 0
```


# Account deactivation

User may deactivate their account if the associated key was compromised, or must be forgotten. To do this, ACME client must send a POST request to the ACME Account URL:

```
POST https://stica.peeringhub.io/acme/acct/6A1AD155B73D45448E7B832888C3EF54
Content-Type: application/jose+json
Content-Length: 461
{
  "protected" : BASE64URL(
    {
      "alg": "ES256",
      "nonce": "7699E1AAD33D492ABB7D5A5326DC7D41",
      "url": "https://stica.peeringhub.io/acme/acct/6A1AD155B73D45448E7B832888C3EF54",
      "kid": "https://stica.peeringhub.io/acme/acct/6A1AD155B73D45448E7B832888C3EF54"
    }
  ),
  "payload" : BASE64URL(
    {
      "status" : "deactivated"
    }
  ),
  "signature" : "<base64url-encoded signature>"
}
```

ACME server shall return 200 OK with the ACME Account object. Account status must be changed to "deactivated".

```
HTTP/1.1 200 OK
Replay-Nonce: 6ECE0681255347D0BB29FCE79E895FF1
Content-Type: application/json; charset=utf-8
Content-Length: 112
{
  "status" : "deactivated",
  "orders" : "https://stica.peeringhub.io/acme/orders/6A1AD155B73D45448E7B832888C3EF54"
}
```

ACME server doesn't provide interface for re-enabling account after deactivation.


# Desktop Client

{% hint style="info" %}
**Good to know:** Before using Peeringhub's ACME Client to request for Stir/Shaken certificate, you must make sure that your OCN is whitelisted in Peeringhub's ACME server by completing the online subscription process.&#x20;
{% endhint %}

## ACME Client Download Instruction

Peeringhub's subscribers can download ACME Client via the URL.

Linux Centos version:

> <https://github.com/peeringhub/RHEL-ACME-Cllient>

Windows version:

> <https://github.com/peeringhub/Windows-ACME-Client>


# Windows Command Line Client

### Install OpenSSL

You need to install OpenSSL to generate a private key.  Your private key should be stored in a secure place.  You will need to use your private key to generate Stir/Shaken Certificate and to sign calls.&#x20;

Here is [instruction](https://www.xolphin.com/support/OpenSSL/OpenSSL_-_Installation_under_Windows) on how to install OpenSSL.

### Generate Private Key

The preferred way to do this is with OpenSSL (supported by almost every platform out there including Windows, Linux & Mac). To install on Windows, you can view installers at the [OpenSSL Binary Wiki](https://wiki.openssl.org/index.php/Binaries) page or go to [Shining Light Productions](https://slproweb.com/products/Win32OpenSSL.html) page (also listed on the Wiki); or most installations, you need Win64 - the Light (drastically smaller download) version will be fine (either 1.1.1 or 1.0.2).\
&#x20;\
Now, let's generate an **unencrypted** private key:

```
openssl ecparam -name prime256v1 -genkey -noout -out private_key.pem
```

\
![](https://support.cerberusftp.com/attachments/token/FvS1CNCmzEjjnoQ1JtPVr46hj/?name=inlineImage.png)

### Download Peeringhub's ACME Client

You can download Peeringhub's ACME Client from:

> <https://github.com/peeringhub/Windows-ACME-Client>

You can download all the files as one ZIP file by using the Download ZIP button:

![](/files/utKPD7K10uPz6esVGWxP)

You can save the ZIP file in a directory and unzip the file.  You should see all these files in your folder:

![](/files/bjhtKxW9Wt5bBzq2Cz4Z)

### Open command line windows

You can read this [articles](https://www.howtogeek.com/235101/10-ways-to-open-the-command-prompt-in-windows-10/) to use one of the suggested methods to open a command line window.

### Create a acme\_client.conf file

You need to create a ACME\_client.conf file with the following content:

```

## Production ACME client configuration## ACME server URLserver_url	
https://stica.peeringhub.io/acme
# Public key 
IDkid		ICX

## Iconectiv configuration#

user_id		        <your iConnectiv username>
password		<your iConnectiv password>
pa_staging		false
pa_trace		false

# EOF
```

### Generate SPC Token

You can run the following command to generate SPC token:

{% code overflow="wrap" %}

```
acme_cli_client.exe -c acme_client.conf gen_spc  private_key_path my_ocn
```

{% endcode %}

The response of "gen\_spc" command is as follows:

{% code overflow="wrap" %}

```
2022-10-01 02:47:16  INFO Using configuration file: 'acme_client.conf'
2022-10-01 02:47:16  INFO

eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCIsIng1dSI6Imh0dHBzOi8vYXV0aGVudGljYXRlLWFwaS1zdGcuaWNvbmVjdGl2LmNvbS9kb3dubG9hZC92MS9jZXJ0aWZpY2F0ZS9jZXJ0aWZpY2F0ZUlkXzEwMDAxMS5jcnQifQ.eyJleHAiOjE3Mjc2ODk2NDksImp0aSI6IjM4NWNhMWM2LWNhM2ItNGM5Zi1hODY4LWJmMTAzZTZhNmEwNyIsImF0YyI6eyJ0a3R5cGUiOiJUTkF1dGhMaXN0IiwidGt2YWx1ZSxk1BaWdCaFlFT0RJd1NnPT0iLCJjYSI6ZmFsc2UsImZpbmdlcnByaW50IjoiU0hBMjU2IDQzOjIzOkI1Ojg4OjkwOjE1OkI3OjhGOjU5OjVFOkZEOjUxOjg5OkI5OjJCOjlGOkMxOkRDOkZCOkM0OkREOjYzOjc5OjE5OjA0OjE0Ojg3OjAxOjg4OjA1OjhBOkJDIn19.1fC2Jnc0u5Q-SnGp6h0bhpQc_j3yhPkFTPTxtDWZy2QfhaDIx8w8TjJgWykSx_GdhYOZTyfAX8QXkHLfYEi-Dw
```

{% endcode %}

### Generate Stir/Shaken Certificate

{% code overflow="wrap" %}

```
acme_cli_client.exe -c acme_client.conf  --spc <path_to_spc_token_file> new_order <path_to_private_key_file>  <ocn> 0 0 C=US S=AZ L=Phoenix O="<organization anem>" CN="orig_name SHAKEN OCN"
```

{% endcode %}

The result you get should be as follows:

{% code overflow="wrap" %}

```
2022-10-01 02:05:48  INFO Using configuration file: 'acme_client.conf'
2022-10-01 02:05:48  INFO

2022-10-01 02:05:48  INFO ACME server 'https://stica-dev.peeringhub.io/acme':
  > new nonce: https://stica-dev.peeringhub.io/acme/new-nonce
  > new account: https://stica-dev.peeringhub.io/acme/new-account
  > key change: https://stica-dev.peeringhub.io/acme/key-change
  > new order: https://stica-dev.peeringhub.io/acme/new-order
2022-10-01 02:05:48  INFO

2022-10-01 02:05:50  INFO Order 'https://stica-dev.peeringhub.io/acme/order/D67985F16A8D49EEA8514870B4D90942'
  > expires: '2022-10-01T23:05:51Z'
  > TNAuthList: 'MAigBhYEODIwSg=='
  > OCN: '820J'
  > notBefore: 'n/a'
  > notAfter: 'n/a'
  > status: 'pending'
  > error: ''
  > authz: 'https://stica-dev.peeringhub.io/acme/authz/8962916A9CB74AF6BAB7953787B92599'
  > finalize: 'https://stica-dev.peeringhub.io/acme/order/D67985F16A8D49EEA8514870B4D90942/finalize'
  > certificate: ''
2022-10-01 02:05:50  INFO

2022-10-01 02:05:50  INFO Challenge 'https://stica-dev.peeringhub.io/acme/authz/8962916A9CB74AF6BAB7953787B92599'
  > submit url: 'https://stica-dev.peeringhub.io/acme/authz/8962916A9CB74AF6BAB7953787B92599/0'
  > status: 'pending'
  > error: ''
  > validated: 'n/a'
2022-10-01 02:05:50  INFO

2022-10-01 02:05:50  INFO Using SPC token file: 'icx.spc.txt'
2022-10-01 02:05:50  INFO

2022-10-01 02:05:53  INFO Challenge 'https://stica-dev.peeringhub.io/acme/authz/8962916A9CB74AF6BAB7953787B92599'
  > submit url: 'https://stica-dev.peeringhub.io/acme/authz/8962916A9CB74AF6BAB7953787B92599/0'
  > status: 'valid'
  > error: ''
  > validated: '2022-09-30T23:05:53Z'
2022-10-01 02:05:53  INFO

2022-10-01 02:05:53  INFO Challenge passed
2022-10-01 02:05:53  INFO

2022-10-01 02:05:54  INFO Order 'https://stica-dev.peeringhub.io/acme/order/D67985F16A8D49EEA8514870B4D90942'
  > expires: '2022-10-01T23:05:51Z'
  > TNAuthList: 'MAigBhYEODIwSg=='
  > OCN: '820J'
  > notBefore: 'n/a'
  > notAfter: 'n/a'
  > status: 'ready'
  > error: ''
  > authz: 'https://stica-dev.peeringhub.io/acme/authz/8962916A9CB74AF6BAB7953787B92599'
  > finalize: 'https://stica-dev.peeringhub.io/acme/order/D67985F16A8D49EEA8514870B4D90942/finalize'
  > certificate: ''
2022-10-01 02:05:54  INFO

2022-10-01 02:05:55  INFO Order 'https://stica-dev.peeringhub.io/acme/order/D67985F16A8D49EEA8514870B4D90942'
  > expires: '2022-10-07T23:05:51Z'
  > TNAuthList: 'MAigBhYEODIwSg=='
  > OCN: '820J'
  > notBefore: 'n/a'
  > notAfter: 'n/a'
  > status: 'valid'
  > error: ''
  > authz: 'https://stica-dev.peeringhub.io/acme/authz/8962916A9CB74AF6BAB7953787B92599'
  > finalize: 'https://stica-dev.peeringhub.io/acme/order/D67985F16A8D49EEA8514870B4D90942/finalize'
  > certificate: 'https://stica-dev.peeringhub.io/acme/cert/1562B94280A04A76899AA6E467BEC01B'
2022-10-01 02:05:55  INFO

2022-10-01 02:05:55  INFO Certificate created
2022-10-01 02:05:55  INFO

2022-10-01 02:05:55  INFO Successfully issued a new End Entity certificate for 810K
2022-10-01 02:05:55  INFO

-----BEGIN CERTIFICATE-----
MIIDFTCCArygAwIBAgIRANnA0y2rL9vePtscT/Edyy8wCgYIKoZIzj0EAwIwgYAx
CzAJBgNVBAYTAlVTMRcwFQYDVQQKDA5QZWVyaW5naHViIEluYzEiMCAGA1UECwwZ
Q2VydGlmaWNhdGlvbiBBdXRob3JpdGllczE0MDIGA1UEAwwrUGVlcmluZ2h1YiBJ
bmMgU0hBS0VOIEludGVybWVkaWF0ZSBDQSBERVYgMTAeFw0yMjEwMDEwOTA1NTZa
Fw0yMzEwMDEwOTA1NTZaMFQxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJBWjEQMA4G
A1UEBwwHUGhvZW5peDEMMAoGA1UECgwDSUNYMRgwFgYDVQQDDA9JQ1ggU0hBS0VO
IDgyMEowWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAQl6Llcx1C9nyCg9OvOWJhj
dfbTyyU2jcyIHFaSr/62Fy8iP9TZV6nkILbE2vFtondqqIc1Tcd42nwxprG1gDv5
o4IBQDCCATwwDgYDVR0PAQH/BAQDAgeAMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYE
FAr1Mn8Um8BY5l48bgu470CExKY0MB8GA1UdIwQYMBaAFCLedT7UXghq/wEc6n3j
xzlTQpcFMBcGA1UdIAQQMA4wDAYKYIZIAYb/CQEBATAWBggrBgEFBQcBGgQKMAig
BhYEODIwSjCBqgYDVR0fBIGiMIGfMIGcoD6gPIY6aHR0cHM6Ly9hdXRoZW50aWNh
dGUtYXBpLXN0Zy5pY29uZWN0aXYuY29tL2Rvd25sb2FkL3YxL2NybKJapFgwVjEU
MBIGA1UEBwwLQnJpZGdld2F0ZXIxCzAJBgNVBAgMAk5KMRMwEQYDVQQDDApTVEkt
UEEgQ1JMMQswCQYDVQQGEwJVUzEPMA0GA1UECgwGU1RJLVBBMAoGCCqGSM49BAMC
A0cAMEQCIH9Jna1FOmHK6FIsZZcaoHdyV/AT9Q544EY7V8sgYPLCAiAhC7kQOIFn
M97IAsN6phEKvgs0+lLHbYon5Mm3gx8X3w==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIDHzCCAsSgAwIBAgIQcuK74nt/PaLZWsRJjaJ2KTAKBggqhkjOPQQDAjB2MQsw
CQYDVQQGEwJVUzEXMBUGA1UECgwOUGVlcmluZ2h1YiBJbmMxIjAgBgNVBAsMGUNl
cnRpZmljYXRpb24gQXV0aG9yaXRpZXMxKjAoBgNVBAMMIVBlZXJpbmdodWIgSW5j
IFNIQUtFTiBST09UIENBIERFVjAeFw0yMjA0MjUyMzQ4MjBaFw0zMjA0MjIyMzQ4
MjBaMIGAMQswCQYDVQQGEwJVUzEXMBUGA1UECgwOUGVlcmluZ2h1YiBJbmMxIjAg
BgNVBAsMGUNlcnRpZmljYXRpb24gQXV0aG9yaXRpZXMxNDAyBgNVBAMMK1BlZXJp
bmdodWIgSW5jIFNIQUtFTiBJbnRlcm1lZGlhdGUgQ0EgREVWIDEwWTATBgcqhkjO
PQIBBggqhkjOPQMBBwNCAARydOBhM+X8nK9TqzW57TVn+ulVnSLWERRAlYCWQGkA
jMBsmQYI5Aw3ULim76WEzyZUJKOyCYLPcyaiqKa7It/Qo4IBJzCCASMwDgYDVR0P
AQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFCLedT7UXghq/wEc
6n3jxzlTQpcFMB8GA1UdIwQYMBaAFCdr86ngPMbyxZYnJzBTcRR6B5CvMBcGA1Ud
IAQQMA4wDAYKYIZIAYb/CQEBATCBpgYDVR0fBIGeMIGbMIGYoDqgOIY2aHR0cHM6
Ly9hdXRoZW50aWNhdGUtYXBpLmljb25lY3Rpdi5jb20vZG93bmxvYWQvdjEvY3Js
olqkWDBWMQswCQYDVQQGEwJVUzELMAkGA1UECAwCTkoxFDASBgNVBAcMC0JyaWRn
ZXdhdGVyMQ8wDQYDVQQKDAZTVEktUEExEzARBgNVBAMMClNUSS1QQSBDUkwwCgYI
KoZIzj0EAwIDSQAwRgIhAKuc7n7u9ukR+BnJFtNUt3y0nAsxaBjZ06CWfneMmtvp
AiEA//1yCI+VNLXLnmutrq83R3x3m8bJnobZj7A0/PM3ZQI=
-----END CERTIFICATE-----
```

{% endcode %}

### Host Stir/Shaken Certificate in a CR

You need to store this following part of the result from the new\_order command to a file:

```
-----BEGIN CERTIFICATE-----
MIIDFTCCArygAwIBAgIRANnA0y2rL9vePtscT/Edyy8wCgYIKoZIzj0EAwIwgYAx
CzAJBgNVBAYTAlVTMRcwFQYDVQQKDA5QZWVyaW5naHViIEluYzEiMCAGA1UECwwZ
Q2VydGlmaWNhdGlvbiBBdXRob3JpdGllczE0MDIGA1UEAwwrUGVlcmluZ2h1YiBJ
bmMgU0hBS0VOIEludGVybWVkaWF0ZSBDQSBERVYgMTAeFw0yMjEwMDEwOTA1NTZa
Fw0yMzEwMDEwOTA1NTZaMFQxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJBWjEQMA4G
A1UEBwwHUGhvZW5peDEMMAoGA1UECgwDSUNYMRgwFgYDVQQDDA9JQ1ggU0hBS0VO
IDgyMEowWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAQl6Llcx1C9nyCg9OvOWJhj
dfbTyyU2jcyIHFaSr/62Fy8iP9TZV6nkILbE2vFtondqqIc1Tcd42nwxprG1gDv5
o4IBQDCCATwwDgYDVR0PAQH/BAQDAgeAMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYE
FAr1Mn8Um8BY5l48bgu470CExKY0MB8GA1UdIwQYMBaAFCLedT7UXghq/wEc6n3j
xzlTQpcFMBcGA1UdIAQQMA4wDAYKYIZIAYb/CQEBATAWBggrBgEFBQcBGgQKMAig
BhYEODIwSjCBqgYDVR0fBIGiMIGfMIGcoD6gPIY6aHR0cHM6Ly9hdXRoZW50aWNh
dGUtYXBpLXN0Zy5pY29uZWN0aXYuY29tL2Rvd25sb2FkL3YxL2NybKJapFgwVjEU
MBIGA1UEBwwLQnJpZGdld2F0ZXIxCzAJBgNVBAgMAk5KMRMwEQYDVQQDDApTVEkt
UEEgQ1JMMQswCQYDVQQGEwJVUzEPMA0GA1UECgwGU1RJLVBBMAoGCCqGSM49BAMC
A0cAMEQCIH9Jna1FOmHK6FIsZZcaoHdyV/AT9Q544EY7V8sgYPLCAiAhC7kQOIFn
M97IAsN6phEKvgs0+lLHbYon5Mm3gx8X3w==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIDHzCCAsSgAwIBAgIQcuK74nt/PaLZWsRJjaJ2KTAKBggqhkjOPQQDAjB2MQsw
CQYDVQQGEwJVUzEXMBUGA1UECgwOUGVlcmluZ2h1YiBJbmMxIjAgBgNVBAsMGUNl
cnRpZmljYXRpb24gQXV0aG9yaXRpZXMxKjAoBgNVBAMMIVBlZXJpbmdodWIgSW5j
IFNIQUtFTiBST09UIENBIERFVjAeFw0yMjA0MjUyMzQ4MjBaFw0zMjA0MjIyMzQ4
MjBaMIGAMQswCQYDVQQGEwJVUzEXMBUGA1UECgwOUGVlcmluZ2h1YiBJbmMxIjAg
BgNVBAsMGUNlcnRpZmljYXRpb24gQXV0aG9yaXRpZXMxNDAyBgNVBAMMK1BlZXJp
bmdodWIgSW5jIFNIQUtFTiBJbnRlcm1lZGlhdGUgQ0EgREVWIDEwWTATBgcqhkjO
PQIBBggqhkjOPQMBBwNCAARydOBhM+X8nK9TqzW57TVn+ulVnSLWERRAlYCWQGkA
jMBsmQYI5Aw3ULim76WEzyZUJKOyCYLPcyaiqKa7It/Qo4IBJzCCASMwDgYDVR0P
AQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFCLedT7UXghq/wEc
6n3jxzlTQpcFMB8GA1UdIwQYMBaAFCdr86ngPMbyxZYnJzBTcRR6B5CvMBcGA1Ud
IAQQMA4wDAYKYIZIAYb/CQEBATCBpgYDVR0fBIGeMIGbMIGYoDqgOIY2aHR0cHM6
Ly9hdXRoZW50aWNhdGUtYXBpLmljb25lY3Rpdi5jb20vZG93bmxvYWQvdjEvY3Js
olqkWDBWMQswCQYDVQQGEwJVUzELMAkGA1UECAwCTkoxFDASBgNVBAcMC0JyaWRn
ZXdhdGVyMQ8wDQYDVQQKDAZTVEktUEExEzARBgNVBAMMClNUSS1QQSBDUkwwCgYI
KoZIzj0EAwIDSQAwRgIhAKuc7n7u9ukR+BnJFtNUt3y0nAsxaBjZ06CWfneMmtvp
AiEA//1yCI+VNLXLnmutrq83R3x3m8bJnobZj7A0/PM3ZQI=
-----END CERTIFICATE-----
```

This file would be your Stir/Shaken certificate.  You will also need to host your certificate to a Certificate Repository.  A Certificate Repository can be deployed using AWS S3 or Google Storage service.&#x20;


# Linux Command Line Client

### Download ACME client

You can download Peeringhub's ACME client from:

```
https://github.com/peeringhub/RHEL-ACME-Cllient
```

### Installation

Install app dependencies:

```
# dnf install curl openssl libuuid
```

Deploy the program:

```
$ tar -xvf dnl_acme_client.tar.gz
```

### Configuration

ACME client uses configuration file `./acme_client.conf`:

* `server_url` - ACME server URL (<https://stica.peeringhub.io/acme>)
* `kid` - Any human-readable string, which can identify the client (e.g. Company Name)
* `pa_user_id` - Iconectiv login
* `pa_password` - Iconectiv password

### Certificate creation

1. Create EC private key:

```
openssl ecparam -genkey -name prime256v1 -out ./private_key.pem
```

1. Get SPC from Iconectiv (if do not have one):

If server doesn't have a white-listed at Iconectiv IP address, ACME client cannot generate SPC tokens, required to prove ownership of SP account. In that case, you must use SPC token file, acquired from a different server, and skip this step.

```
gen_spc [--ca] {EC key path} {OCN}

- --ca - whether to create SPC for SCA or a regular SP certificate
- {EC key path} - path to EC private key, generated in the first step
- {OCN} - Iconectiv Service Provider account ID (4 alnum characters, e.g. 123H)
```

For regular SP certificate:

```
./dnl_acme_client -c ./acme_client.conf gen_spc ./private_key.pem 123H > ./123H.spc
```

For SCA certificate:

```
./dnl_acme_client -c ./acme_client.conf gen_spc --ca ./private_key.pem 123H > ./123H_CA.spc
```

1. Create a new certificate order:

<pre><code>new_order [--ca] [--spc {SPC file path}] {EC key path} {OCN} {not_before} {not_after} {subject parameters}

- --ca - (optional) if set, order SCA certificate, otherwise order a regular SP certificate
- --spc - (optional) path to SPC file, generated in step 2. If not set, a new SPC will be requested from Iconectiv
- {EC key path} - path to EC private key, generated in the first step
- {OCN} - Iconectiv Service Provider account ID (4 alnum characters, e.g. 123H)
<strong>- {not_before} - (optional) certificate start date.  This is a timestamp value.
</strong>- {not_after} - (optional) certificate expiration date. This is a timestamp value.

Subject parameters:
  C={country} - mandatory (must be US)
  S={state} - optional
  L={locality} (e.g. city) - optional
  O={organization} - mandatory
  OU={organization unit} - optional
  CN={common name} - mandatory
</code></pre>

Your "O" and "CN" values must be unique.  STI certificates shall include a Subject field containing a Distinguished Name (DN), which is unique for each subject entity certified under one CA issuer identity, as specified in RFC 5280 \[Ref 11].

{% hint style="info" %}
6.4.1 STI Certificate Requirements

This section defines the STI Certificate profile that shall be supported by SHAKEN-compliant STI-CAs and Service Providers.

....

STI certificates shall include a Subject field containing a Distinguished Name (DN), which is unique for each subject entity certified under one CA issuer identity, as specified in RFC 5280 \[Ref 11]. The DN shall contain a Country (C=) attribute, a Common Name (CN=) attribute and an Organization (O=) attribute. Other DN attributes are optional. For non-End-Entity CA certificates (Basic Constraints CA boolean = TRUE), the Common Name attribute shall include the text string "SHAKEN" and also indicate whether the certificate is a root or intermediate certificate (e.g., CN=SHAKEN root). The Common Name attribute of an End-Entity certificate shall contain the text string “SHAKEN”, followed by a single space, followed by the SPC value identified in the TNAuthList of the End-Entity certificate (e.g., "CN=SHAKEN 1234"). The Organization (O=) attribute shall include a legal name of the service provider in order to facilitate traceback and operations. STI certificates shall include an Issuer field. For root certificates, the Issuer field shall match the certificate’s Subject field. For intermediate and End-Entity certificates, the Issuer field shall match the Subject field of the parent certificate.
{% endhint %}

> "Subject" string combination must be unique for all valid certificates.

## Example command line on generating certificates:

For regular SP certificate:

```
./dnl_acme_client -c ./acme_client.conf --spc ./123H.spc new_order ./private_key.pem 123H 0 0 C=US S=AZ L=Phoenix O="Company Name" CN="Company Name SHAKEN 123H" > 123H.pem
```

For SCA certificate:

```
./dnl_acme_client -c ./acme_client.conf --spc ./123H_CA.spc new_order --ca ./private_key.pem 123H 0 0 C=US S=AZ L=Phoenix O="Company Name" CN="Company Name Subordinate CA 123H" > 123H_CA.pem
```

{% hint style="info" %}
You can use {not\_*before}  and {not\_*&#x61;fter} field to set the validity period of the certificate you are generating. &#x20;

If you put 0 to not\_*before and not\_*&#x61;fter variables, Peeringhub's ACME server will assume a one year validity. &#x20;

However, if your Stir/Shaken subscription is expiring earlier than 1 year, then the certificate will end on the subscription expiration date.
{% endhint %}

{% hint style="info" %}
There are many free online service that can convert date to timestamp for you.  One such site is <https://www.epochconverter.com/>
{% endhint %}

Review downloaded certificate:

```
openssl x509 -text -noout -in ./123H.pem

Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            7e:52:58:50:e5:59:cb:19:c9:3b:dd:46:a4:85:16:9c
        Signature Algorithm: ecdsa-with-SHA256
        Issuer: C = US, O = Peeringhub Inc, OU = Certification Authorities, CN = Peeringhub Inc SHAKEN Intermediate CA 2
        Validity
            Not Before: May 25 18:18:54 2022 GMT
            Not After : May 25 18:18:54 2023 GMT
        Subject: C = US, ST = AZ, L = Phoenix, O = Company Name, CN = Company Name SHAKEN 123H
        Subject Public Key Info:
            Public Key Algorithm: id-ecPublicKey
                Public-Key: (256 bit)
                pub:
                    04:5f:8e:7b:f1:6b:cf:46:d1:5d:43:33:c7:66:98:
                    b6:d6:24:8a:e6:95:9f:38:27:94:a8:21:35:55:27:
                    17:29:11:5b:5b:26:ee:3e:8a:ab:6d:d4:4a:62:a2:
                    fc:e2:09:e5:44:df:31:3c:83:1a:21:b5:ff:3e:3a:
                    94:c2:33:8e:d8
                ASN1 OID: prime256v1
                NIST CURVE: P-256
        X509v3 extensions:
            X509v3 Key Usage: critical
                Digital Signature
            X509v3 Basic Constraints: critical
                CA:FALSE
            X509v3 Subject Key Identifier:
                B9:14:9E:E1:C5:2B:00:29:E3:00:D8:F3:60:FF:3F:EB:34:50:A6:E0
            X509v3 Authority Key Identifier:
                keyid:22:DE:75:3E:D4:5E:08:6A:FF:01:1C:EA:7D:E3:C7:39:53:42:97:05

            X509v3 Certificate Policies:
                Policy: 2.16.840.1.114569.1.1.1

            1.3.6.1.5.5.7.1.26:
                0.....123H
            X509v3 CRL Distribution Points:

                Full Name:
                  URI:https://authenticate-api.iconectiv.com/download/v1/crl
                CRL Issuer:
                  DirName:L = Bridgewater, ST = NJ, CN = STI-PA CRL, C = US, O = STI-PA

    Signature Algorithm: ecdsa-with-SHA256
         30:46:02:21:00:b8:8d:fa:9f:cd:c0:20:65:f4:ce:84:6e:2f:
         8d:7e:26:22:33:26:f4:3c:d4:1d:40:11:cf:ec:5f:35:ae:71:
         40:02:21:00:88:41:11:8f:cb:2a:28:a9:48:b3:1d:8a:c5:9e:
         30:52:09:e7:7c:f5:12:de:ff:37:95:d9:b9:21:7f:d6:0d:be
```

### Account management

***

#### Login and list active orders

```
login {EC key path}

./dnl_acme_client -c ./acme_client.conf login ./private_key.pem
```

#### Change account's access key

1. Create new EC private key:

```
openssl ecparam -genkey -name prime256v1 -out ./new_private_key.pem
```

1. Update key on server:

```
key_change {old key path} {new key path}

./dnl_acme_client -c ./acme_client.conf key_change ./private_key.pem ./new_private_key.pem
```

#### Deactivate account

```
deactivate {EC key path}

./dnl_acme_client -c ./acme_client.conf deactivate ./private_key.pem
```


# Python Libraries

Peeringhub provides two Python packages for service providers who want to generate and operate STIR/SHAKEN certificates from a Python-based workflow:

* [stir-shaken-toolkit](https://pypi.org/project/stir-shaken-toolkit/) is the reusable toolkit. Use it when you want a command-line utility or Python library for ACME, TNAuthList, STI-PA SPC tokens, CSRs, certificate inspection, and Peeringhub certificate issuance.
* [shaken-cert-manager](https://pypi.org/project/shaken-cert-manager/) is the lifecycle manager. Use it when you want a Certbot-style operations tool that keeps the active certificate current, manages archive/live state, runs deployment hooks, reports status, renews certificates, and cleans up old material.

The video walkthrough [SHAKEN Cert Manager intro](https://www.youtube.com/watch?v=A4O7BrlWtq4) explains the intended operating model: use the toolkit for the low-level STIR/SHAKEN and ACME work, then use the manager when you need repeatable certificate operations on a production signing server.

#### Which Python project should I use?

Use `stir-shaken-toolkit` when you are learning the flow, testing Peeringhub issuance, building your own automation, or integrating certificate issuance into an existing Python service. It exposes provider-neutral RFC 8555 ACME primitives, STIR/SHAKEN-specific helpers, and Peeringhub defaults.

Use `shaken-cert-manager` when the certificate must be maintained over time. It is the operational layer on top of `stir-shaken-toolkit`. It tracks which certificate generation is active, keeps old generations in an archive, publishes stable `live/current` links, decides when renewal is needed, and provides `status`, `renew`, `force-renew`, and `cleanup` commands.

Neither package signs calls by itself. Your STI-AS, SIP proxy, or signing service still signs outbound calls and inserts the SIP `Identity` header. The Python tools only help you obtain, publish, rotate, inspect, and monitor the STIR/SHAKEN certificate material used by that signing service.

#### Prerequisites

Before using either Python package, prepare these values:

* Python 3.10 or later.
* An active Peeringhub STI-CA account.
* The Peeringhub ACME key identifier, also called `ACME_KID`.
* STI-PA credentials: `STIPA_USER_ID`, `STIPA_PASSWORD`, and `STIPA_SP_ID`.
* Your service provider code, usually the same value as the OCN/SPC, for example `818H`.
* Certificate subject values, including country, state, locality, and organization.
* A secure location for the ACME account key, for example `/var/lib/shaken/account/account.key`.
* A public HTTPS URL where your signing service can publish the active `certificate-chain.pem`. This URL is the certificate URL used by PASSporT `x5u`.

Install the packages in a virtual environment:

```bash
python3 -m venv .venv
. .venv/bin/activate
pip install --upgrade pip
pip install stir-shaken-toolkit shaken-cert-manager
```

#### Option 1: Issue a certificate directly with stir-shaken-toolkit

`stir-shaken-toolkit` is the best starting point because it shows every important step in the Peeringhub issuance flow. The package is split into three layers:

* `acme_core`: provider-neutral ACME request signing, nonces, accounts, orders, challenges, finalization, and download logic.
* `stir_shaken_acme`: STIR/SHAKEN-specific helpers for TNAuthList, STI-PA SPC tokens, fingerprints, CSRs, certificate issuance, inspection, and validation.
* `stir_shaken_toolkit.providers.peeringhub`: Peeringhub defaults and convenience APIs so operators do not need to build the ACME profile by hand.

Start by exporting the required values. Replace the example values with your own production values:

```bash
export STIPA_USER_ID="sti-pa-user"
export STIPA_PASSWORD="sti-pa-password"
export STIPA_SP_ID="818H"
export STIPA_SPC="818H"
export ACME_KID="peeringhub-kid"
export SHAKEN_SUBJECT_COUNTRY="US"
export SHAKEN_SUBJECT_STATE="TX"
export SHAKEN_SUBJECT_LOCALITY="Irving"
export SHAKEN_SUBJECT_ORGANIZATION="Example Telecom"
```

Create or verify the Peeringhub ACME account directory:

```bash
stir-shaken-toolkit peeringhub-account-setup --account-dir /var/lib/shaken/account
```

This creates or verifies two important files:

* `account.key`: the durable EC P-256 private key used for Peeringhub ACME account authentication.
* `account.json`: a recoverable cache of the Peeringhub ACME account URL.

For Peeringhub issuance, the same `account.key` is used for ACME request signing, the STI-PA SPC token fingerprint, the CSR public key, and the final certificate/private-key pair. Protect it like any other production private key.

Issue the certificate:

```bash
stir-shaken-toolkit peeringhub-issue --account-dir /var/lib/shaken/account
```

During issuance, the toolkit performs this flow:

1. Prepares or verifies the local Peeringhub ACME account.
2. Builds the TNAuthList value from your SPC.
3. Generates the fingerprint required for the STI-PA SPC token.
4. Requests and validates the STI-PA SPC token.
5. Creates a Peeringhub ACME order.
6. Submits the `tkauth-01` challenge.
7. Builds a CSR using the local ACME account key.
8. Finalizes the ACME order.
9. Downloads and validates the issued STIR/SHAKEN certificate chain.

By default, the command writes artifacts to a timestamped directory such as:

```
./shaken-cert-20260508T162900Z
```

The output directory contains:

* `csr.pem`: the CSR submitted to Peeringhub.
* `csr.der`: the DER form of the same CSR.
* `leaf.pem`: the issued subscriber certificate.
* `certificate-chain.pem`: the subscriber certificate followed by the Peeringhub intermediate certificate.
* `issuance.json`: issuance metadata, order URLs, certificate URLs, validation details, subject details, and the account key path used for the CSR.

The output directory does not contain a private key. The matching private key is the ACME account key. In most deployments, publish `certificate-chain.pem` at your public STIR/SHAKEN certificate URL and configure your signing system to use `account.key` as the private key. Do not publish `account.key`.

You can inspect the certificate and verify that the key matches:

```bash
stir-shaken-toolkit inspect --certificate ./shaken-cert-20260508T162900Z/leaf.pem
stir-shaken-toolkit inspect --certificate ./shaken-cert-20260508T162900Z/certificate-chain.pem --json
stir-shaken-toolkit validate-key-pair \
  --key /var/lib/shaken/account/account.key \
  --certificate ./shaken-cert-20260508T162900Z/leaf.pem
```

#### Option 2: Operate certificates with shaken-cert-manager

`shaken-cert-manager` is for servers that need ongoing certificate management. The manager owns a state directory, usually `/var/lib/shaken`, and keeps a safe operational layout:

```
/var/lib/shaken/
  account/
    account.key
    account.json
  archive/
    <generation_id>/
      csr.pem
      csr.der
      leaf.pem
      certificate-chain.pem
      manifest.json
  live/
    <generation_id>/
      leaf.pem -> ../../archive/<generation_id>/leaf.pem
      certificate-chain.pem -> ../../archive/<generation_id>/certificate-chain.pem
    current -> <generation_id>
  failed/
    <generation_id>/
  active.json
  last-attempt.json
```

The `archive` directory is the durable certificate history. The `live` directory exposes stable paths to currently usable generations. `live/current` points to the active generation, which makes it easy for a web server or deploy hook to publish the current `certificate-chain.pem` without changing application configuration every time a certificate is renewed.

Create a private manager config file:

```bash
cp shaken-cert-manager.example.yaml /etc/shaken-cert-manager.yaml
chmod 600 /etc/shaken-cert-manager.yaml
```

A minimal production config looks like this:

```yaml
enabled: true
peeringhub_environment: production
server_id: voice1

stipa_spc: 818H
stipa_sp_id: 818H
stipa_user_id: sti-pa-user
stipa_password: sti-pa-password
acme_kid: peeringhub-kid

shaken_subject_country: US
shaken_subject_state: TX
shaken_subject_locality: Irving
shaken_subject_organization: Example Telecom

state_dir: /var/lib/shaken
renew_before_days: 45
warning_days: 30
minimum_certificate_lifetime_days: 14

pre_activate_hook: /usr/local/sbin/shaken-pre-activate
deploy_hook: /usr/local/sbin/shaken-deploy
```

Create or verify the ACME account key first:

```bash
stir-shaken-toolkit peeringhub-account-setup --account-dir /var/lib/shaken/account
```

Issue the first certificate:

```bash
shaken-cert-manager --config /etc/shaken-cert-manager.yaml issue-initial
```

`issue-initial` only issues a certificate when no active usable certificate exists. If an active certificate is already present, it exits successfully without replacing it.

Check status:

```bash
shaken-cert-manager --config /etc/shaken-cert-manager.yaml status
shaken-cert-manager --config /etc/shaken-cert-manager.yaml status --json
shaken-cert-manager --config /etc/shaken-cert-manager.yaml status --nagios
```

Use `status --json` for local automation and `status --nagios` for monitoring systems. The Nagios output includes a status code and certificate days remaining, so your monitoring system can alert before the certificate becomes unsafe to use.

Run renewal from your scheduler:

```bash
shaken-cert-manager --config /etc/shaken-cert-manager.yaml renew
```

`renew` checks the active certificate first. It only issues a replacement when the certificate is inside the configured renewal window, when active state is critical, or when the active certificate needs replacement. For deliberate manual replacement, use:

```bash
shaken-cert-manager --config /etc/shaken-cert-manager.yaml force-renew
```

For non-interactive operations, add `--skip-confirm`:

```bash
shaken-cert-manager --config /etc/shaken-cert-manager.yaml force-renew --skip-confirm
```

Run cleanup periodically:

```bash
shaken-cert-manager --config /etc/shaken-cert-manager.yaml cleanup
```

Cleanup removes expired inactive archives, stale live links, and old failed transaction directories. It does not remove the active certificate generation.

#### Automating renewal

A simple cron job can run renewal twice per day:

```cron
0 0,12 * * * root /usr/local/bin/shaken-cert-manager --config /etc/shaken-cert-manager.yaml renew
```

For systemd hosts, use a timer instead. A systemd timer can add randomized delay, persistent catch-up after missed runs, and structured logs. Keep lifecycle hooks in the YAML config; the scheduler should only run `renew`.

#### How this connects to call signing

After issuance, the signing system needs two things:

* The private key, stored locally and readable only by the signing service. With Peeringhub issuance this is usually `/var/lib/shaken/account/account.key`.
* A public HTTPS URL that serves the active `certificate-chain.pem`, usually from `/var/lib/shaken/live/current/certificate-chain.pem` or a web-server path updated by the deploy hook.

The signing service uses the private key to sign PASSporT tokens and places the public certificate URL in the SIP `Identity` header as `x5u`. Downstream verifiers download the certificate chain from that URL and validate the signature. If the private key and certificate do not match, verification will fail.

#### Using the toolkit from Python code

Use the Python API when you need the issuance flow inside your own application instead of calling the CLI. This example shows the shape of a Peeringhub issuer:

```python
from pathlib import Path

from stir_shaken_acme import (
    ShakenCertificatePolicy,
    ShakenSubject,
    StipaSettings,
    TnAuthList,
)
from stir_shaken_toolkit.providers.peeringhub import (
    PeeringhubIssuer,
    PeeringhubProfile,
)

profile = PeeringhubProfile.for_environment("production")
tn_auth_list = TnAuthList("818H")

policy = ShakenCertificatePolicy(
    subject=ShakenSubject(
        country="US",
        state="TX",
        locality="Irving",
        organization="Example Telecom",
        common_name="SHAKEN 818H generation-1",
    ),
    tn_auth_list_der=tn_auth_list.der(),
    expected_crl_url=profile.stipa_crl_url,
    minimum_certificate_lifetime_days=21,
)

issuer = PeeringhubIssuer.build(
    profile=profile,
    account_key_path=Path("/var/lib/shaken/account/account.key"),
    account_state_path=Path("/var/lib/shaken/account/account.json"),
    acme_kid="peeringhub-kid",
    stipa_settings=StipaSettings(
        base_url=profile.stipa_base_url,
        user_id="sti-pa-user",
        password="sti-pa-password",
        sp_id="818H",
        expected_crl_url=profile.stipa_crl_url,
    ),
    certificate_policy=policy,
)

# Live issuance should only be run from an operator-controlled environment.
# Use the CLI or manager unless your application needs direct control.
```

{% hint style="info" %}
For one-time testing, start with `stir-shaken-toolkit`. For production operations, use `shaken-cert-manager` and schedule `renew` with monitoring on `status --nagios` or `status --json`.
{% endhint %}

>


# Staging Environment Support

When you are succesfully registered in Peeringhub portal ( <http://portal.peeringhub.io> ), your OCN will be added to our stagging environment.&#x20;

You will be able to test the full ACME functionalities using RESTful API via the stagging URL:

> &#x20;[https://stica-dev.peeringhub.io](https://stica-dev.peeringhub.io/)

### Editing ACME-Client.conf

To use Peeringhub's Staging ACME environment, you need to modify your ACME-client.conf as follows:

{% code lineNumbers="true" %}

```
#
# Test ACME client configuration
#

# ACME server URL
server_url	https://stica-dev.peeringhub.io/acme

# Public key ID
kid		<your_orig_name>

#
# Iconectiv configuration
#
pa_user_id		<your iconnectiv staging user>
pa_password		<your iconnectiv staging password>
pa_staging		true
pa_trace		false
# EOF



```

{% endcode %}


# Configuring ACME Client

You can use the Peeringhub's ACME client in Peeringhub's Staging ACME server as well.&#x20;

The same client software can be downloaded from:

> <https://github.com/peeringhub/RHEL-ACME-Cllient>

The acme\_config needs to be updated to the following:

```
#
# ACME client configuration
#

# ACME server URL
server_url    https://stica-dev.peeringhub.io/acme

# Public key ID
kid        ACME client test EC P-256 key

#
# Iconectiv configuration
#
pa_user_id        login
pa_password        password
pa_staging        true
pa_trace        false

# EOF
```

{% hint style="info" %}
The pa\_staging is set to "false" by default.  If you want to use the ACME client in the staging environment, you must set as "true."
{% endhint %}

The pa\_trace value is optional.  It is "false" by default.  If set to "true", then it will log all the HTTP interaction with iConnectiv.&#x20;

&#x20;


# Getting Support

To obtain support from Peeringhub's Stir/Shaken CA service, you can register in our support portal and file support ticket under the appropriate category:

> [https://support.peeringhub.io/servicedesk/customer/portal](https://support.peeringhub.io/servicedesk/customer/portal/2)


# Troubleshoot

## Invalid CSR - certificate with such Subject name already exists

If you are getting the error below, that means, you need to use another "CN" variable when you order certificate.  Each "CN" must be different from the previous ones you used.  One suggestion is to add a unique numeric at the end of "CN."&#x20;

```
ERROR (src/main.c:837) Order failed - {"type":"urn:ietf:params:acme:error:badCSR","detail":"Invalid CSR - certificate with such Subject name already exists"}
```

## Invalid SPC - Failed to download certificate

This error means that the IP you are using now to interact with iConnectiv API, either by calling iConnectiv API directly or by using Peeringhub's ACME client, is not whitelisted in iConnectiv.  You need to check if your IP is specified in Access Request Form.&#x20;

```
ERROR (src/main.c:805) Challenge submission failed - {"type":"urn:ietf:params:acme:error:incorrectResponse","detail":"Invalid SPC - Failed to download certificate from 'https://authenticate-api.iconnectiv.com/download/v1/certificae/certificateId_161324.crt'"}
```

The Access Request Form looks like the following:

![](/files/9QynLHqGdfMCOEzJHjfy)


# Verify a Stir/Shaken Certificate

Part of the identity token included in a SIP header is the Stir/Shaken Certificate of the originating carriers. &#x20;

An identity token looks like the following:

{% code overflow="wrap" %}

```
eyJhbGciOiJFUzI1NiIsInBwdCI6InNoYWtlbiIsInR5cCI6InBhc3Nwb3J0IiwieDV1IjoiaHR0cHM6Ly9idy1zaGFrZW4tY2VydC1wdWIuczMuYW1xx9uYXdzLmNvbS9iYW5kd2lkdGgtc2hha2VuLWNlcnRfMjAyMzA3MTYucGVtIn0.eyJhdHRlc3QiOiJCIiwiZGVzdCI6eyJ0biI6WyIxNzcwMjk2NTM1OSJdfSwiaWF0IjoxNjY1NDI0MDcxLCJvcmlnIjp7InRuIjoiMTc3MDQ0ODgyMDAifSwib3JpZ2lkIjoiY2Y1NzVkOWYtOGNiMS0zOWMzLWI3N2EtODUyZjJiYTdmNTQ2In0.IIXlVkGpYtP70O-HQQKAv4mqR2_1qqPpDqELS_US1mS0jEcvUnUm2N16HLwlrn0Zne2-UkTl0U3f_IYNO8slvQ;info=<https://certificates.peeringhub.io/123H/123H.crt>;alg=ES256;ppt=shaken
```

{% endcode %}

You can download the certificate file from the "info" field and the content of the file is similar to below:

```
-----BEGIN CERTIFICATE-----
zIIDdddCAr2gAwIBAgIQSJ/BURPUF9492q9GgBDhlDAKBggqhkjOPQQDAjB8MQsw
xQYDVQQGEwJVUzEXMBUGA1UECgwOUGVlcmluZ2h1YiBJbmMxIjAgBgNVBAsMGUNl
cnRpZmljYXRpb24gQXV0aG9yaXRpZXMxMDAuBgNVBAMMJ1BlZXJpbmdodWIgSW5j
IFNIQUtFTiBJbnRlcm1lZGlhdGUgQ0EgMjAeFw0yMjA4MjQwNTA1MzBaFw0yMjA5
MTIxMTExNTVaMF8xCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJERTERMA8GA1UEBwwI
Q0xBWU1PTlQxETAPBgNVBAoMCE1lcmF0YWxrMR0wGwYDVQQDDBRNZXJhdGFsayBT
SEFLRU4gMjg5SzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABGLa/dZjC4lmBJw7
m2nFkausaapWdoWc1ug4pr/w3rm/DQsSRs/0o0Gm7Cw0L2WjSYTG6e2wt820w9rq
Z5rgl9KjggE8MIIBODAOBgNVHQ8BAf8EBAMCB4AwDAYDVR0TAQH/BAIwADAdBgNV
HQ4EFgQUw1+a9xx+PW878Lx98N9MOf33JEcwHwYDVR0jBBgwFoAUrqFzUYgpVxHK
DKn0sQpuTrhLTQcwFwYDVR0gBBAwDjAMBgpghkgBhv8JAQEBMBYGCCsGAQUFBwEa
BAowCKAGFgQyODlLMIGmBgNVHR8EgZ4wgZswgZigOqA4hjZodHRwczovL2F1dGhl
bnRpY2F0ZS1hcGkuaWNvbmVjdGl2LmNvbS9kb3dubG9hZC92MS9jcmyiWqRYMFYx
FDASBgNVBAcMC0JyaWRnZXdhdGVyMQswCQYDVQQIDAJOSjETMBEGA1UEAwwKU1RJ
LVBBIENSTDELMAkGA1UEBhMCVVMxDzANBgNVBAoMBlNUSS1QQTAKBggqhkjOPQQD
AgNIADBFAiEA9FwWY/mpoaJrUX/5C0kiMy0tFTwb4LmRiVgJc3RImNwCICt2Z6Mo
Z2Bza1qdBai5uMy0BeIXbGq/9b1Z6wCOfLHW
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
xxxxxdCCArWgAwIBAgIRALZNFq96KG4nRDKyzVhPcaUwCgYIKoZIzj0EAwIwazEL
MAkGA1UEBhMCVVMxFzAVBgNVBAoMDlBlZXJpbmdodWIgSW5jMSIwIAYDVQQLDBlD
ZXJ0aWZpY2F0aW9uIEF1dGhvcml0aWVzMR8wHQYDVQQDDBZQZWVyaW5naHViIElu
YyBSb290IENBMB4XDTIyMDYyMjIyNDUwMloXDTMyMDYxOTIyNDUwMlowfDELMAkG
A1UEBhMCVVMxFzAVBgNVBAoMDlBlZXJpbmdodWIgSW5jMSIwIAYDVQQLDBlDZXJ0
aWZpY2F0aW9uIEF1dGhvcml0aWVzMTAwLgYDVQQDDCdQZWVyaW5naHViIEluYyBT
SEFLRU4gSW50ZXJtZWRpYXRlIENBIDIwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNC
AATXEEZfOD4d6FnCYEcvzXAMpFyyP8F1fGefqfxy+R22euER5DvlXYg0vRiyF1hD
KC/hvM7eC74evVeiNgpWB3j+o4IBJzCCASMwDgYDVR0PAQH/BAQDAgGGMA8GA1Ud
EwEB/wQFMAMBAf8wHQYDVR0OBBYEFK6hc1GIKVcRygyp9LEKbk64S00HMB8GA1Ud
IwQYMBaAFBzpokb/fffddddngvRijv4Fon/PMBcGA1UdIAQQMA4wDAYKYIZIAYb/
CQEBATCBpgYDVR0fBIGeMIGbMIGYoDqgOIY2aHR0cHM6Ly9hdXRoZW50aWNhdGUt
YXBpLmljb25lY3Rpdi5jb20vZvvvvvvvYWQvdjEvY3JsolqkWDBWMQswCQYDVQQG
EwJVUzELMAkGA1UECAwCTkoxFDASBgNVBAcMC0JyaWRnZXdhdGVyMQ8wDQYDVQQK
DAZTVEktUEExEzARBgNVBAMMClNUSS1QQSBDUkwwCgYIKoZIzj0EAwIDSAAwRQIg
GkVAngGoauAcC66weTZ39bchjkWjkJKdZifjcqqM/y0CIQCmG8NEcrd6aC92TjHp
N2/d38qvM8vvvvv+smqhcg==
-----END CERTIFICATE-----
```

You can decrypt the content of the certificate to get the information about the origination carrier using Openssl command:

> openssl x509 -text -noout -in cert\_file\_path

You should get back a response similar to the following:

```
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            48:9f:c1:51:13:ee:17:de:aa:da:af:46:80:10:e1:94
    Signature Algorithm: ecdsa-with-SHA256
        Issuer: C=US, O=Peeringhub Inc, OU=Certification Authorities, CN=Peeringhub Inc SHAKEN Intermediate CA 2
        Validity
            Not Before: Aug 24 05:05:30 2022 GMT
            Not After : Sep 12 11:11:55 2022 GMT
        Subject: C=US, ST=DE, L=CLAYMONT, O=ABC, CN=ABC SHAKEN 123H
        Subject Public Key Info:
            Public Key Algorithm: id-ecPublicKey
                Public-Key: (256 bit)
                pub: 
                    04:62:da:fd:d6:aa:0b:bb:66:04:9c:3b:9b:69:c5:
                    91:ab:ac:69:aa:56:76:85:9c:d6:e8:38:a6:bf:f0:
                    de:b9:bf:0d:dd:12:46:cf:f4cca3:41:a6:ec:2c:34:
                    2f:65:a3:49:84:c6:e9:ed:b0:b7:cd:b4:c3:da:ea:
                    67:9a:e0:97:d2
                ASN1 OID: prime256v1
                NIST CURVE: P-256
        X509v3 extensions:
            X509v3 Key Usage: critical
                Digital Signature
            X509v3 Basic Constraints: critical
                CA:FALSE
            X509v3 Subject Key Identifier: 
                C3:5F:9A:F7:1C:7E:dd:6F:3B:bb:BC:cc:F0:DF:4C:39:FD:F7:24:dd
            X509v3 Authority Key Identifier: 
                keyid:AE:A1:73:51:88:29:57:22:CA:0C:A9:F4:B1:4A:6E:4E:B8:4B:4D:07

            X509v3 Certificate Policies: 
                Policy: 2.16.840.1.114569.1.1.1

            1.3.6.1.5.5.7.1.26: 
                0.....123H
            X509v3 CRL Distribution Points: 

                Full Name:
                  URI:https://authenticate-api.iconectiv.com/download/v1/crl
                CRL Issuer:
                  DirName: L = Bridgewater, ST = NJ, CN = STI-PA CRL, C = US, O = STI-PA

    Signature Algorithm: ecdsa-with-SHA256
         30:45:02:21:00:f4:5c:16:11:f9:a9:a1:a2:6b:51:7f:f9:0b:
         49:22:33:2d:2d:15:3c:1b:33:b9:91:89:58:09:73:74:48:98:
         dc:02:20:2b:76:67:a3:28:44:60:73:6b:5a:9d:05:a8:b9:b8:
         cc:b4:05:e2:17:6c:6a:bf:f5:bd:59:eb:00:8e:7c:b1:a3
```


# Integration

**his section covers common integration scenarios collected from our users, illustrating how they deploy their STIR/SHAKEN Certificate Authority (CA) with their switch or CPaaS platforms.**

These real-world examples are shared to help you better understand different deployment approaches and integration methods across various platforms.

If you have screenshots, configuration details, or integration information for additional platforms, we welcome your contribution. Please email them to **<support@peeringhub.io>**.


# Bandwidth

The following screenshot is from the **Bandwidth** platform.\
To complete the integration, download the **Private Key** from your **Peeringhub.io** portal and upload it to the location shown.

For the **Certificate**, copy the **CRL link** from the Certificate page in your Peeringhub.io portal and paste it into your browser to download the certificate file.

You can download the Private Key directly from the **Private Key** page within your Peeringhub.io portal.

<figure><img src="/files/IHTFU7ByfrUWwCu4Oojp" alt=""><figcaption></figcaption></figure>

## How to Convert Your STIR/SHAKEN Private Key and Certificate for Bandwidth

### Requirements

* **OpenSSL** installed on your computer.
* **Intermediate CA Certificate (save as `peeringhub_intermediate.crt`):**

  ```
  -----BEGIN CERTIFICATE-----
  MIICEDCCAbWgAwIBAgIJAJZM3gWl52yeMAoGCCqGSM49BAMCMGsxCzAJBgNVBAYT
  AlVTMRcwFQYDVQQKDA5QZWVyaW5naHViIEluYzEiMCAGA1UECwwZQ2VydGlmaWNh
  dGlvbiBBdXRob3JpdGllczEfMB0GA1UEAwwWUGVlcmluZ2h1YiBJbmMgUm9vdCBD
  QTAeFw0yMDEyMTcxNTMxMDRaFw00MDEyMTIxNTMxMDRaMGsxCzAJBgNVBAYTAlVT
  MRcwFQYDVQQKDA5QZWVyaW5naHViIEluYzEiMCAGA1UECwwZQ2VydGlmaWNhdGlv
  biBBdXRob3JpdGllczEfMB0GA1UEAwwWUGVlcmluZ2h1YiBJbmMgUm9vdCBDQTBZ
  MBMG
  ```

### Step 1: Convert the Private Key

1. Open a terminal or command prompt.
2. Run the following command:

```bash
openssl ec -in stir_private_key.pem -out stir_private_key-fixed.pem -param_enc named_curve
```

**Explanation:**

* `stir_private_key.pem` → This is the original key you downloaded from **PeeringHub**.
* `stir_private_key-fixed.pem` → This is the new, fixed key that OpenSSL will generate.

3. After running the command, you will have a new key file: `stir_private_key-fixed.pem`.
4. Upload this fixed key to the **Bandwidth portal**.

### Step 2: Prepare the Certificate

1. The PeeringHub certificate is `.crt`. Rename it to `.cer`:

```
stir_certificate.crt → stir_certificate.cer
```

2. **Append the Intermediate CA to your certificate**:

```bash
cat peeringhub_intermediate.crt >> stir_certificate.cer
```

> This combines your certificate with PeeringHub’s Intermediate CA, which Bandwidth requires.

3. Upload the updated `stir_certificate.cer` to the **Bandwidth portal**.


# Common Bandwidth Error

### Error #1: BAD\_REQUEST: Unsupported private key format

<figure><img src="/files/PkbMrS4DZFFaLDPIgM16" alt=""><figcaption></figcaption></figure>

When you get this error, you need to convert your private key using the following command:

```
openssl ec -in stir_private_key.pem -out stir_private_key-fixed.pem -param_enc named_curve
```

### ERROR #2: BAD\_REQUEST: No Chain of Trust to CA

<figure><img src="/files/jOVdM7mn5IdJNSpQfZde" alt=""><figcaption></figcaption></figure>

You need to append Peeringhub's CA certificate to the end to .cer or .crt file.  Here is Peeringhub's CA certificate:

```
-----BEGIN CERTIFICATE-----
MIICEDCCAbWgAwIBAgIJAJZM3gWl52yeMAoGCCqGSM49BAMCMGsxCzAJBgNVBAYT
AlVTMRcwFQYDVQQKDA5QZWVyaW5naHViIEluYzEiMCAGA1UECwwZQ2VydGlmaWNh
dGlvbiBBdXRob3JpdGllczEfMB0GA1UEAwwWUGVlcmluZ2h1YiBJbmMgUm9vdCBD
QTAeFw0yMDEyMTcxNTMxMDRaFw00MDEyMTIxNTMxMDRaMGsxCzAJBgNVBAYTAlVT
MRcwFQYDVQQKDA5QZWVyaW5naHViIEluYzEiMCAGA1UECwwZQ2VydGlmaWNhdGlv
biBBdXRob3JpdGllczEfMB0GA1UEAwwWUGVlcmluZ2h1YiBJbmMgUm9vdCBDQTBZ
MBMGByqGSM49AgEGCCqGSM49AwEHA0IABOnrCNZEAlQT3yv/Z2pcR/NtTuNf7k3p
jojYhYvA83uMCzdu9KlG+LdDwFcioZPF027ks4CaeenplBMGhNMkVnajQjBAMA4G
A1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBQc6aJG/+sT
GtSS54L0Yo7+BaJ/zzAKBggqhkjOPQQDAgNJADBGAiEA/rriu3nwg8fan3oUiIA+
12PM+zuj6XfE7Ay92wNItTwCIQCrkOhIJG0L2Mg/wpDJPTWO4gaTpGqYbdexFlsi
nEAaFg==
-----END CERTIFICATE-----

```


# Peeringhub STI-API

Generating Your STIR/SHAKEN Certificate with PeeringHub.io

PeeringHub.io offers a simplified and developer-friendly set of APIs to help you generate your STIR/SHAKEN certificate with ease. These APIs abstract the complexity of the underlying ACME protocol, allowing you to integrate certificate issuance into your workflow quickly and efficiently.

The certificate generation process involves three key steps:

#### Step 1: Generate Your Authentication Token

Obtain an auth token to securely interact with the PeeringHub API.

#### Step 2: Generate a Private Key

Create a private key that will be used in the certificate request process.

#### Step 3: Request Your STIR/SHAKEN Certificate

Use the authentication token and private key to request and obtain your certificate.

This section provides step-by-step examples demonstrating how to use PeeringHub.io's APIs for each stage of the process.


# Generate Auth Token

You can use your Peeringhub.io acount email and password to generate an Auth Token.

<mark style="color:green;">`POST`</mark> `/api/auth/login`

Generate an Auth Token

**Headers**

| Name         | Value              |
| ------------ | ------------------ |
| Content-Type | `application/json` |

**Body**

| Name       | Type   | Description      |
| ---------- | ------ | ---------------- |
| `email`    | string | Name of the user |
| `password` | number | Age of the user  |

**Example**

```
curl -X 'POST' 
  'https://api.peeringhub.io/api/auth/login' 
  -H 'accept: */*' 
  -H 'Content-Type: application/json' 
  -d '{
  "email": "ceo@telcom.co",
  "password": "12345678"
}'
```

**Response**

{% tabs %}
{% tab title="200" %}

```json
{
  "tokens": {
    "access": "eyJsInR5cCI6IkpXVCJ9.eyJzZXJ2aWNlX3Byb3ZpZGVyX3V1aWQiOiIzZTIwMTk4ZC1lZDE5LTQwODktOTVlNy1lYTdhMDNmZmNjODEiLCJjb21wYW55X25hbWUiOiJUZXN0IENvbXAiLCJvY24iOiI4MThIIiwicGhvbmVfbnVtYmVyIjoiKDQ4NCkgNDI0LTk2ODMiLCJmaXJzdF9uYW1lIjoiQW5uZSIsImxhc3RfbmFtZSI6Ikt3bm9nIiwidGl0bGUiOiJ2cCIsImFkZHJlc3MiOiIzMyBXZXN0IGxha2UiLCJhZGRyZXNzMiI6bnVsbCwiY2l0eSI6IlJpY2htb25kIiwic3RhdGUiOiJBTCIsInppcGNvZGUiOiIzNDM0NCIsImNvdW50cnkiOiJVUyIsInN0YXR1cyI6bnVsbCwiZW1haWwiOiJhbmt3b25nOTk5QGdtYWlsLmNvbSIsInN1YnNjcmlwdGlvbl9zdGFydGVkX29uIjoiMjAyNS0wNC0zMFQxNTozOTozNS4xMTRaIiwic3Vic2NyaXB0aW9uX2V4cGlyZWRfb24iOiIyMDI4LTA0LTMwVDE1OjM5OjMzLjAwMFoiLCJzdWJkb21haW4iOiJ0ZXN0LWNvbXAuYXBpLnBlZXJpbmdodWIuaW8iLCJpc195ZWFybHkiOmZhbHNlLCJhdXRvX2NoYXJnZSI6bnVsbCwicHJpbnRlZF9uYW1lIjoiYWFhIiwic3RyaXBlX2N1c3RvbWVyX2lkIjoiY3VzX003OHFxN1R3WVpmS2FIIiwiaXNfYWN0aXZlIjp0cnVlLCJpc19jb25maXJtZWQiOnRydWUsInJlc2VsbGVyX3V1aWQiOm51bGwsImtpZCI6IlRlc3RDb21wIiwiZmlsZXJfaWQiOm51bGwsImZybl9udW1iZXIiOm51bGwsImNyZWF0ZWRfb24iOiIyMDIyLTA4LTE1VDEzOjUzOjE5LjE2OFoiLCJpbnZpdGVkIjpbXSwidHlwZSI6InNlcnZpY2UtcHJvdmlkZXIiLCJpYXQiOjE3NDcyNTY2MjMsImV4cCI6MTc0Nzg2MTQyM30.KzbTpsHOYnfAOPeZwAnB9Mx4rIKhhKbPyXuq-e5_6r4"
  }
}
```

{% endtab %}

{% tab title="400" %}

```json
{
  "error": "Wrong email or password"
}
```

{% endtab %}
{% endtabs %}


# Generate Private Key

Each STIR/SHAKEN certificate requires a private key for its creation. PeeringHub.io provides a dedicated API that simplifies the process of securely generating this private key.

## Generate Private Key

<mark style="color:green;">`POST`</mark> [/api/service\_provider/generate\_sti\_priv\_key](https://api.peeringhub.io/api-doc/#/Service%20Provider/ServiceProviderController_generateStiPrivKey)

After calling this API, you will receive a UUID that uniquely identifies the generated private key. You can use this UUID to download the corresponding private key. When generating a STIR/SHAKEN certificate with PeeringHub.io, simply reference this UUID to specify which private key should be used for the certificate issuance.

**Headers**

| Name          | Value              |
| ------------- | ------------------ |
| Content-Type  | `application/json` |
| Authorization | `Bearer <token>`   |

**Example**<br>

{% code overflow="wrap" %}

```
curl -X 'POST'  
  'https://api.peeringhub.io/api/service_provider/generate_sti_priv_key'  
  -H 'accept: */*'  
  -H 'Authorization: Bearer eyJhbGciOiJIUzI1ddd6IkpXVCJ9.eyJzZXJ2aWNlX3Byb3ZpZGVyX3V1aWQiOiIzZTIwMTk4ZC1lZDE5LTQwODktOTVlNy1lYTdhMDNmZmNjODEiLCJjb21wYW55X25hbWUiOiJUZXN0IENvbXAiLCJvY24iOiI4MThIIiwicGhvbmVfbnVtYmVyIjoiKDQ4NCkgNDI0LTk2ODMiLCJmaXJzdF9uYW1lIjoiQW5uZSIsImxhc3RfbmFtZSI6Ikt3bm9nIiwidGl0bGUiOiJ2cCIsImFkZHJlc3MiOiIzMyBXZXN0IGxha2UiLCJhZGRyZXNzMiI6bnVsbCwiY2l0eSI6IlJpY2htb25kIiwic3RhdGUiOiJBTCIsInppcGNvZGUiOiIzNDM0NCIsImNvdW50cnkiOiJVUyIsInN0YXR1cyI6bnVsbCwiZW1haWwiOiJhbmt3b25nOTk5QGdtYWlsLmNvbSIsInN1YnNjcmlwdGlvbl9zdGFydGVkX29uIjoiMjAyNS0wNC0zMFQxNTozOTozNS4xMTRaIiwic3Vic2NyaXB0aW9uX2V4cGlyZWRfb24iOiIyMDI4LTA0LTMwVDE1OjM5OjMzLjAwMFoiLCJzdWJkb21haW4iOiJ0ZXN0LWNvbXAuYXBpLnBlZXJpbmdodWIuaW8iLCJpc195ZWFybHkiOmZhbHNlLCJhdXRvX2NoYXJnZSI6bnVsbCwicHJpbnRlZF9uYW1lIjoiYWFhIiwic3RyaXBlX2N1c3RvbWVyX2lkIjoiY3VzX003OHFxN1R3WVpmS2FIIiwiaXNfYWN0aXZlIjp0cnVlLCJpc19jb25maXJtZWQiOnRydWUsInJlc2VsbGVyX3V1aWQiOm51bGwsImtpZCI6IlRlc3RDb21wIiwiZmlsZXJfaWQiOm51bGwsImZybl9udW1iZXIiOm51bGwsImNyZWF0ZWRfb24iOiIyMDIyLTA4LTE1VDEzOjUzOjE5LjE2OFoiLCJpbnZpdGVkIjpbXSwidHlwZSI6InNlcnZpY2UtcHJvdmlkZXIiLCJpYXQiOjE3NDcyNTY2MjMsImV4cCI6MTc0Nzg2MTQyM30.KzbTpsHOYnfAOPeZwAnB9Mx4rIKhhKbPyXuq-e5_6r4'  
  -d ''
```

{% endcode %}

**Response**

{% tabs %}
{% tab title="200" %}

```json
{
  "success": true,
  "priv_key_uuid": "c0232-adc4-4dff-8016-7565744a18f79"
}

```

{% endtab %}
{% endtabs %}


# Extract Your Private Key

Peeringhub.io allows you to generat as many Private Key as you want.  You can generate different Stir/Shaken certificate and each certificate is generated with different Private Key.

## Create a new user

<mark style="color:green;">`GET`</mark> [/api/service\_provider/sti\_priv\_key/file/{priv\_key\_uuid}](https://api.peeringhub.io/api-doc/#/Service%20Provider/ServiceProviderController_getStiKeyFile)

This API will let you download your Private Key file.

**Headers**

| Name          | Value              |
| ------------- | ------------------ |
| Content-Type  | `application/json` |
| Authorization | `Bearer <token>`   |

**Body**

| Name            | Type   | Description      |
| --------------- | ------ | ---------------- |
| priv\_key\_uuid | string | Private Key UUID |

**Example**

{% code overflow="wrap" %}

```
curl -X 'GET' \
  'https://api.peeringhub.io/api/service_provider/sti_priv_key/file/c021xxxx-dc4-4dff-8016-756xxxx9' \
  -H 'accept: */*' \
  -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzZXJ2aWNlX3Byb3ZpZGVyX3V1aWQiOiIzZTIwMTk4ZC'
```

{% endcode %}

**Response**

{% tabs %}
{% tab title="200" %}

```json
 access-control-allow-origin: * 
 connection: keep-alive 
 content-disposition: inline;filename="818H_1747257159636_private_key.pem" 
 content-type: application/octet-stream 
 date: Wed,14 May 2025 21:42:26 GMT 
 server: nginx/1.14.1 
 transfer-encoding: chunked 
 x-powered-by: Express 
```

{% endtab %}
{% endtabs %}


# Generate Stir/Shaken Certifiate

You can generate unlimited certificates. Each one remains valid until your PeeringHub.io subscription expires.

## Generate a Stir/Shaken Certificate

<mark style="color:green;">`POST`</mark> [/api/service\_provider/generate\_sti\_spc\_cert](https://api.peeringhub.io/api-doc/#/Service%20Provider/ServiceProviderController_generateStiCert)<br>

You can generate as many certifiate as you want.  The certificate will last till the end of your Peeringhub.io's subscription period. &#x20;

**Headers**

| Name          | Value              |
| ------------- | ------------------ |
| Content-Type  | `application/json` |
| Authorization | `Bearer <token>`   |

**Body**

| Name               | Type   | Description              |
| ------------------ | ------ | ------------------------ |
| `private_key_uuid` | string | Private Key UUID         |
| sti\_pa\_username  | string | Your iConnectiv Username |
| sti\_pa\_password  | string | Your iConnectiv Password |

**Example**

{% code overflow="wrap" %}

```
curl -X 'POST'  
  'https://api.peeringhub.io/api/service_provider/generate_sti_spc_cert'  
  -H 'accept: */*'  
  -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzZXJ2aWNlX3Byb3ZpZGVyX3V1aWQiOiIzZTIwMTk4Z'  
  -H 'Content-Type: application/json'  
  -d '{
  "private_key_uuid": "c02xxx302-adc4-4dff-8016-xxxxx8f79",
  "sti_pa_username": "your_sti_user",
  "sti_pa_password": "your_sti_pass"
}'
```

{% endcode %}

**Response**

{% tabs %}
{% tab title="200" %}

```json
{
  "success": true,
  "payload": {
    "res": {
      "service_provider_uuid": "3xxxx8d-ed19-4089-95e7-ea7axxxxxc81",
      "sti_priv_key_uuid": "c02xxx302-adc4-4dff-8016-xxxxx8f79",
      "cr_path": "https://certificates.peeringhub.io/818H/H6xUJgxY/ABC.crt",
      "success": true,
      "serial_number": "H6xUJgxY",
      "sti_cert_expire_date": "Thu, 14 May 2026 21:34:16 GMT",
      "sti_cert_start_date": "2025-05-14T21:34:16.000Z",
      "error_cause": null,
      "uuid": "5cdf84d9-eb87-4e8d-aa89-249651ce1b0d",
      "created_on": "2025-05-14T21:34:21.087Z"
    }
  }
}
```

{% endtab %}
{% endtabs %}

The `cr_path` field contains the URL from which you can download your STIR/SHAKEN certificate.


# FAQ

## Getting 405 Error with  <https://stica.peeringhub.io/acme/cert/8181995B4287422A83FF5D9C15D1A8A2>

This URL is returned in the create new order API of ACME server.  It is not a certificate URL on Peeringhub's CR ( Certificate Repository ).  This link can only be accessed via ACME protocol and only through the ACME client with their public key.  They cannot simply download it using unsigned GET request.  Your Stir/Shaken certificate must be hosted in a CR ( certificate repository )

ACME protocol doesn't support certificate hosting we also provide certificate repository free of charge to host your certificate.&#x20;


