Skip to main content

Enrollment over secure transport

Overview​

This API is based on the Device Configuration API framework. For guidance on how to use these APIs, please refer to Device Configuration APIs.

The VAPIX® Enrollment over secure transport API makes it possible to configure the device for automatic certificate enrollment. An EST profile can either be set in one call or patched to change its configuration.

Bootstrap distribution of CA certificates​

During certificate enrollment, the device acts as an EST client and connects to an EST server, the enrollment endpoint operated by the certificate authority. The /cacerts operation is the client's request for the CA certificates it should trust.

CA certificates returned by the server in response to the /cacerts operation are added to the device's trust store automatically. No out-of-band verification of these certificates is performed.

This creates a bootstrap trust problem: on the very first connection, the device has no way to distinguish a legitimate EST server from an impostor. Whichever server it reaches will have its CA certificates installed and trusted from that point onward. An attacker who can intercept or redirect that initial request can establish themselves as a trusted certificate authority for the device.

Precautions should therefore be taken when configuring the server for certificate issuance:

  • Pre-configure the device with the EST server's root certificate. This is the strongest option, as it removes the bootstrap problem entirely. The device can authenticate the server before trusting anything it sends.
  • If pre-configuration is not possible, secure the server's DNS records with DNSSEC. This does not authenticate the server itself, but it prevents an attacker from redirecting the device to a different host through DNS manipulation.

Use cases​

Set an EST profile​

Add a new EST profile to the profile list. The certificate enrollment process starts when the minimal required settings are present.

Example:

curl --request POST \
--anyauth \
--user "<username>:<password>" \
--header "Content-Type: application/json" \
"http://<servername>/config/rest/cert-est/v1/profiles" \
--data '{
"data": {
"caCertificates": [
"root-cert-GlobalSign",
"inter-cert-GlobalSign"
],
"certificate": "client_cert",
"id": "EST Profile",
"server": "192.168.0.1:443/.well-known/est",
"subject": {
"cn": "My EST Client"
}
}
}'
201 Created
Content-Type: application/json

{
"status": "success",
"data": {
"caCertificates": [
"root-cert-GlobalSign",
"inter-cert-GlobalSign"
],
"certificate": "client_cert",
"id": "EST Profile",
"server": "192.168.0.1:443/.well-known/est",
"services": null,
"subject": {
"cn": "My EST Client"
},
"subjectAlternativeNames": null
}
}

Enrollment​

To trigger enrollment, set a valid server URL, the name of the client certificate to authenticate with the server and the CA certificates needed to validate the certificate presented by the server to establish a TLS connection.

Delete an EST profile​

Specify the EST profile to delete it.

curl --request DELETE \
--anyauth \
--user "<username>:<password>" \
--header "Content-Type: application/json" \
"http://<servername>/config/rest/cert-est/v1/profiles/EST Profile"
200 OK
Content-Type: application/json

{
"status": "success"
}

Set EST server​

Specify the hostname of the server that enrolls new certificates.

The hostname can be either the IP or DNS of the server preceding the path, followed by a port number.

Examples of valid values:

  • "127.0.0.1"
  • "www.example.com:8443"

Example:

curl --request PATCH \
--anyauth \
--user "<username>:<password>" \
--header "Content-Type: application/json" \
"http://<servername>/config/rest/cert-est/v1/profiles/EST Profile/server" \
--data '{
"data": "www.example.com:8443"
}'
200 OK
Content-Type: application/json

{
"status": "success"
}

Set EST server CA certificates​

Configure one or more CA certificates that the device will use to authenticate the EST server.

During enrollment, the device and the EST server perform mutual TLS authentication: the server verifies the device's identity, and the device verifies the server's. These certificates form the trust anchor for the second half of that exchange — the device accepts the server's TLS certificate only if it chains to one of the CA certificates configured here.

Obtain these certificates from the certificate authority that operates your EST server. In most deployments this is the root CA certificate of the issuing hierarchy, though an intermediate can be used if the server's certificate chains to it.

