REST API
The REST API offered by Web Services Option Pack is made up of three parts: crypto for cryptographic operations, km for key management, and a health check endpoint.
Full details of the REST API are available in the Web Services Option Pack OpenAPI spec file /opt/nfast/wsop/docs/swagger.yml
.
The currently defined set of operations is as follows:
-
Crypto
-
Sign
-
Verify
-
Encrypt
-
Decrypt
-
-
Key Management
-
List Keys
-
Get Key information
-
Create Key
-
Delete Key
-
List Key Groups
-
List Keys in a Key Group
-
Get Key Group information
-
Get Key Group name
-
Create Protection Domain
-
Delete Protection Domain
-
List Protection Domains
-
Get Protection Domain information
-
Activate a Protection Domain
-
Deactivate a Protection Domain
-
-
Health check endpoint
Common fields
Several of these fields are common to many cryptographic and key management operations.
Key identifiers
Security World keys are uniquely identified in REST calls through a resource identifier. A key’s resource identifier includes which Key Group it is a member of. An example key identifier is:
km/v1/groups/ee3b7c4b-c6a7-3f2b-9d1c-0fc6c76168bb/keys/f9388a1e-b1c6-3e0e-bb5e-8eb887aab4be
Key Group identifiers
All Security World keys belong to exactly one Key Group. Each Key Group belongs to, and is protected by, a single Protection Domain. An example key group identifier is:
ee3b7c4b-c6a7-3f2b-9d1c-0fc6c76168bb
Protection Domain identifiers
A Protection Domain is either a Softcard or the set of all module keys. An example Protection Domain identifier is:
ee3b7c4b-c6a7-3f2b-9d1c-0fc6c76168bb
Protection Domain types
A Protection Domain is one of the following types:
-
Module
-
Softcard
-
Well-Known
Plaintext, ciphertext, payloads and signatures
Data sent in requests or responses is encoded in base64url format. Base64url encoding is a variation of standard base64 encoding and uses a slightly different character set that are safe for using in URLs without additional escaping of reserved characters, see Base64url Encoding
Data that forms part of cryptographic operations must be sent in a single request. Responses will similarly be sent from Web Services Option Pack as a single response body.
Digest option
Applicable for signing and verification requests, the optional digest
Boolean flag indicates whether the provided payload
has been hashed prior to sending the request.
When the digest
flag is set to true
, the server-side hashing of the payload is skipped, and length checking is performed to ensure that the supplied payload
is the correct length for the hash that corresponds to the signature or verification algorithm.
The digest flag is not applicable for HMAC signing and verification requests.
|
Algorithm identifiers
The majority of the algorithms are identified using JSON Web Algorithm identifiers.
For example, RS256
specifies RSA signatures with SHA-256 for hashing.
For further information, see Supported Algorithms in this User Guide and the Web Services Option Pack OpenAPI Specification.
Examples
Given a client certificate and corresponding key, it is possible to use command line tools such as curl
to demonstrate use of the REST API.
These examples assume the following:
-
The Web Services Option Pack server’s CA certificate is located in
server_ca.pem
. -
A valid client certificate is located in
client_crt.pem
. -
The private key corresponding to the client certificate is located in
client_key.pem
.
List keys
List all keys:
curl --cacert server_ca.pem \
--cert client_crt.pem --key client_key.pem \
--header 'Accept: application/json' \
--request GET \
"https://wsop.server:18001/km/v1/keys?sort=created"
Result:
{
"keys": [
{
"created": "2017-07-03T13:17:56Z",
"kid": "/km/v1/groups/366f38ec-64e1-503c-9950-18cc324d67c6/keys/90050af4-9b8c-5731-bbf2-08e3af797e2c",
"sworldAppname": "simple",
"sworldIdent": "test-aes"
},
{
"created": "2017-07-06T15:44:12Z",
"kid": "/km/v1/groups/366f38ec-64e1-503c-9950-18cc324d67c6/keys/e51a13d1-b775-3129-b1f9-b8642a212475",
"sworldAppname": "simple",
"sworldIdent": "test-rsa"
}
//...
]
}
List one key:
curl --cacert server_ca.pem \
--cert client_crt.pem --key client_key.pem \
--header 'Accept: application/json' \
--request GET \
"https://wsop.server:18001/km/v1/keys?limit=1"
Result:
{
"keys": [
{
"created": "2017-07-03T13:17:56Z",
"kid": "/km/v1/groups/366f38ec-64e1-503c-9950-18cc324d67c6/keys/90050af4-9b8c-5731-bbf2-08e3af797e2c",
"sworldAppname": "simple",
"sworldIdent": "test-aes"
}
]
}
List keys, with an offset:
curl --cacert server_ca.pem \
--cert client_crt.pem --key client_key.pem \
--header 'Accept: application/json' \
--request GET \
"https://wsop.server:18001/km/v1/keys?offset=2"
Result:
{
"keys": [
{
"created": "2017-07-06T08:12:51Z",
"kid": "/km/v1/groups/366f38ec-64e1-503c-9950-18cc324d67c6/keys/69fc1c75-81eb-58ad-83ff-c3fd517c27cf",
"sworldAppname": "simple",
"sworldIdent": "test-aes192"
},
{
"created": "2017-07-07T17:24:31Z",
"kid": "/km/v1/groups/366f38ec-64e1-503c-9950-18cc324d67c6/keys/7f34e38a-be3a-5378-a163-3313ce82ea02",
"sworldAppname": "simple",
"sworldIdent": "test-aes256"
}
//...
]
}
List all keys created since the beginning of the year:
curl --cacert server_ca.pem \
--cert client_crt.pem --key client_key.pem \
--header 'Accept: application/json' \
--request GET \
-d "filter=created%20ge%20datetime'2017-01-01T00:00:00Z'"
"https://wsop.server:18001/km/v1/keys"
Result:
{
"keys": [
{
"created": "2017-07-03T13:17:56Z",
"kid": "/km/v1/groups/366f38ec-64e1-503c-9950-18cc324d67c6/keys/90050af4-9b8c-5731-bbf2-08e3af797e2c",
"sworldAppname": "simple",
"sworldIdent": "test-aes"
},
{
"created": "2017-07-06T15:44:12Z",
"kid": "/km/v1/groups/366f38ec-64e1-503c-9950-18cc324d67c6/keys/e51a13d1-b775-3129-b1f9-b8642a212475",
"sworldAppname": "simple",
"sworldIdent": "test-rsa"
}
]
}
The use of %20 to escape spaces in URIs.
Date and time stamps are in ISO-8601 format.
|
List all keys which have a certain name:
curl --cacert server_ca.pem \
--cert client_crt.pem --key client_key.pem \
--header 'Accept: application/json' \
--request GET \
"https://wsop.server:18001/km/v1/keys?name=engineering"
Result:
{
"keys": [
{
"created": "2021-12-17T16:44:52Z",
"kid": "/km/v1/groups/19e40e8c-2188-5f9f-a1c8-8007424a4157/keys/589e4486-9da6-53ec-92ff-b2444c61ee02",
"name": "engineering",
"sworldAppname": "simple",
"sworldIdent": "test-aes192"
},
{
"created": "2021-12-17T16:44:52Z",
"kid": "/km/v1/groups/19e40e8c-2188-5f9f-a1c8-8007424a4157/keys/470d26c7-ad9d-5e49-9910-6e0c4fa9dad5",
"name": "engineering",
"sworldAppname": "simple",
"sworldIdent": "test-aes256"
},
{
"created": "2021-12-17T16:45:08Z",
"kid": "/km/v1/groups/a8668e0d-ef17-5a36-9dff-12a885dcb738/keys/1afdf157-056a-561e-8280-9b1b8e3aa817",
"name": "engineering",
"public": "/km/v1/groups/a8668e0d-ef17-5a36-9dff-12a885dcb738/keys/1afdf157-056a-561e-8280-9b1b8e3aa817/public",
"sworldAppname": "simple",
"sworldIdent": "test-rsa"
}
]
}
List all keys with a matching substring of that named.
curl --cacert server_ca.pem \
--cert client_crt.pem --key client_key.pem \
--header 'Accept: application/json' \
--request GET \
-d "filter=kid%20contains'269f0189'"
"https://wsop.server:18001/km/v1/keys"
Result:
{
"keys": [
{
"created": "2017-07-03T13:17:56Z",
"kid": "/km/v1/groups/366f38ec-64e1-503c-9950-18cc324d67c6/keys/90050af4-9b8c-5731-bbf2-08e3af797e2c",
"sworldAppname": "simple",
"sworldIdent": "test-aes"
}
]
}
List keys in a group
List all keys belonging to a certain group, for instance 19e40e8c-2188-5f9f-a1c8-8007424a4157 group:
curl --cacert server_ca.pem \
--cert client_crt.pem --key client_key.pem \
--header 'Accept: application/json' \
--request GET \
"https://wsop.server:18001/km/v1/groups/19e40e8c-2188-5f9f-a1c8-8007424a4157/keys"
Result:
{
"keys": [
{
"created": "2021-12-17T16:44:52Z",
"kid": "/km/v1/groups/19e40e8c-2188-5f9f-a1c8-8007424a4157/keys/4a59aec6-1cb4-5f27-9546-249b6e241f6f",
"sworldAppname": "simple",
"sworldIdent": "test-aes192"
},
{
"created": "2021-12-17T16:44:51Z",
"kid": "/km/v1/groups/19e40e8c-2188-5f9f-a1c8-8007424a4157/keys/dc2b10ee-dc7b-521f-b732-db252f7c13c2",
"name": "accounting",
"sworldAppname": "simple",
"sworldIdent": "test-hmac256"
},
//...
]
}
All HTTP queries described in List keys also work when listing the keys of a certain group. |
List Key Groups
List all key groups:
curl --cacert server_ca.pem \
--cert client_crt.pem --key client_key.pem \
--header 'Accept: application/json' \
--request GET \
"https://wsop.server:18001/km/v1/groups"
Result:
{
"groups": [
{
"groupid": "ccba7ee7-9032-5217-9db2-58d07fd4c045",
"keys": "/km/v1/groups/ccba7ee7-9032-5217-9db2-58d07fd4c045/keys",
"name": "soft1",
"protection": "/km/v1/protectiondomains/ccba7ee7-9032-5217-9db2-58d07fd4c045",
"type": "Softcard"
},
{
"groupid": "366f38ec-64e1-503c-9950-18cc324d67c6",
"keys": "/km/v1/groups/366f38ec-64e1-503c-9950-18cc324d67c6/keys",
"name": "Module Protection",
"protection": "/km/v1/protectiondomains/366f38ec-64e1-503c-9950-18cc324d67c6",
"type": "Module"
},
//...
]
}
Public key export
The following example exports the public key from an ECDSA key:
curl --cacert server_ca.pem \
--cert client_crt.pem --key client_key.pem \
--header 'Accept: application/json' \
--request GET \
"https://wsop.server:18001/km/v1/groups/366f38ec-64e1-503c-9950-18cc324d67c6/keys/6ff3a5ef-c12f-5e82-b1d6-d955caef2730"
Result:
{
"alg": "ES384",
"crv": "P-384",
"kid": "/km/v1/groups/366f38ec-64e1-503c-9950-18cc324d67c6/keys/6ff3a5ef-c12f-5e82-b1d6-d955caef2730”,
"kty": "EC",
"x": "JDvhhAqlSpn2xrjq7C1iOYKvPZl1PVARsXlsQc9EyP9dxhcZSJ0bkJcYXuu-3PWx",
"y": "_B3o_PZx2jsYA4nsKG82sCoEyCzdbeFTtIPrO5Y8PhkRc4owIiO_7BOUu97BkRsZ"
}
Public key import
Public Key import can only be performed in the Well-Known
Protection key group.
curl --cacert server_ca.pem \
--cert client_crt.pem –-key client_key.pem \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--request POST \
-d '{"appname":"simple", "ident":"test-import", "public": {"alg": "ES384","crv": "P-384","kty": "EC","x": "JDvhhAqlSpn2xrjq7C1iOYKvPZl1PVARsXlsQc9EyP9dxhcZSJ0bkJcYXuu-3PWx", "y": "_B3o_PZx2jsYA4nsKG82sCoEyCzdbeFTtIPrO5Y8PhkRc4owIiO_7BOUu97BkRsZ"}}'
'https://wsop.server:18001/km/v1/groups/2bd40730-85b1-5deb-8417-fb78a7735743/keys'
Result:
{
"kid": "/km/v1/groups/2bd40730-85b1-5deb-8417-fb78a7735743/keys/170ff5ca-9d46-522c-84d1-84074955b94f"
}
Create keys
The following example creates a key in the Module Protection
key group:
curl --cacert server_ca.pem \
--cert client_crt.pem –-key client_key.pem \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--request POST \
-d '\{"keytype":"ECDSA","curve":"P-256", "appname":"simple","ident":"test-p256"}'
'https://wsop.server:18001/km/v1/groups/366f38ec-64e1-503c-9950-18cc324d67c6/keys'
Result:
{
"kid": "/km/v1/groups/366f38ec-64e1-503c-9950-18cc324d67c6/keys/54872032-a16b-5c5e-a1c5-97f2656b7c24"
}
Delete keys
The following example deletes a key:
curl --cacert server_ca.pem \
--cert client_crt.pem –-key client_key.pem \
--request DELETE \
'https://wsop.server:18001/km/v1/groups/366f38ec-64e1-503c-9950-18cc324d67c6/keys/54872032-a16b-5c5e-a1c5-97f2656b7c24'
On successful deletion, 204 No Content
is returned.
Create Protection Domains
Create Protection Domain can only be performed with Softcard
Protection Domain types.
The following example creates a Protection Domain of type Softcard
.
curl --cacert server_ca.pem \
--cert client_crt.pem –-key client_key.pem \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--request POST \
-d '{"name":"softcard1","passphrase":"passphrase1","type":"Softcard"}' \
'https://wsop.server:18001/km/v1/protectiondomains' | jq
Result:
{
"id": "e3307c07-300e-585a-95da-ed4f3d0c226e"
}
Delete Protection Domains
Delete Protection Domain can only be performed with Softcard
Protection Domain types.
The following example deletes a Protection Domain and all associated keys.
curl --cacert server_ca.pem \
--cert client_crt.pem –-key client_key.pem \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--request DELETE \
'https://wsop.server:18001/km/v1/protectiondomains/025ad489-3ec8-5bbc-b251-f0e497f7cd48?cascade=keys' | jq
On successful deletion, 204 No Content
is returned.
List Protection Domains
List all Protection Domains:
curl --cacert server_ca.pem \
--cert client_crt.pem --key client_key.pem \
--header 'Accept: application/json' \
--request GET \
"https://wsop.server:18001/km/v1/protectiondomains"
Result:
{
"protectiondomains": [
{
"active": true,
"id": "366f38ec-64e1-503c-9950-18cc324d67c6",
"name": "Module Protection",
"type": "Module"
},
{
"active": false,
"id": "ccba7ee7-9032-5217-9db2-58d07fd4c045",
"name": "soft1",
"type": "Softcard"
},
//...
]
}
Activate Protection Domains
Activate a Protection Domain:
curl --cacert server_ca.pem \
--cert client_crt.pem –-key client_key.pem \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--request POST \
-d '\{"passphrase":"passphrase1"}' \
"https://127.0.0.1:18001/km/v1/protectiondomains/ccba7ee7-9032-5217-9db2-58d07fd4c045/activate"
Result:
{
"protectiondomain": {
"active": true,
"id": "ccba7ee7-9032-5217-9db2-58d07fd4c045",
"name": "soft1",
"type": "Softcard"
}
}
Deactivate Protection Domains
Deactivate a Protection Domain:
curl --cacert server_ca.pem \
--cert client_crt.pem –-key client_key.pem \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--request POST \
"https://127.0.0.1:18001/km/v1/protectiondomains/ccba7ee7-9032-5217-9db2-58d07fd4c045/deactivate"
Result:
{
"protectiondomain": {
"active": false,
"id": "ccba7ee7-9032-5217-9db2-58d07fd4c045",
"name": "soft1",
"type": "Softcard"
}
}
Sign payload
The following example signs a payload:
curl --cacert server_ca.pem \
--cert client_crt.pem –-key client_key.pem \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--request POST \
-d '\{"kid":"/km/v1/groups/366f38ec-64e1-503c-9950-18cc324d67c6/keys/e51a13d1-b775-3129-b1f9-b8642a212475",
"alg":"RS256",
"payload":"dGVzdCBkYXRhCg"}'
'https://wsop.server:18001/crypto/v1/sign'
Result:
{
"signature": "<base64url-encoded signature omitted>"
}
Verify signature
The resulting signature can be verified as follows:
curl --cacert server_ca.pem \
--cert client_crt.pem –-key client_key.pem \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--request POST \
-d '\{"kid":"/km/v1/groups/366f38ec-64e1-503c-9950-18cc324d67c6/keys/e51a13d1-b775-3129-b1f9-b8642a212475",
"alg":"RS256",
"payload":"dGVzdCBkYXRhCg",
"signature": "<base64url-encoded signature omitted>"}'
'https://wsop.server:18001/crypto/v1/verify'
Result:
{
"valid":true
}
Encrypt plaintext
The following example encrypts some plaintext:
curl --cacert server_ca.pem \
--cert client_crt.pem –-key client_key.pem \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--request POST \
-d '\{"kid":"/km/v1/groups/366f38ec-64e1-503c-9950-18cc324d67c6/keys/90050af4-9b8c-5731-bbf2-08e3af797e2c",
"alg":"RSA-OAEP-256",
"plaintext":"dGVzdCBkYXRhCg"}'
'https://wsop.server:18001/crypto/v1/encrypt'
Result:
{
"ciphertext": "<base64url-encoded ciphertext omitted>",
}
Decrypt ciphertext
The resulting ciphertext can be decrypted as follows:
curl --cacert server_ca.pem \
--cert client_crt.pem –-key client_key.pem \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--request POST \
-d '\{"kid":"":"/km/v1/groups/366f38ec-64e1-503c-9950-18cc324d67c6/keys/90050af4-9b8c-5731-bbf2-08e3af797e2c ",
"alg":"RSA-OAEP-256",
"ciphertext":"<base64url-encoded ciphertext omitted>"}'
'https://wsop.server:18001/crypto/v1/decrypt'
Result:
{
"plaintext": "dGVzdCBkYXRhCg"
}
Health check
The health of the system can be checked as follows:
curl --cacert server_ca.pem \
--cert client_crt.pem –-key client_key.pem \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--request GET \
'https://wsop.server:18001/health'
Result:
{
"releaseId": "1.2.0",
"status": "pass",
"version": "1"
}
The health check endpoint can be configured to not require TLS mutual authentication while retaining mutual authentication on all other endpoints. For more information, see Configuration. |
Error handling
In the event of a failed request, errors are reported to the client by using the HTTP response codes that indicate errors and an appropriate error message and error code in the response body in JSON format.
For example:
{
"error": "ResourceNotFound",
"message": "loading key /km/v1/groups/366f38ec-64e1-503c-9950-18cc324d67c6/keys/98487743-2ac4-5fe9-81ba-95eb4a93cae4 failed: unknown key",
"path": "/crypto/v1/sign",
"status": "404",
"timestamp": "2019-12-05T09:58:40Z"
}
Language bindings
An OpenAPIv2-compliant API description is provided (/opt/nfast/wsop/docs/swagger.yml
).
This represents the Web Services Option Pack REST API, which can be used for generating bindings for a number of programming languages using tools provided as part of Smartbear’s Swagger.
The correctness of the generated bindings from Smartbear’s Swagger tooling cannot be guaranteed due to numerous issues with the generators. For more information, see the documentation provided by Smartbear. |