Registration API

This API allows a caller to create a Secure Enrollment Profile (SEP) using information obtained from the Enrollment Portal (using the v2.3 API).

!

This is an advanced API. Most developers should utilize Ionic’s SDK to perform device request communication such as creating or requesting keys.

This endpoint is used during the enrollment of client devices. The request takes an encrypted and signed “enrollment package” and returns a Secure Enrollment Profile (SEP). The contents of the enrollment package include an ephemeral public key for the device and an Ionic token composed of user identification and extra authentication data.

NOTE: This endpoint does not follow the General Device Request format. It creates the SEP, which is a prerequisite for using all endpoints following the General Device Request format.

Prerequisites

Before making this request, the device will need to complete an authentication exchange with the Enrollment Portal to get the “enrollment package”. (For more information on the Enrollment Portal, see the Glossary and the Registration Overview.) The exchange may involve a SAML or OAuth SSO exchange, an email token, or other exchange of proof(s) of the user’s identity. At the end of that exchange, the device should have the following values:

Value Example Notes
UIDAUTH ,I.eyKaWs...n0= A signed and optionally encrypted token value that contains information about the identity of the user. It must be combined with the STOKEN (described below) for the signature in the UIDAUTH to validate. The information contained in this token is used to lookup a corresponding user in Ionic.com. This value is prefixed with “,I” and should be included with the value of UIDAUTH.
STOKEN I.YBCFEDZJJX6SC A string that is either returned directly by the Enrollment Portal or sent to the user over an alternate channel (typically email) to provide an extra factor of authentication. This depends on the configuration of the Enrollment Portal. This value is prefixed with “I.” and should be included with the value of STOKEN.
Key Server Public Key https://enrollment.ionic.example.com/ keyspace/ABcd/pubkey Typically an RSA 3072-bit key used for encrypting the enrollment package for the key server via an ephemeral intermediate key.
API URL https://api.ionic.com The scheme, host, and optionally port of the Ionic.com API server that should be used by the device when enrolling.
Keyspace ABcd The unique identifier of the set of keyservers into which the device is enrolling.

NOTE: UIDAUTH and STOKEN are used for authentication and replay protection and cannot be reused.

Request

NOTE: A code sample can be found in the included samples at samples-devreq/python/registration/registration.py.

URL

/v2.3/register/{keyspace}

where {keyspace} is the unique identifier of the set of keyservers into which the device is enrolling.

Method

POST

Headers

Header Required Notes
X-Conversation-ID: Basic {UUID} Required {UUID} is a random UUID.
Content-Type: application/json Optional Request body is in JSON format

Request Body

The request body is a JSON object that takes the form:

{
  "k": "ABcd",
  "p": "KNOUWI9/YGA5gNK7X2NbikWEpDnW9GS4QHrrU7Xe+Vb...sGZihZ73R9WkyLwtyeWToYrsGy",
  "s": "G5137Qih0TYjVcHJqVlU8wjHjR+2+3tzPCHv/mDkhM2...4mtc5DI6P+l9oG+dkVADcQxD1p",
  "g": "Zij1ouToHxpCATyGFRYu5F8Iq2+6hFsto+6vMFe20cm...y8CyNkwtvZGDv1oStddr7lMB=="
}

where the fields are:

Field Description
k Keyspace into which the device is attempting to enroll.
p Encoded, encrypted enrollment package.
s Encoded, encrypted ephemeral AES key used on the enrollment package in the field above. This is encrypted with the key server public key.
g Encoded signature of the enrollment package using the device’s ephemeral key pair.

All of these keys are required, and each is described below.

k

The keyspace is obtained from the Enrollment Portal.

p

Follow these steps to create the p field value:

  1. Append UIDAUTH to the STOKEN string to form the Ionic token.
  2. Encode this string using standard Base64 encoding to form the value of the AUTH field.
  3. Generate a 3072-bit RSA public and private key pair. We’ll refer to the private key as S.CD.
  4. DER encode the public key and Base64-encode the result using standard encoding. Do not include any newlines or other whitespace.
  5. Take these two values and form the JSON object below.

    {
      "TKRespPubKDERB64": "{Base64-encoded DER-encoded public key}",
      "AUTH": "{Base64-encoded Ionic token}"
    }
    
  6. Encode this JSON object in a UTF-8 byte array.

  7. Generate a random 256-bit AES key and a unique 16-byte initialization vector. We’ll refer to this AES key as K.CD:KS.

  8. Use the AES key to encrypt the contents of the byte array using counter mode.

  9. Prepend the initialization vector to the resulting cipher text and Base64 encode the result using standard encoding.

s

Follow these steps to create the s field value using the AES key K.CD:KS (created during the p value steps above).

  1. Encrypt the AES key using the public key of the key server using the OAEP padding scheme with SHA-1 as defined in PKCS #1.
    • The key server public key can be requested from https://enrollment.ionic.example.com/keyspace/{keyspace}/pubkey.
  2. Encode the result with standard Base64 encoding. There should be no line breaks.

g