Configuring certificates here is the recommended alternative to allowing the device to accept CA certificates automatically via the /cacerts operation, which offers no protection against an impostor server on first connection.

Examples of valid values:

  • [ "EST server root CA" ]

Example:

curl --request PATCH \
--anyauth \
--user "<username>:<password>" \
--header "Content-Type: application/json" \
"http://<servername>/config/rest/cert-est/v1/profiles/EST Profile" \
--data '{
"data": {
"caCertificates": [
"root-cert-GlobalSign",
"inter-cert-GlobalSign"
]
}
}'
200 OK
Content-Type: application/json

{
"status": "success"
}

Set client certificate​

Set the certificate that is required to authenticate the client to the EST server.

Examples of valid values:

  • "Device ID Certificate"

Example:

curl --request PATCH \
--anyauth \
--user "<username>:<password>" \
--header "Content-Type: application/json" \
"http://<servername>/config/rest/cert-est/v1/profiles/EST Profile" \
--data '{
"data": {
"certificate": "client_cert"
}
}'
200 OK
Content-Type: application/json

{
"status": "success"
}

Set subject field of CSR​

Set the X509 Subject used by the CSR when it is sent to the EST server during enroll and re-enroll.

The following Subject attributes are supported:

  • Common Name

If not configured, the Common Name will default to <hostname>.

Example:

curl --request PATCH \
--anyauth \
--user "<username>:<password>" \
--header "Content-Type: application/json" \
"http://<servername>/config/rest/cert-est/v1/profiles/EST Profile/subject" \
--data '{
"data": {
"cn": "Common Name of certificate"
}
}'
200 OK
Content-Type: application/json

{
"status": "success"
}

Set Subject Alternative Names of CSR​

Set the SAN field used by the CSR when it is sent to the EST server during enroll and re-enroll.

Valid SAN values are IP addresses and domain names, each prefixed with the corresponding type.

Examples of valid values:

  • "DNS:example.org"
  • "IP:127.0.0.1"

If not configured, SAN will default to [DNS:<hostname>].

Example:

curl --request PATCH \
--anyauth \
--user "<username>:<password>" \
--header "Content-Type: application/json" \
"http://<servername>/config/rest/cert-est/v1/profiles/EST Profile" \
--data '{
"data": {
"subjectAlternativeNames": [
"IP:127.0.0.1"
]
}
}'
200 OK
Content-Type: application/json

{
"status": "success"
}

Services to assign enrolled certificate to​

Set one or more services that will use the EST enrolled certificate. The valid values of supported services is returned in the supportedServices properties.

Examples of valid values:

  • 'WEBSERVER': The web server (HTTPS).
  • 'NETAUTH': The 802.1X network authentication client.
  • 'MQTT': The MQTT client service.
  • 'RTSPS': The video streaming service (RTSP over TLS).

Error events​

Error events are stateless events that are reported if the EST client fails. They are specified using the 'TopicExpression' and 'MessageContent' parameters. The following examples will show you how to receive these error events over a WebSocket connection.

WebSocket connection are initiated with an HTTP handshake sequence before being upgraded. The endpoint ws(s)://<device>/vapix/ws-data-stream should be use with digest authentication.

Example of a WebSocket flow:

Client WS handshake request​

GET /vapix/ws-data-stream?sources=events HTTP/1.1
Host: 192.168.0.90
Connection: Upgrade
Pragma: no-cache
Cache-Control: no-cache
Authorization: Digest username="root", realm="AXIS_ACCC8EC43707",
nonce="JrMSij/TBQA=646b1c2c4c0a80a7feb4e34ef9e3422180924c37",
uri="/vapix/ws-data-stream?sources=events",
algorithm=MD5, response="683f06da91f927fa1772c42f16597
Upgrade: websocket
Sec-WebSocket-Version: 13
Sec-WebSocket-Key: 1L91ICBqd8iwa0I0e6Wgzg==

Server handshake response​

