SignServer REST endpoints using cURL
Using CURL
The examples provided use cURL to send requests to the SignServer REST endpoints.
The base https URL used for all admin requests is:
https://localhost:8443/signserver/rest/v1
And the base http URL used for signing requests is:
http://localhost:8080/signserver/rest/v1
Configure Workers Using REST Endpoints in SignServer
Add New Worker
Adding a new worker can be done from two endpoints. You can choose to provide a specific ID in the URL. If you do not provide an ID, SignServer sets the next available one for you.
Endpoint: POST /workers or /workers/id
Example request to create a PlainSigner:
curl --location --cert dss10_admin1.p12 --cert-type p12 --pass foo123 --request POST 'https://localhost:8443/signserver/rest/v1/workers' \
--header 'X-Keyfactor-Requested-With: X' \
--header 'Content-Type: application/json' \
--data-raw '{
"properties": {
"NAME": "PlainSigner",
"IMPLEMENTATION_CLASS": "org.signserver.module.cmssigner.PlainSigner",
"TYPE": "PROCESSABLE",
"AUTHTYPE": "NOAUTH",
"CRYPTOTOKEN": "CryptoTokenP12",
"DEFAULTKEY": "signer00003",
"DISABLEKEYUSAGECOUNTER": "true"
}
}'
If the request is successful, SignServer does not return any errors. If the request fails, SignServer returns an error message with the cause of the failure.
Example error message of a conflict with the chosen worker name:
{"error":"Worker already exists: PlainSigner"}
Get Worker Configuration
You can request the full configuration of all workers from the SignServer instance or a more detailed configuration for one specific worker ID.
Endpoint: GET /workers
The GET /workers endpoint only returns the ID and name of the existing workers on the SignServer instance. It does not look at the body even if one is provided.
Example request:
curl --location --cert dss10_admin1.p12 --cert-type p12 --pass foo123 --request GET 'https://localhost:8443/signserver/rest/v1/workers' \
--header 'X-Keyfactor-Requested-With: X'
Example response to an empty body:
{
"workers": [
{
"id": 1,
"name": "CryptoTokenP12"
},
{
"id": 2,
"name": "PlainSigner"
}
]
}
Endpoint: GET /workers/id
The GET /workers/id endpoint can provide a more detailed configuration for a specified worker. This endpoint also does not look at the body even if one is provided.
Example request:
curl --location --cert dss10_admin1.p12 --cert-type p12 --pass foo123 --request GET 'https://localhost:8443/signserver/rest/v1/workers/2' \
--header 'X-Keyfactor-Requested-With: X'
Example response for the provided ID pointing to an existing PlainSigner:
{
"properties": {
"CRYPTOTOKEN": "CryptoTokenP12",
"AUTHTYPE": "NOAUTH",
"IMPLEMENTATION_CLASS": "org.signserver.module.cmssigner.PlainSigner",
"DEFAULTKEY": "signer00003",
"TYPE": "PROCESSABLE",
"DISABLEKEYUSAGECOUNTER": "true",
"NAME": "PlainSigner"
}
}
Change Worker Configuration
Endpoint: PATCH /workers/id
The PATCH /workers/id request only needs to contain the properties that you want to be added or changed. Remaining worker properties are not affected by this request.
Use this endpoint to:
Change an existing property by providing a different value.
Add a property by providing it in the request body.
Example body for changing the name of the worker:
curl --location --cert dss10_admin1.p12 --cert-type p12 --pass foo123 --request PATCH 'https://localhost:8443/signserver/rest/v1/workers/2' \
--header 'X-Keyfactor-Requested-With: X' \
--header 'Content-Type: application/json' \
--data-raw '{
"properties": {
"NAME": "NewPlainSigner"
}
}'
If the request is successful, SignServer returns:
{
"responseMessage": "Worker properties successfully updated"
}
If the request fails, SignServer returns an error message with the cause of the failure.
Example error message for trying to make changes to a worker ID that does not exists:
{
"error": "No such worker: 3"
}
Endpoint: PUT /workers/id
The PUT /workers/id request needs to contain all the properties of the worker. This endpoint overwrites the full configuration of the provided worker ID.
Use this endpoint to:
Change an existing property by providing a different value.
Remove a property by not providing it in the request.
Add a property by providing it in the request body.
If you do not want to change a property, you need to provide that property with the current value.
Example request for changing the name of the worker:
curl --location --cert dss10_admin1.p12 --cert-type p12 --pass foo123 --request PUT 'https://localhost:8443/signserver/rest/v1/workers/2' \
--header 'X-Keyfactor-Requested-With: X' \
--header 'Content-Type: application/json' \
--data-raw '{
"properties": {
"CRYPTOTOKEN": "CryptoTokenP12",
"AUTHTYPE": "NOAUTH",
"IMPLEMENTATION_CLASS": "org.signserver.module.cmssigner.PlainSigner",
"DEFAULTKEY": "signer00003",
"TYPE": "PROCESSABLE",
"DISABLEKEYUSAGECOUNTER": "true",
"NAME": "NewPlainSigner"
}
}'
If the request is successful, SignServer returns:
{
"responseMessage": "Worker properties successfully updated"
}
If the request fails, SignServer returns an error message with the cause of the failure.
Example error message for trying to make changes to a worker ID that does not exists:
{
"error": "No such worker: 3"
}
Remove Worker
Endpoint: DELETE /workers/id
The DELETE /workers/id endpoint removes the worker with the provided ID. The endpoint will not take any body input from the request.
Example of removing a worker with id 2:
curl --location --cert dss10_admin1.p12 --cert-type p12 --pass foo123 --request DELETE 'https://localhost:8443/signserver/rest/v1/workers/2' \
--header 'X-Keyfactor-Requested-With: X'
If the request is successful, SignServer returns:
{
"responseMessage": "Worker removed successfully"
}
If the request fails, SignServer returns an error message with the cause of the failure.
Example error message for trying to delete a worker ID that does not exists:
{
"error": "No such worker: 2"
}
Reload from database
Endpoint: POST /workers/reload
The POST /workers/reload endpoint reloads the configuration from database. If the request metadata is left empty, it reloads all the workers.
Example of request reloading all workers:
curl --location --cert dss10_admin1.p12 --cert-type p12 --pass foo123 --request POST 'https://localhost:8443/signserver/rest/v1/workers/reload' \
--header 'X-Keyfactor-Requested-With: X'
If the request for reloading all workers is successful, SignServer returns:
{
"responseMessage": "All workers successfully reloaded"
}
If you only want to reload specific workers, the wanted worker IDs can be provided in the body of the request.
Example request for reloading defined worker IDs:
curl --location --cert dss10_admin1.p12 --cert-type p12 --pass foo123 --request POST 'https://localhost:8443/signserver/rest/v1/workers/reload' \
--header 'X-Keyfactor-Requested-With: X' \
--header 'Content-Type: application/json' \
--data-raw '{
"workerIDs": [
1, 2
]
}'
If the request is successful, SignServer returns:
{
"responseMessage": "Workers successfully reloaded"
}
If the request fails, SignServer returns an error message with the cause of the failure.
Example error message for trying to reload a worker ID that does not exists:
{
"error": "No such worker: 3"
}
Using REST endpoint for Signing
Signing request
Endpoint: POST /workers/{IDorName}/process
The following provides an example of signing some sample data. This example assumes that you have a PlainSigner set up in SignServer.
Example of a request for a PlainSigner:
curl --location --request POST 'http://localhost:8080/signserver/rest/v1/workers/2/process' \
--header 'X-Keyfactor-Requested-With: X' \
--header 'Content-Type: application/json' \
--data-raw '{
"data": "Sample Data!"
}'
Response:
{
"archiveId":"12aab5dba45d5fbe538a1d210287ae4912df677b",
"data":"P2TkMBhhwDGfu9OUarAf65Z2h2gkDYqiQGV6WPi+N6mdxxbi8g14k+BvCz47yhDAVD3D/bJhP+L5knYQ92rgfcf7AS2o2o7ppzCE0ZvEtY0mZHL/7GAe4ZnuK+8cqeK1kP9mY9/dIWsZelZb8LPLVsC/rdFBAW89LsGzvjw6mEK1Zle4JkkqM7K+c1bnOYWYaLxIXTgxgPz6i9ccMoYREUntZ0srf2rKcv1k1W0/kc8G0R3CjC8Hje/J+FpIAOtd89kG4nvqa/OPt8GqipnXAmPXpCOuDAvDsWEJL32x+QHqdkl4ixaeAxFWnougm/qL0MZF6KmYXXm/wXqTD2o6pA==",
"metaData":{},
"requestId":"1277380144",
"signerCertificate":"MIIDlzCCAn+gAwIBAgIIOdPbElQbJhcwDQYJKoZIhvcNAQELBQAwTDEWMBQGA1UEAwwNRFNTIFN1YiBDQSAxMTEQMA4GA1UECwwHVGVzdGluZzETMBEGA1UECgwKU2lnblNlcnZlcjELMAkGA1UEBhMCU0UwHhcNMTYwMzAzMDgyNTA0WhcNMzYwMjI3MDgyNTA0WjBKMRQwEgYDVQQDDAtzaWduZXIwMDAwMzEQMA4GA1UECwwHVGVzdGluZzETMBEGA1UECgwKU2lnblNlcnZlcjELMAkGA1UEBhMCU0UwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCyFKqwwiHS2o4PO3zovqC+jGuIELnja1iAlg/hyrRp28mF6BOGVaKE6ZzbQIMmmICRz+EeqXN1W8gyCEh6T2qN3QvXTAF9mrrUI3hG4Xn/Davgsln8saRE0zt45yy47dPq5YofYJWWIdW/6qssiX+ApcPqthCQfkgraUSagS/Reqy0WT/A2lwKh147GB9+MxhheskQIPaKQasOpI7vGfzey+GnkHPsfU21irS2nC8uzv6hd0G6hNYUEmJtIh9/5WebMoMiGFq1sydTtZp7pJilfPyxrAkHXEwMUEEMcVlE/ISCoKMttnLMUT/F00cHesU4D2yNl6gcSjpMj4Q/iF+hAgMBAAGjfzB9MB0GA1UdDgQWBBQ2/WY3Ln7tdUmDrTyvtvSZwBg8YzAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFBxgQUremK3l1gOK6GaCqX6w8gKHMA4GA1UdDwEB/wQEAwIF4DAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwQwDQYJKoZIhvcNAQELBQADggEBAIUh6kkCMc0Fs6U+Sw6Ns0Yd28Fb5SM//nE6mq3mf1SD4lAyChVrFvlqMZJaqeJlkVeHc9E+KCE5bX1r2iGC8rnE9DuItI0pKMrgFt4cbSbDwgovnTrkiIhuqP2pjdhmrHtlLqZBR8e16c4xGSn6XWKJ8vPzx2AJl7MY3sY3Z4aPckBFNjG1lzH1inq5WM/+WaLghOQQngaXeU+SWpoAM7cUjB8Uyjf2Qr2GerI4AZZJMuC6BuvMdFMyXX78l7c9qmvK9Bre+SFKdtcMAgnglLzu0lyPHPwYL0R+pwc5dFOJipafxeqeHGpkZTXMsdMn6f1USRznlGbRWru68/XOOFU="
}
If the request fails, SignServer returns an error message with the cause of the failure.
Clientside hashing
Endpoint: POST /workers/{IDorName}/process
The following provides an example of signing some sample data with clientside hashing. This example assumes that you have a PlainSigner set up in SignServer. The PlainSigner needs to have ALLOW_CLIENTSIDEHASHING_OVERRIDEset to true.
When the client sends the request, the following properties need to be provided as request metadata:
USING_CLIENTSUPPLIED_HASH=trueCLIENTSIDE_HASHDIGESTALGORITHM=SHA-256
In CLIENTSIDE_HASHDIGESTALGORITHM=SHA-256, replace SHA-256 with the name of the hash algorithm used to digest the data. The algorithm must be one of those configured in the signer with the ACCEPTED_HASH_DIGEST_ALGORITHMS property.
These properties can be provided in the metadata of the request.
For clientside hashing, the encoding of the data needs to be set to BASE64, and the data needs to be base64 encoded binary.
Example for formatting data:
$ echo "Sample" > sample.txt
$ openssl dgst -sha256 -out pre-computed-hash.bin -binary sample.txt
$ base64 pre-computed-hash.bin
47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=
Example of a request for a PlainSigner using clientsidehashing:
$ curl --location --request POST 'http://localhost:8080/signserver/rest/v1/workers/2/process' \
--header 'X-Keyfactor-Requested-With: X' \
--header 'Content-Type: application/json' \
--data-raw '{
"metaData": {
"CLIENTSIDE_HASHDIGESTALGORITHM": "SHA-256",
"USING_CLIENTSUPPLIED_HASH": "true"
},
"data": "47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=",
"encoding": "BASE64"
}'
Response:
{
"archiveId":"bdce6dbdfeb4207979ac5047e000da6aaa1085ad",
"data":"Eb/2MbFLQR0kSJ0uUveIdP6qF8xwaphpHbm4yFZDM9NmekMl1TMvCEh7E9sipFTWfhC97b5BtOyQLH6tucwz8j9VD+b534uhvpkwTOjbSkDpAzgTsmfXLlzaOt8/X8/HbYpr+RTQQPXM2pGEc7s8OxqnQetAU7aadPXDHPN14C71oGTGVDn6tLMlSgOhPL2L3d8qKAlWlxEJPhInLA4BwyOuJ7X45dpJS2rO0sKRyHWS1T+z1cHf41hDvlTaX9xmYiYkNC9s0kwV4xwBNjGebs2I0vtHVT/99l47/sj/vCk191IDPupfrtAMHpBo3EMsuuLn0xbVkI0Tkil4Emrp6A==",
"metaData":{},
"requestId":"465995014",
"signerCertificate":"MIIDlzCCAn+gAwIBAgIIOdPbElQbJhcwDQYJKoZIhvcNAQELBQAwTDEWMBQGA1UEAwwNRFNTIFN1YiBDQSAxMTEQMA4GA1UECwwHVGVzdGluZzETMBEGA1UECgwKU2lnblNlcnZlcjELMAkGA1UEBhMCU0UwHhcNMTYwMzAzMDgyNTA0WhcNMzYwMjI3MDgyNTA0WjBKMRQwEgYDVQQDDAtzaWduZXIwMDAwMzEQMA4GA1UECwwHVGVzdGluZzETMBEGA1UECgwKU2lnblNlcnZlcjELMAkGA1UEBhMCU0UwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCyFKqwwiHS2o4PO3zovqC+jGuIELnja1iAlg/hyrRp28mF6BOGVaKE6ZzbQIMmmICRz+EeqXN1W8gyCEh6T2qN3QvXTAF9mrrUI3hG4Xn/Davgsln8saRE0zt45yy47dPq5YofYJWWIdW/6qssiX+ApcPqthCQfkgraUSagS/Reqy0WT/A2lwKh147GB9+MxhheskQIPaKQasOpI7vGfzey+GnkHPsfU21irS2nC8uzv6hd0G6hNYUEmJtIh9/5WebMoMiGFq1sydTtZp7pJilfPyxrAkHXEwMUEEMcVlE/ISCoKMttnLMUT/F00cHesU4D2yNl6gcSjpMj4Q/iF+hAgMBAAGjfzB9MB0GA1UdDgQWBBQ2/WY3Ln7tdUmDrTyvtvSZwBg8YzAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFBxgQUremK3l1gOK6GaCqX6w8gKHMA4GA1UdDwEB/wQEAwIF4DAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwQwDQYJKoZIhvcNAQELBQADggEBAIUh6kkCMc0Fs6U+Sw6Ns0Yd28Fb5SM//nE6mq3mf1SD4lAyChVrFvlqMZJaqeJlkVeHc9E+KCE5bX1r2iGC8rnE9DuItI0pKMrgFt4cbSbDwgovnTrkiIhuqP2pjdhmrHtlLqZBR8e16c4xGSn6XWKJ8vPzx2AJl7MY3sY3Z4aPckBFNjG1lzH1inq5WM/+WaLghOQQngaXeU+SWpoAM7cUjB8Uyjf2Qr2GerI4AZZJMuC6BuvMdFMyXX78l7c9qmvK9Bre+SFKdtcMAgnglLzu0lyPHPwYL0R+pwc5dFOJipafxeqeHGpkZTXMsdMn6f1USRznlGbRWru68/XOOFU="
}
If the request fails, SignServer returns an error message with the cause of the failure.
Example for verifying:
$ echo Eb/2MbFLQR0kSJ0uUveIdP6qF8xwaphpHbm4yFZDM9NmekMl1TMvCEh7E9sipFTWfhC97b5BtOyQLH6tucwz8j9VD+b534uhvpkwTOjbSkDpAzgTsmfXLlzaOt8/X8/HbYpr+RTQQPXM2pGEc7s8OxqnQetAU7aadPXDHPN14C71oGTGVDn6tLMlSgOhPL2L3d8qKAlWlxEJPhInLA4BwyOuJ7X45dpJS2rO0sKRyHWS1T+z1cHf41hDvlTaX9xmYiYkNC9s0kwV4xwBNjGebs2I0vtHVT/99l47/sj/vCk191IDPupfrtAMHpBo3EMsuuLn0xbVkI0Tkil4Emrp6A==
| base64 --decode > sample.sig
$ openssl dgst -signature sample.sig -verify plainsigner-pubkey.pem -SHA256 sample.txt
Verified OK
File upload
Endpoint: POST /workers/{IDorName}/process
The following provides an example of uploading and signing a PDF using multipart/form-data. This example assumes that you have a SignServer PDF Signer set up in SignServer.
In this example, a password-protected PDF is signed to also display how to properly set additional request metadata properties that will be sent to the signer.
Example for uploading and signing a PDF using PDF Signer:
curl --output test_signed.pdf --location --request POST 'http://localhost:8080/signserver/rest/v1/workers/{idOrName}/process' \
--header 'X-Keyfactor-Requested-With: REST' \
--header 'Accept: application/octet-stream' \
--form 'myfile=@"test.pdf"' \
--form 'REQUEST_METADATA.pdfPassword="foo123";type=multipart/form-data;charset=utf-8'