Follow these steps to create the g field value using the private key S.CD (created during the p value steps above).

  1. Sign the p value using the generated private key. This should be done using PSS and SHA-256 as defined in PKCS #1 with a salt length of 32 bytes.
  2. Encode the result with standard Base64 encoding. There should be no line breaks.

Sample Request

POST https://api.ionic.com/v2.3/register/ABcd
Content-Type: application/json
X-Conversation-ID: 3fd96550-c405-47fc-8bbc-6711292d32f1

{
  "k": "ABcd",
  "p": "KNOUWI9/YGA5gNK7X2NbikWEpDnW9GS4QHrrU7Xe+Vb...sGZihZ73R9WkyLwtyeWToYrsGy",
  "s": "G5137Qih0TYjVcHJqVlU8wjHjR+2+3tzPCHv/mDkhM2...4mtc5DI6P+l9oG+dkVADcQxD1p",
  "g": "Zij1ouToHxpCATyGFRYu5F8Iq2+6hFsto+6vMFe20cm...y8CyNkwtvZGDv1oStddr7lMB=="
}

Response

Successful Response Content Example

POST 200 OK
Content-Type: application/json

{
  "deviceID":"ABcd.A.1d9a8a1e-bbc5-4188-9c19-5f3106a13a80",
  "SEPAESK":"2ZteiIL0r5sP5ZNt164DWY...r1DLNOwP6Au5ACu3220x4=",
  "SEPAESK-IDC":"AZ7j+LAXKn9ya7k...zq+BNjnLfR0+SkbEwNILS+0="
}

Response Content Fields

The response contains the three core pieces of the SEP.

Field Type Description
deviceID string Unique identifier of the resulting SEP.
SEPAESK string Encoded, encrypted key used to protect transactions between the device and keyserver.
SEPAESK-IDC string Encoded, encrypted key used to protect transactions between the device and Ionic.com.

The SEPAESK field is the encoded and encrypted device-to-key-server SEP.CD:KS key. To obtain the key:

  1. Decode the SEPAESK value using standard base64 encoding.
  2. The resulting bytes contain a 16-byte initialization vector followed by ciphertext.
  3. Decrypt the data using the same ephemeral 256-bit AES key from the construction of the request object using AES-CTR mode.
  4. The result is the raw 256-bit SEP.CD:KS.

The SEPAESK-IDC field is the encoded and encrypted SEP.CD:IDC key. To obtain the key:

  1. Decode the value of this field using the standard base64 encoding.
  2. The resulting bytes should be decrypted using the ephemeral private key of the device from the construction of the request object.
  3. This should be done using the OAEP padding scheme with SHA-1 as defined in PKCS #1.
  4. The result is the raw 256-bit SEP.CD:IDC.

NOTE: See the Glossary for more information on the SEP.CD:KS and SEP.CD:IDC keys.

Status Codes and Errors

Code Causes
200 OK Successfully registered.
400 Bad Request Invalid JSON for request body.
400 Bad Request Public key or device cannot be parsed.
400 Bad Request Forming request for internal services failed.
400 Bad Request Invalid keyspace.
400 Bad Request Replay detected.
400 Bad Request Could not resolve tenant enrollment settings.
400 Bad Request Signature verification failed.
400 Bad Request Authorization token could not be decoded..
401 Unauthorized User is not enabled and cannot be enrolled.
401 Unauthorized Session key failed to decrypt.
401 Unauthorized Signature did not validate..
401 Unauthorized Payload could not be decrypted.
401 Unauthorized Token is incorrect.
404 Not Found Keyspace or tenant not found.
409 Not Found User not found.
409 Conflict Request is a replay.
417 Expectation Failed Routing to keyserver failed.
417 Expectation Failed Keyserver response is missing fields.
417 Expectation Failed Could not decode session key.
417 Expectation Failed Payload could not be decoded.
417 Expectation Failed Key pair could not be decoded.
417 Expectation Failed Signature could not be decoded.
417 Expectation Failed Current configuration does not support this type of enrollment.
417 Expectation Failed Attributes failed to re-sign.
424 Misdirected Request Could not resolve key server public key or could not verify signature from key server.
451 Unavailable For Legal Reasons Could not resolve tenant settings related to enrollment.
451 Unavailable For Legal Reasons Could not find needed user attribute fields in order to search for user.
500 Internal Server Error Could not JIT enroll user.
500 Internal Server Error Could not store device.
500 Internal Server Error Failed to form a response message.
500 Internal Server Error Could not contact enterprise manager.
500 Internal Server Error Other internal error.
503 Service Unavailable Unable to make request to upstream service.
503 Service Unavailable No keyserver is connected that can serve the requested keyspace.

In addition to an error response code, more information is contained in the response body. Errors are returned with a unique numeric code, message string identifying the error at a high level, and the same conversation ID used in the request.

{
  "error": {
    "cid": "{string}",
    "code": 0,
    "message": "{string}"
  }
}
Field Type Description
error object Error object.
error/cid string Conversation ID.
error/code integer Error code.
error/message string Text description of the error.