Successful handshake response​
HTTP/1.1 101 Switching Protocols
Date: Tue, 02 Nov 2021 16:09:47 GMT
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: kZ1kuOZMJmrfKnY8FvL7Tjwb0iw=
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits=15
Failure handshake response​
HTTP/1.1 401 Unauthorized
Date: Tue, 02 Nov 2021 16:09:47 GMT
Server: Apache/2.4.48 (Unix) OpenSSL/1.1.1l
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 1; mode=block
WWW-Authenticate: Digest realm="AXIS_ACCC8EC43707",
nonce="5X26hdDPBQA=f1d9367d1b0699f406a95bbf79e35f6e08c5d3af",
algorithm=MD5, stale=true, qop="auth"
Content-Length: 381
Content-Type: text/html; charset=iso-8859-1

Select events to receive​

When the client has established a successful connection, it needs to specify what error events it wants to receive. This is done by sending a configuration request.

Client sends a configuration request with event filters​
{
"request": {
"apiVersion": "1.0",
"context": "Client defined request ID",
"method": "events:configure",
"params": {
"eventFilterList": [
{
"topicFilter": "tnsaxis:CertificateManagement/EST/Error"
}
]
}
},
"response": {
"apiVersion": "1.0",
"context": "Client defined request ID",
"method": "events:configure",
"data": {}
}
}

Error events​

Error events are sent to the client as JSON requests. The client should not respond to these notification requests.

Event notification syntax

{
"apiVersion": "1.0",
"method": "events:notify",
"params": {
"notification": {
"topic": "tnsaxis:CertificateManagement/EST/Error",
"timestamp": 1785242798912,
"message": {
"source": {
"Profile": "EST Example"
},
"key": {},
"data": {
"ErrorCode": "3",
"Message": "Request Error : 60 : SSL peer certificate or SSH remote key was not OK"
}
}
}
}
}
ParameterDescription
apiVersion=<string>The API version used for the request.
method=<string>The performed operation. This field will be set to "events:notify"
params.notification=<JSON object>'Required'. Specifies the event notification details.
params.notification.timestamp=<integer>'Optional'. Specifies the timestamp for the notification.
params.notification.topic=<string>'Required'. Specifies the topic for the notification.
params.notification.message=<JSON Object>'Required'. Specifies the notification message.
params.notification.message.source.Profile=<string>'Required'. Specifies the profile that has failed.
params.notification.message.key=<key-value pairs>'Optional'. Specifies the key of notification.
params.notification.message.data=<key-value pairs>'Required'. Specifies the data of notification.
params.notification.message.data.ErrorCode=<string>'Required'. Specifies the error code.
params.notification.message.data.Message=<string>'Required'. Additional error information.
Error codes​
Error CodeDescription
0Internal error during startup of EST client.
1External error during test connection.
2Internal error during EST client connection.
3External error during EST client connection.
4Internal error during EST client enrollment.
5External error during EST client enrollment.
6Internal error during EST client re-enrollment.
7External error during EST client re-enrollment.

API definition​

Structure​

cert-est.v1 (Root Entity)
├── supportedServices (Property)
├── profiles (Entity Collection)
├── caCertificates (Property)
├── certificate (Property)
├── id (Property)
├── server (Property)
├── services (Property)
├── status (Property)
├── subject (Property)
├── subjectAlternativeNames (Property)

Entities​

cert-est.v1​

  • Description: EST root object
  • Type: Singleton
  • Operations
    • GET
  • Attributes
    • Dynamic Support: No
Properties​
supportedServices​
  • Description: List of the services that can have enrolled certificates assigned to it.
  • Datatype: ServiceList
  • Operations
    • GET (Permissions: admin, operator, viewer)
  • Attributes
    • Nullable: No
    • Dynamic Support: No / Dynamic Enum: No / Dynamic Range: No
Actions​

This entity has no actions.

cert-est.v1.profiles​

  • Description: EST profiles.
  • Type: Collection (Key Property: id)
  • Operations
    • GET
    • SET
    • ADD
      • Required properties: id
      • Optional properties: server, caCertificates, certificate, subject, subjectAlternativeNames, services
    • REMOVE
  • Attributes
    • Dynamic Support: No
Properties​
caCertificates​
  • Description: EST server CA certificates
  • Datatype: CertificateList
  • Operations
    • GET
    • SET
  • Attributes
    • Nullable: Yes
    • Dynamic Support: No / Dynamic Enum: No / Dynamic Range: No
certificate​
  • Description: Existing certificate to base CSR on
  • Datatype: Alias
  • Operations
    • GET
    • SET
  • Attributes
    • Nullable: Yes
    • Dynamic Support: No / Dynamic Enum: No / Dynamic Range: No
id​
  • Description: EST profile identifier.
  • Datatype: Alias
  • Operations
    • GET
    • SET
  • Attributes
    • Nullable: No
    • Dynamic Support: No / Dynamic Enum: No / Dynamic Range: No
server​
  • Description: EST server hostname.
  • Datatype: string
  • Operations
    • GET
    • SET
  • Attributes
    • Nullable: Yes
    • Dynamic Support: No / Dynamic Enum: No / Dynamic Range: No
services​
  • Description: Services to assign enrolled certificate to
  • Datatype: ServiceList
  • Operations
    • GET
    • SET
  • Attributes
    • Nullable: Yes
    • Dynamic Support: No / Dynamic Enum: No / Dynamic Range: No
status​
  • Description: Status of the setup of the EST profile
  • Datatype: Status
  • Operations
    • GET
  • Attributes
    • Nullable: No
    • Dynamic Support: No / Dynamic Enum: No / Dynamic Range: No
subject​
  • Description: x509 subject of the enrolled certificate
  • Datatype: Subject
  • Operations
    • GET
    • SET
  • Attributes
    • Nullable: Yes
    • Dynamic Support: No / Dynamic Enum: No / Dynamic Range: No
subjectAlternativeNames​
  • Description: Subject alternative names, each prefixed with either "IP:" or "DNS:", e.g. "DNS:example.org"
  • Datatype: SubjectAltNameList
  • Operations
    • GET
    • SET
  • Attributes
    • Nullable: Yes
    • Dynamic Support: No / Dynamic Enum: No / Dynamic Range: No
Actions​

This entity has no actions.

Data Types​

Alias​

  • Description: Client-defined identifier
  • Type: string
  • Minimum Length: 1
  • Maximum Length: 128

CertificateList​

  • Description: Certificates list
  • Type: array
  • Element type: Alias
  • Null Value: No

CommonName​

  • Description: The Common Name is used to specify the fully qualified domain name (FQDN) of the server or the name of the individual or organization for which the certificate is issued.
  • Type: string
  • Minimum Length: 1
  • Maximum Length: 64

Service​

  • Description: A service to configure with an EST enrolled certificate.
  • Type: string
  • Enum Values: "WEBSERVER", "NETAUTH", "MQTT", "RTSPS"

ServiceList​

  • Description: Service list
  • Type: array
  • Element type: Service
  • Null Value: No

Status​

  • Description: The EST profiles status.
  • Type: string
  • Enum Values: "UNCONNECTED", "CONNECTED", "ENROLLED"

Return the current status of the EST client.

  • 'UNCONNECTED': There is currently no connection with the server.
  • 'CONNECTED': The connection with the EST server is working. CA certificates will be downloaded.
  • 'ENROLLED': The EST client has received a certificate from the EST server. It will request to renew the certificate before it expires.

Subject​

  • Description: Subject of the CSR that will be sent to the EST server. Uses the default subject settings if left empty.
  • Type: complex
  • Fields
    • cn
      • Description: Common Name
      • Type: CommonName
      • Nullable: Yes / Gettable: Yes

SubjectAltNameList​

SubjectAlternativeName​

  • Description: The Subject Alternative Name is used to specify additional domain names and IP addresses for which the certificate is issued.
  • Type: string