SignServer
Search signserver.org for:

SignServer Manual

Introduction

Introduction/scope

The SignServer is an application framework performing cryptographic operations for other applications. It's intended to be used in environments where keys are supposed to be protected in hardware but there isn't possible to connect such hardware to existing enterprise applications or where the operations are considered extra sensitive so the hardware have to protected more carefully. Another usage is to provide a simplified method to provide signatures in different application managed from one location in the company.

The SignServer have been designed for high-availability and can be clustered for maximum reliability.

The SignServer comes with a RFC 3161 compliant Time-Stamp signer serving requests through HTTP or client-authenticated HTTPS. A MRTD (Machine Readable Travel Document, i.e. electronic passport) signer. A PDF signer that adds a signature automatically to a uploaded PDF document, ODF signer that adds a signature automatically to uploaded ODF document, OOXML Signer that adds signature automatically to a uploaded OOXML document, and a validation service used to lookup the validation of a given certificate.

architecture
Drawing 1: Overview of a possible set up of a highly available SignServer solution

Changes from previous versions

Changes between version 3.1 and 3.2

  • A new administration web service (WS) for remote administration of SignServer.
  • A new administration GUI desktop application for managing workers. Supports key generation and both local and remote administration.
  • A new client command line interface (CLI) for requesting signing and validation.
  • Support for GlassFish Server 2.1.1.
  • Support for JBoss Application Server 5.1.
  • Support for Oracle Database.
  • Worker renewing signers by generating new keys and sending certificate requests to EJBCA.
  • Better audit and transaction logging.
  • New build scripts and project structure with the goal of decouple the different SignServer modules and sub-projects and simplify future development.
  • Front page listing all demo web pages.
  • The bundled SMTP server and MailSigner build of SignServer has been removed.

Changes between version 3.0 and 3.1

  • A new Cluster Class Loader, simplifying the management of customized workers in a cluster. All the resource data including the classes themselves are stored in database and accessible from all nodes simultaneously. It is also possible to run multiple versions of the same worker in the same SignServer cluster, this is useful when migrating a worker to new code since both the old and new worker can be run at the same time.
  • PDF Signer, Time-Stamp Authority and MRTD and their specific libraries have the possibility to build into separate module archives (MAR files) that have to be uploaded to the SignServer installation before usage, if the cluster classloader is enabled (default).
  • Installation packages for Linux/Windows of both SignServer and MailSigner using generation software from Bitrock.
  • New extended module for signing ePassports: MRTD-SOD.
  • New modules for signing and validating XML documents.
  • A new ODF Signer module that adds signature to ODF documents, such as : odt,ods,odt (tested with OpenOffice.org 3.1.0). Simple web page is added where ODF document can be uploaded for signing, and resulted signed document downloaded.
  • A new OOXML Signer Module that adds signature to Office Open XML documents, such as docx,xlsx,pptx (tested with Microsoft Office 2007).Simple web page is added where open office xml document can be uploaded for signing, and resulted signed document downloaded.
  • Validators for several document types as well.
  • Java 5 is no longer supported.
  • For minor changes see the change log at http://jira.primekey.se

Changes between version 2 and 3

  • Complete refactorisation of J2EE from EJB2 to EJB3 to simplify further development.
  • Renamed component "Service" to "TimedService" since 3.0 supports other services.
  • A "TimedService" can now be configured with a 'cron-like' settings to have services executed in other than just periodical intervals.
  • A Validation Service API used to validate certificate from different issuers. The Validation Service API have it's own easy to use Web Service used to integrate with other platforms. A Group Key Service API used to generate and manage group keys, symmetric or asymmetric.
  • Possibility to have customized authorization of requests, not just the built in client certificate authorization list.
  • The name SignToken is changed to CryptoToken and introduced a new concept of ExtendedCryptoToken that supports symmetric operations.
  • The RMI-SSL interface have been removed and replaced with a JAX-WS interface with a simple client framework supporting different load-balance or high availability policies.
  • All request data have changed from serialization to externalization to be easier to translate to other platforms.
  • A completely new MailSigner API based upon the JAMES SMTP server to perform automated cryptographic operations on e-mails very similar to the plug-ins for the SignServer.
  • Java 1.4 is no longer supported.
  • A lot of new JUnit tests in the test suite.
  • A PDF Signer that can add a signature to a PDF document through a simple HTML interface.
  • PKCS11 Crypto Token to connect to different PKCS11 implementations.

Changes between version 1 and 2

  • signserver_server.property file have been removed and replaced with a global configuration store.
  • It is now possible to dynamically add and remove available signers
  • A new type of component, "Service" that is run on a timely basis, used to perform maintenance or report generation.
  • Improved cluster deployment functionality.
  • New CLI tools to batch configure the SignServer, and to backup a current configuration.
  • This makes it possible to set-up a configuration in test environment, dump the configuration and configure the same it in production.

Terms Used in This Document

Term Explanation
Signer A Processable service performing signatures upon requests. This could be a ready made signer or a custom developed one.
Crypto Token (former Sign Token) A Crypto Token is a name for the entity containing the private key and is responsible for its cryptographic operations. Every Processable have a Crypto Token that can be a PKCS12, Smart Card or HSM connection.
Extended Crypto Token An enhanced Crypto Token with support for symmetric key operations.
PKCS11CryptoToken A Crypto Token able to communicate with Hardware Security Modules through the standard PKCS11 interface.
TimedService (former Service) A TimedService is a task that is run on a timely basis, performing maintenance tasks like changing active key or generate a report.
Worker A common name for Processable (Signer or other type of service) and TimedService
Processable A type of worker that is used to process requests, i.e. not a TimedService.
Worker Configuration Each Worker can be configured with properties specific for that worker. There are two sets of worker configuration one "Active" that is used by the signer and one "current" which is the one configured by the administrator. The current configuration isn't used in production until the administrator issued the reload command. This makes it possible for the administrator to configure multiple properties and double-check them before they are actually used.
Global Configuration Store Is a dynamic store used to define available Workers and their Crypto Tokens. But other data that needs to be read globally could be set there as well. The global configuration properties are activated immediately. There are two different scopes for the store data, Global Scope and Node Scope.
Global Scope Data stored in the global configuration that can be read by all nodes in the cluster.
Node Scope Data that is node specific and can only be read within the same node.
Worker Id Unique identifier of a worker, an integer larger than 0
Worker Name A name used as a human readable synonym for a Worker Id
Validation Service A Processable that checks if a certificate is valid or not. Have a Default Validation Service implementation that should work in most cases.
A Validation Service should have one or more Validators configured.
Group Key Service A Processable that can be used to manage, generate and distribute group keys to a set of clients. The service support four types of calls, fetch group key (used by clients), pre-generate group keys, switch encryption key (key used to safely store the group keys in database) and remove group keys. There exists a Default Group Key Service that should satisfy most use cases.
Certificate Validator (former Validator) A Certificate Validator is responsible for checking the status of one or more issuer's certificates. This could be as an OCSP client or a CRL checker or just looking up the status in a database.
Document Validator A Document Validator is validating a signed document by checking its signature and corresponding certificate(s) and returns the validation result.
Authorizer An interface that enables developers to integrate the authorization parts with existing authorization systems of who is authorized to perform requests to a Processable.
Time Stamp Signer A Signer that can be used to set up a Timestamp Authority according to RFC 3161.
MRTD Signer A Signer that performs signatures of MRTD (Machine Readable Travel Documents, i.e. Electronic Passports) blobs.
MRTD SOD Signer A Signer that creates the complete security object (SOd) for a MRTD (Machine Readable Travel Document, i.e. Electronic Passports) by signing the data groups.
PDF Signer A Signer that attaches an electronic signature signature to a PDF document.
XML Signer A Signer that puts in an enveloped signature in XML documents (XMLDSig)
XML Validator A Document Validator that validates signed XML documents (XMLDSig)
ODF Signer A Signer that attaches an electronic signature to an ODF document. ODF Signer is tested with documents produced by OpenOffice.org v 3.1.0
ODF (Open Document Format) Document XML-based file format for representing electronic documents such as spreadsheets, charts, presentations and word processing documents. more...
OOXML (Office Open XML) Document XML-based file format for representing spreadsheets, charts, presentations and word processing documents. more...
OOXML Signer A Signer that attaches an electronic signature to an OOXML document.
Cluster Class Loader A Java Class Loader specific for the SignServer project. The class loader simplifies the distribution of new code to a cluster by uploading and fetching it from database. It also enables the use of multiple versions of the same worker code in the same cluster.
Module Archive or MAR file A 'Module Archive' is a specific packaging format used by the cluster class loader to upload code to a cluster. A MAR files is structured in a specific way with a descriptor containing module and version information. The MAR file also contains one or more parts depending on were in the system the code will be deployed.
A Module Archive have the postfix .mar and can be generated with a specific ANT-task.
Archiver Implementation handling archiving of a worker's response by storing it in a database or similar.

Overall Architecture

The SignServer is a framework designed to perform different kind of cryptographic operations for different applications.

Since the 3.0 version there are three kind of processable services. Signers (used to sign or in other way process requested data). Validation Services used to verify the validity of a certificate against a set of backed issuers. The validation service can be used to simply the integration of PKIs into existing applications. The the third processable service is a group key service framework used to manage and to distribute group keys for different applications, these keys can be both symmetric and asymmetric. In addition to processable services there also exists another concept called Timed Service (called just 'service' in 2.0 edition) which are plug-ins run at defined intervals performing maintenance or reporting routines.

Out-of-the-box are there three Signers ready to be used. They are a MRTD Signer used for signing Machine Readable Travel Documents (also known as Electronic Passports), a Timestamp Signer that can be used to set up a Timestamp Authority and a PDF signer that can be used to automatically sign documents.

The main way of communicating with the SignServer is through a WebService interface (previous versions had a RMI-SSL interface, but that have been replaced by the WS for better platform independence.) but the Timestamp Signer is also available through HTTP communication and the PDF signer have a simple HTML page that allows users to upload documents to be signed.

For an overview of the different concepts in the SignServer see illustration 1. The base component is called Worker which is assigned an id, optionally a name and a configuration. A sub component is a Processable which receives and processes requests. A Processable (optionally) have access to a cryptographic token (CryptoToken) in charge of managing the keys of a Processable. A CryptoToken can be either software or hardware based.

The applications i administrated through a command-line interface, where the properties and access control can be configured.

One SignServer can have multiple services for different purposes.

SignServer components
Illustration 1: Components in the SignServer project

Installation Guide

Server installation

1. Check prerequisites

Make sure all required softwares are installed:

  • Java: Sun/Oracle JDK 6 Update 10 or later or OpenJDK*
  • Application server: JBoss 4.2.3.GA**, JBoss 5.1.0.GA or GlassFish Server Open Source Edition 2.1.1
  • Database: HypersonicSQL (bundled with JBoss), MySQL 5.1 or Oracle Database 10/11g
  • Build tool: Apache Ant 1.7.1 or later

* The ODFSigner has issues with OpenJDK. Please see DSS-168 for a workaround.
** JBoss 4.2.3.GA is available in two different versions (standard and JDK6) which differens in web services stacks. The one called JBoss 4.2.3.GA-JDK6 should be used.

2. Unpack SignServer

Download and unzip the latest SignServer release archive from SourceForge or for the absolutly latest unstable version checkout from the Subversion (SVN) repository.

3. Set environment variables

*** APPSRV_HOME ***

Set APPSRV_HOME to point to your application server installation.

export APPSRV_HOME=/opt/jboss-4.2.3.GA
                        
*** ANT_HOME ***

Set ANT_HOME to point to your Apache Ant installation.

export ANT_HOME=/usr/share/ant
                        
*** ANT_OPTS ***

Set ANT_OPTS to give Ant more memory for building SignServer.

export ANT_OPTS="-Xmx512m -XX:MaxPermSize=128m"
                        
*** SIGNSERVER_HOME ***

Set SIGNSERVER_HOME to point to your SignServer installation.

export SIGNSERVER_HOME=/opt/signserver
                        
*** SIGNSERVER_NODEID ***

Set SIGNSERVER_NODEID to an unique ID for the server.

export SIGNSERVER_NODEID=node1
                        

4. Setup database

Create a database and user for SignServer. The application server will try to create tables during startup of SignServer but if the database user does not have table create permissions or if you run on Glassfish the tables must be created manually. See doc/howtos/create-tables-signserver32-*.sql.

Copy the driver for your database to the application server lib folder.

For GlassFish also configure a connection pool and JNDI resource:

  1. Go to the Admin Console: http://localhost:4848
  2. Click on Resources -> JDBC -> Connection Pools
  3. Add a new Pool. For instance: Name: MySQLPool
  4. Fill in:
    databaseName: signserver
    password: signserver
    portNumber 3306
    serverName: localhost
    user: signserver
  5. Click Ping to test
  6. Click on Resources -> JDBC -> JDBC Resources
  7. Add new:
    JNDI Name: jdbc/SignServerDS
    Pool Name: MySQLPool

4. Configure web server keystores

For JBoss if you are going to protect the HTTP communication with SSL, you need a JKS SSL server keystore. Rename the web server keystore to tomcat.jks at put it in a 'p12' subdirectory. Also place the web server root certificate in DER encoding in the same directory, call it rootcert.cer.

For GlassFish enable client authentication for http-listener-2 and manually update the keystores with the right certificates.

5. Configure application server

*** Fix web service problem in JBoss ***

Edit jboss-beans.xml to force the endpoint URL to be generated based on the WSDL request by commenting out the line:

    <property name="webServiceHost">${jboss.bind.address}</property>

For JBoss 4.2.3.GA the file is available under: server/default/deploy/jbossws.sar/jbossws.beans/META-INF/

For JBoss 5.1.0.GA the file is available under: server/default/deployers/jbossws.deployer/META-INF/

*** Fix JBoss 5 bug with Oracle JDK ***

If you are using Oracle's JDK and JBoss 5.1.x you need to copy SIGNSERVER_HOME/lib/1.6/bc*.jar to JBOSS_HOME/server/default/lib/. Remember this when it's time for upgrades! This is a bug tracked by JBoss as JBAS-7882.

6. Configure build

Copy signserver_build.properties.sample to signserver_build.properties and open it for editing in your favorite text editor.

cp signserver_build.properties.sample signserver_build.properties
                    
*** Application server configuration ***

Set appserver.type to the application server (jboss or glassfish).

appserver.type=jboss
                        
*** Web GUI configuration ***

Uncomment j2ee.web-nohttps=true if SignServer should be used to configure the keystore in JBoss.

#j2ee.web-nohttps=true
                        

For GlassFish change httpserver.privhttps to a port configured with HTTPS and client authentication.

httpserver.privhttps=8181
                        
*** Database configuration ***

For GlassFish make sure the datasource.jndi-name and datasource.jndi-name-prefix matches the resource configured in the admin console.

datasource.jndi-name=SignServerDS
datasource.jndi-name-prefix=jdbc/
                        

Select database management system

database.name=mysql
                        

For JBoss set the database connection URL, database driver and username and password.

database.url=jdbc:mysql://127.0.0.1:3306/signserver
database.driver=com.mysql.jdbc.Driver
database.username=signserver
database.password=signserver
                        
*** Web Service Configuration ***

Enable or disable the web services.

signserverws.enabled=true
genericws.enabled=true
validationws.enabled=true
adminws.enabled=true
                        
*** Modules Configuration ***

Enable all modules that should be built and choose if they should be included in the SignServer enterprise application archive (EAR). By setting includemodulesinbuild=true (default) all modules are built in. Otherwise for each module specify that it should be enabled and included:

module.xmlsigner.enabled=true
module.xmlsigner.include=true
...
                        

For GlassFish to enable debug logging include the Log4j module.

module.log4j.enabled=true
module.log4j.include=true
                        
*** Cluster Class Loader Configuration ***

The cluster class loader can be used in development for having the code of the signers loaded on all nodes. If it is not used the modules must be built into signserver.ear either by specifying that for each module (as in previous section) or by specifying includemodulesinbuild=true to include all modules.

Notice that this feature is experimental and should not be used in production. It will be removed in future versions of SignServer.

To enable the cluster class loader specify:

useclusterclassloader=true
                        

7. Build and deploy SignServer

Run "ant deploy" to build SignServer and deploy it to the selected application server. If the configuration changed since the last build run the clean target first.

ant clean deploy
                    

Start the application server and verify that SignServer was deployed and database tables were created.

8. Accessing SignServer

After startup a few different user interfaces are available.

*** Command Line Interface ***
bin/signserver.sh getstatus brief all
Assuming JBoss JNDI provider...
===========================================
Executing Command on host : localhost
===========================================


Current version of server is : SignServer 3.2-svn
                    
*** Graphical User Interface ***
bin/admingui.sh	
						
*** Web Interface ***

Point your web browser to http://localhost:8080/signserver for demo web pages and local documentation.

Signer setup

After server installation the different signers can be setup using the SignServer CLI.

Loading signers

Signers (and other workers) can be loaded in two different ways. Either using "module add" or by setting properties using "setproperty" or "setproperties" etc.

*** module add ***

The "module add" command loads both the code and the configuration from a MAR file and thus requires the clustered class loader to be enabled.

bin/signserver.sh modules add dist-server/MODULE.mar CONFIGURATION
                        
*** setproperties ***

The "setproperties" command loads all the properties from a property file that can define one or many signers. The code for the signers needs to be deployed to the application server together with SignServer either by setting includemodulesinbuild=true to include all modules or by setting individual module.MODULENAME.include=true properties in signserver_build.properties.

bin/signserver.sh setproperties doc/sample-configs/CONFIGURATION.PROPERTIES
                        

After adding or changing a property for a worker (either with "module add" or by any of the "setpropery" or "setproperties" commands) the configuration needs be applied by issuing the reload command with the ID of the worker.

bin/signserver.sh reload 4711
                    

Quick start demo Timestamp signer

This is a quick start guide to quickly get you setup with a demo Time Stamp service (TSA according to RFC3161). It will let you quickly get a feeling how the structure of the SignServer works, so you can move on to more advanced features described in the manual.

  1. Make sure the tsa module is built in by setting module.tsa.enabled=true and module.tsa.include=true in signserver_build.properties before building and deploying SignServer. Alternativly, set includemodulesinbuild=true to have all modules built in.
  2. Load the Timestamp demo configuration and notice the generated worker ID (in this example 1):
    $ bin/signserver.sh setproperties doc/sample-configs/qs_timestamp_configuration.properties
  3. Activate the configuration with:
    $ bin/signserver.sh reload 1
  4. You can check the status and configuration with:
    $ bin/signserver.sh getstatus complete all
  5. Run the test client to see that everything is up:
    $ bin/client.sh timestamp http://localhost:8080/signserver/process?workerName=TimeStampSigner
    The message "TimeStampRequest validated" should appear once a second. Also check JBOSS_HOME/server/default/log/server.log or GLASSFISH_HOME/domains/domain1/logs/server.log that successful messages appear.

Quick start demo PDF signer

To install the PDF signer you can issue the following commands (either instead of the TSA or in addition to the TSA).

  1. Make sure the pdfsigner module is built in by setting module.pdfsigner.enabled=true and module.pdfsigner.include=true in signserver_build.properties before building and deploying SignServer. Alternativly, set includemodulesinbuild=true to have all modules built in.
  2. Load the PDF signer demo configuration and notice the generated worker ID (in this example 2):
    $ bin/signserver.sh setproperties doc/sample-configs/qs_pdfsigner_configuration.properties
  3. Activate the configuration with:
    $ bin/signserver.sh reload 2
  4. You can check the status and configuration with:
    $ bin/signserver.sh getstatus complete all

You can now, with your web browser, access the URL http://localhost:8080/signserver/demo/pdfsign.jsp to get PDF documents signed.

Quick start demo OOXML signer

To install the OOXML signer you can issue the following commands.

  1. Make sure the ooxmlsigner module is built in by setting module.ooxmlsigner.enabled=true and module.ooxmlsigner.include=true in signserver_build.properties before building and deploying SignServer. Alternativly, set includemodulesinbuild=true to have all modules built in.
  2. Load the OOXML signer demo configuration and notice the generated worker ID (in this example 3):
    $ bin/signserver.sh setproperties doc/sample-configs/qs_ooxmlsigner_configuration.properties
  3. Activate the configuration with:
    $ bin/signserver.sh reload 3
  4. You can check the status and configuration with:
    $ bin/signserver.sh getstatus complete all

You can now, with your web browser, access the URL http://localhost:8080/signserver/demo/ooxmlsign.jsp to get any Office Open XML documents signed (ex: MS Office 2007 Word document, Excel document, Power Point presentation...).

Quick start demo ODF signer

To install the ODF signer you can issue the following commands.

  1. Make sure the odfsigner module is built in by setting module.odfsigner.enabled=true and module.odfsigner.include=true in signserver_build.properties before building and deploying SignServer. Alternativly, set includemodulesinbuild=true to have all modules built in.
  2. Load the ODF signer demo configuration and notice the generated worker ID (in this example 4):
    $ bin/signserver.sh setproperties doc/sample-configs/qs_odfsigner_configuration.properties
  3. Activate the configuration with:
    $ bin/signserver.sh reload 4
  4. You can check the status and configuration with:
    $ bin/signserver.sh getstatus complete all

You can now, with your web browser, access the URL http://localhost:8080/signserver/demo/odfsigner.jsp to get any Open Document Format documents signed (ex: documents produced by OpenOffice.org or LibreOffice).

Quick start demo XML signer

To install the demo XML signer you can issue the following commands.

  1. Make sure the xmlsigner module is built in by setting module.xmlsigner.enabled=true and module.xmlsigner.include=true in signserver_build.properties before building and deploying SignServer. Alternativly, set includemodulesinbuild=true to have all modules built in.
  2. Load the XML signer demo configuration and notice the generated worker ID (in this example 5):
    $ bin/signserver.sh setproperties doc/sample-configs/qs_xmlsigner_configuration.properties
  3. Activate the configuration with:
    # bin/signserver.sh reload 5
  4. You can check the status and configuration with:
    $ bin/signserver.sh getstatus complete all

You can now, with your web browser, access the URL http://localhost:8080/signserver/demo/xmlsign.jsp to get XML documents signed.

Quick start demo XML validator

An XML validator validates the signature of an XML document. It uses a certificate validation service worker for validating the certificate so that worker has to be configured first.

To install a certificate validation service worker issue the following commands:

  1. Load the configuration and notice the worker ID (in this example: 6):
    $ bin/signserver.sh setproperties doc/sample-configs/qs_validator_dummy_configuration.properties
  2. Activate the configuration with:
    $ bin/signserver.sh reload 6
  3. The status of the Worker can now be viewed with:
    $ bin/signserver.sh getstatus complete CertValidationWorker

Then to install the XML validator you can issue the following commands:

  1. Make sure the xmlvalidator module is built in by setting module.xmlvalidator.enabled=true and module.xmlvalidator.include=true in signserver_build.properties before building and deploying SignServer. Alternativly, set includemodulesinbuild=true to have all modules built in.
  2. Load the XML validator demo configuration and notice the generated worker ID (in this example 7):
    $ bin/signserver.sh setproperties doc/sample-configs/qs_xmlvalidator_configuration.properties
  3. Verify the configuration with (notice that VALIDATIONSERVICEWORKER is set to "CertValidationWorker"):
    $ bin/signserver.sh getconfig 7
  4. Activate the configuration with:
    $ bin/signserver.sh reload 7
  5. The status of the Validator can now be viewed with:
    $ bin/signserver.sh getstatus complete DemoXMLValidator

Now the SignServer APIs can be used to request XML documents to be validated by the DemoXMLValidator worker.

Quick start demo MRTD SOD signer

The MRTD SOD signer takes as input data group hashes and creates a signed SO(d). This means that the signserver will function as a Document Signer for ePassports.

To install the MRTD SOD signer you can issue the following commands:

  1. Make sure the mrtdsodsigner module is built in by setting module.mrtdsodsigner.enabled=true and module.mrtdsodsigner.include=true in signserver_build.properties before building and deploying SignServer. Alternativly, set includemodulesinbuild=true to have all modules built in.
  2. Load the MRTD SOD signer demo configuration and notice the generated worker ID (in this example 8):
    $ bin/signserver.sh setproperties doc/sample-configs/qs_mrtdsodsigner_configuration.properties
  3. Activate the configuration with:
    $ bin/signserver.sh reload 8
  4. The status of the signer can now be viewed with:
    $ bin/signserver.sh getstatus complete mrtdsodsigner

Now the SignServer APIs can be used to send MRTD SOD sign requests the MRTDSODSigner.
Also you can use the HTML page http://localhost:8080/signserver/demo/mrtdsodsign.jsp to enter requests and get the SOd back. This HTML form also functions as a sample to show how you can make HTTP requests from the personalisation system to the Document Signer.

*** Production configuration with HSM ***

To install a production signer using an HSM instead of the demo signer you can edit doc/sample-config/qs_mrtdsodsigner_configuration.properties and change from SoftCryptoToken to PKCS11CryptoToken and comment all properties under SoftCryptoToken properties and instead fill in all properties under PKCS11CryptoToken properties and then run:
(note after changing properties in the file it needs to be loaded again with setproperties)

Before starting with an HSM installation you should read the about the PKCS11CryptoToken in the plugins section of the manual.

bin/signserver.sh setproperties doc/sample-config/qs_mrtdsodsigner_configuration.properties
bin/signserver.sh getconfig 9
bin/signserver.sh reload 9
bin/signserver.sh generatecertreq 9 "C=SE,CN=MRTD SOD Signer" SHA256WithRSA mrtdsodsigner.req

Where 9 is the signerId that you got when running the 'setproperties' command.
This will create a certificate request that you can get signed by your CA. When you have received the response you can import it and the CA certficate. If you have the returned signer certificate as cert.pem and the CA certificate as cacert.pem, then:

cat cert.pem cacert.pem > certchain.pem
bin/signserver.sh uploadsignercertificate 9 glob cert.pem
bin/signserver.sh uploadsignercertificatechain 9 glob certchain.pem
bin/signserver.sh reload 9

Hint: you can use EJBCA to create keys on a PKCS#11 HSM using clientToolBox.
ejbcaClientToolBox.sh PKCS11HSMKeyTool generate /opt/ETcpsdk/lib/linux-x86_64/libcryptoki.so 2048 DSSignKey 5

Historic Installation Guides

Clustered SignServer 3.0 CentOS 4.4 Installation Guide

Installation guide describing step-by-step how to setup a SignServer cluster on CentOS 4.4. Even if the document is specific for this OS is should be quite easy to adopt it to other environments as well. It can be downloaded here either as PDF or viewed as HTML

Clustered SignServer 2.0 CentOS 4.4 Installation Guide

Version 2.0 of the same documentation.PDF HTML

Usage Guide

Introduction

Configuration/Administration

The SignServer administration command line interface (Admin CLI) is started using bin/signserver.sh (or bin/signserver.cmd).

Every worker is identified by an ID and an optional name that can be used in all the CLI commands.

It is possible to do configuration of a worker while it's in production. All configuration commands are cached until a reload command is issued and the configuration becomes active.

There is a special property file for the cli interface called signserver_cli.properties defining which nodes that exists in the cluster. The properties are:

hostname.masternode = Should only contain one of the nodes, specified as the default master node. Used by operations dealing with the database and where not all nodes in the cluster needs to be contacted. It is possible to override this setting in the CLI by using the -host <host name> parameter.

hostname.allnodes = Should contain all the nodes in the cluster, separated by a ';'. Mainly used by the commands getStatus, activateCryptoToken and deactivateCryptoToken.

Its possible to customize the CLI with your own code. How to do this is described in the development section.

Administration CLI

*** General Commands ***

getstatus: Returns the status of the given worker, it says if its crypto token is active or not and the loaded 'active' configuration. It is possible to get a brief summary or a complete listing for one worker or all configured workers. If all workers are displayed will also all the global configuration parameters be displayed.

getconfig: Returns the current worker or global configuration depending on options.

For worker configuration observe that this configuration might not have been activated yet, not until a reload command is issued.

setproperty: Sets a custom property used by the worker or crypto token, see reference for the given Worker and CryptoToken for available properties.

setproperties: Command used to batch a set of properties, both for the global and worker configuration. It can be used to configure a Signer in a test environment, dump all the properties and upload it into production.

It reads all the configuration properties form a property file and depending on the contents of the key it sets the given property. All properties will be set according to the following defined rule set.

Rule Comment
Properties starting with id<num>. Will set the property to the value of the given id to the worker with the given id.
Properties starting with name<name>. Will set the property to a worker with the given name. (If the name doesn't exists a unique id will be generated and assigned).
Property keys containing GENID<NUM>, example WORKERGENID1 or GLOB. WORKERGENID1 The SignServer will find a free unique id and assign substitute all GENID<num> with this id.
Properties starting with glob. Will set a global property with global scope.
Properties starting with node. Will set a global property with node scope.
Properties starting with -<other prefix><value> Will remove the property, either worker or global.

See the directory 'sample-configs' for examples.

removeproperty: Removes a configured property

dumpproperties: This tool will dump all configured properties for one or all workers in the system into a property file. If the configuration for one worker is dumped it can be used to transfer the configuration from one installation to another. If all configurations is dumped, it can be used as a backup tool.

uploadsignercertificate: Used to upload the certificate when the worker only needs the actual signing certificate and not the entire chain.

uploadsignercertificatechain: Used when uploading a complete certificate chain to the worker. Which command that is supposed to be used is depending on the worker and crypto token used.

generatecertreq: Used to generate a certificate request for a worker to be signed by a certificate authority. It takes distinguished name and signature algorithm as parameters and writes the request in PEM format to file.

activatecryptotoken: Used to activate crypto tokens. Authentication code is usually the PIN used to unlock the keys on the HSM. Not used if the token is set to auto-activation.

deactivatecryptotoken: Brings a crypto token off-line. Not used if token is set to auto-activation.

*** SignServer Specific Commands ***

Authorization Related

These commands are used to configure the internal client certificate authorization when it is turned on. It controls which clients that is authorized to request a processable worker.

addauthorizedclient: Adds a client certificate to a processable workers list of acceptable clients using this worker. Specify certificate serial number in hex and the Issuer DN of the client certificate.

removeauthorizedclient: Removes added client certificate entries.

listauthorizedclients: Displays the current list of acceptable clients.

Database Related

resync:

The 'resync' command is used after a SignServer had a complete database failure. When this happens will the Global Configuration become in 'Off-line' mode and it's not possible for the nodes to communicate internally and the Global Configurations will not be in sync any more. After the database is up again can this command be sent to the node that have the most valid Global Configuration and write it to the database. After this will the Global Configuration be in 'On-line' mode again.

Archive Related

This commands can be used for processable workers that have archiving turned on. They are used to find specific archived responses. It's up to the implementation of the worker if it supports archiving or not and it is up to the choosen Archiver if it archives the data in way that it can be queried using this commands. For Archivers other than the default "OldDatabaseArchiver" quering might have to be done directly in the database or by some custom application.

archive findfromarchiveid: Command used to extract archived data from database identified by the archive Id.

The Id depends on the worker, in case of the TSA is the TimeStampInfo serial number used. The data is stored with the same file name as the archive id in the specified path.

archive findfromrequestip: Used to extract all archived data requested from a specified IP address.

All data is stored as separate files with the archive id as file name in the specified path.

archive findfromrequestcert: Used to extract all archived data requested from a client by specified it's certificates serial number and issuer DN.

All data is stored as separate files with the archive id as file name in the specified path.

Group Key Service Related

These commands only applies for group key services.

groupkeyservice pregeneratekeys: Command used to pregenerate a given number of group keys for a given group key service and stores them unassigned encrypted in the database. This commands can be used to let the cluster work on CPU insensitive key generation during low business hours.

groupkeyservice removegroupkeys: Command used to remove group keys not used any more. A time range of when created, first used and last fetched can be used as criteria.

groupkeyservice switchenckey: Command used manually switch the encryption key used to secure the group keys in database. Usually is the encryption key switched automatically but this command can be used to override this default behaviour.

Module Archive Related

There exists three commands for managing module archives in a cluster, they are quite straightforward. Use the command 'signserver.sh/cmd module' command for more details.

module add: The 'add' command uploads a '.mar' file to the cluster. It is possible to define in which environment the module should be used, for instance 'production' or 'test' but this is all depending on which environments the module supports.

If signature verification is required by the server it is also possible to specify a path to a JKS key store along with an alias and password to the key used.

module remove: Command used to remove a specified version of a module.

module list: Command to list all uploaded modules, it is also possible to see all JAR files that is included in the modules.

Administrators Related

wsadmins -list:

Lists administrator certificates (certificate serial number and issuer DN) for administrators authorized to use the Admin Web Service interface to administrate SignServer.

wsadmins -add:

Authorizes an administrator to use the Admin Web Service interface by certificate serialnumber and issuer DN.

wsadmins -remove:

Removes an administrator from the list of authorized administrators.

Administration GUI

As a complement to the command line interface there is also a graphical user interface for managing some of the most basic administrative tasks.

The SignServer AdminGUI can be build by running "ant admingui" and then started using the script bin/admingui.sh. By default it tries to connect to a locally running SignServer instance using EJB calls. If that fails or if the command line option "-ws" is specified a connection dialog for connecting using web services is displayed instead.

*** Connect to SignServer dialog ***

Specify URL to SignServer server as well as keystore and truststore for setting up the HTTPS connection and then click the button Connect. By clicking the button Load defaults the settings from the file default_connect.properties is loaded. If the connection is successful the current settings are stored to connect.properties and displayed the next time the dialog is openned.

Web Service URL: Base URL to the SignServer server. Default: https://localhost:8443/signserver

Truststore Type: Type of the truststore. Should match the choosen truststore file (if any). Options are: "Use keystore", JKS, PKCS12 or PEM. If "Use keystore" is choosen the trusted certificates are instead taken from the keystore and no truststore is used.

Truststore file path: Path to the truststore file (if any).

Truststore password: Password of the truststore file (if any).

Keystore Type: Type of the keystore. Should match the choosen keystore file path. Options are: JKS, PKCS12 or PKCS11. If PKCS11 is choosen the keystore file path should be the patch to the PKCS#11 shared library file.

*** Main window ***

The SignServer Administration GUI main window consists of a menu bar, a toolbar, the working area and at the bottom a status bar. The working area constists of a left and right part where the left is a list of all configured workers and the right shows details for the selected workers (if any).

*** Main window: Menu bar ***

File -> Exit: Exits the SignServer Administration GUI

Edit -> Activate: Activates the selected worker(s).

Edit -> deactivate: Deactivates the selected worker(s).

Edit -> Renew key...: Opens the Renew key dialog for the selected worker(s).

Edit -> Test key...: Opens the Test key dialog for the selected worker(s).

Edit -> Generate CSR...: Opens the Generate CSR dialog for the selected worker(s).

Edit -> Install certificates...: Opens the Install certificates dialog for the selected worker(s).

Edit -> Renew signer...: Opens the Renew signer dialog for the selected worker(s).

Edit -> Global configuration...: Opens the Global configuration window.

Edit -> Administrators...: Opens the Administrators window.

View -> Refresh: Refreshes the information about all workers.

View -> Status Summary...: Switches to the Status Summary tab for the selected worker.

View -> Status Properties...: Switches to the Status Properties tab for the selected worker.

View -> Configuration...: Switches to the Configuration tab for the selected worker.

View -> Authorization...: Switches to the Authorization tab for the selected worker.

Help -> About...: Opens the about box doc.

*** Main window: Tool bar ***

Refresh: Refreshes the information about all workers.

Activate: Activates the selected worker(s).

Deactivate: Deactivates the selected worker(s).

Renew key...: Opens the Renew key dialog for the selected worker(s).

Test key...: Opens the Test key dialog for the selected worker(s).

Generate CSR...: Opens the Generate CSR dialog for the selected worker(s).

Install certificates...: Opens the Install certificates dialog for the selected worker(s).

Renew signer...: Opens the Renew signer dialog for the selected worker(s).

*** Main window: Status Summary Tab ***

Displays the status summary for the selected worker in the same format as the CLI command "signserver getstatus complete".

*** Main window: Status Properties Tab ***

Displays the status in properties format with the option of viewing details for some properties such as for the certificates.

Details...: Selecting an property and clicking this button opens a dialog box with more information for the property (if supported). Currently for certificates this openns the Certificate details dialog.

*** Main window: Configuration Tab ***

Lists all the selected worker's configuration properties and gives the ability to add, remove or edit properties.

Add...: Adds a new property to the selected worker.

Edit: Edit the selected property.

Remove: Removes the selected property.

*** Main window: Authorization Tab ***

Lists all the authorized client certificates for the selected worker. Notice that this only applies if the worker has the AUTHTYPE set to CLIENTCERT otherwise information about authorized clients might be taken from other sources.

Add...: Adds a new authorized client. If the option "Apply changes to all selected workers" is checked the client is added to all the currently selected workers.

Edit...: Edits the selected authorized client. If the option "Apply changes to all selected workers" is checked the client is modified in all the currently selected workers.

Remove: Removes the selected client. If the option "Apply changes to all selected workers" is checked the client is modified in all the currently selected workers.

*** Renew key dialog ***

Generates new keys for all the listed workers. For this to work all workers should have the same password. Key algorithm, Key specification and New key alias must be specified if it is not taken from the worker's configuration.

*** Test key dialog ***

Test keys for all the listed workers. It is optional to either test the current key or the next key (if any) or all the keys in the keystore. For this to work all workers should have the same password. The results shows for each key the key alias, SUCCESS and the public key hash if the test signing succeded.

*** Generate CSR dialog ***

Generates certificate signing requests (CSR:s) in PKCS#10 format for all listed signers and either for the current key (Default key) or the next key. Signature algorithm, subject distingueshed name (DN) and Filename must be specified if not already taken from the worker's configuration. The format of the request could either be a Standard CSR file or a CSR wrapped in PKCS#7/CMS signed object created by a RequestSigner. The with the last option is that at the CA the signature of the request can be verified.

*** Install certificates ***

Installs signer certificate and certificate chains for the listed workers and if next key is choosen that key becomes the new default key.

Signer certificate: Browse for the signer certificate file in PEM format.

Certificate chain: Browse for the signer certificate chain file in PEM format. The signer certificate is added to the chain if it is not already included so normally this could just be the CA certificate.

*** Renew signer dialog ***

Requests a Renewal worker to renew all the choosen and selected workers. The Renewal worker will generate a new key if there isn't already a next key available and then contact EJBCA using its web service interface to request a new certificate. After recieving the new certificate it is installed and the next key becomes the current default key. Notice how the "Not valid after" date and possibly also the Signings column changes and the Renewal checkbox gets unchecked after a successfull renewal.

*** Global configuration dialog ***

Lists all the global configuration properties and gives the ability to add, remove or edit properties.

*** Administrators dialog ***

Lists all the authorized WS administrators and gives the ability to add, remove or edit authorized administrators.

Working with Workers

In SignServer operations are performed by workers. There can be many workers and each worker has its own configuration. Each worker is identified by an unique ID. A worker can also be configured with a name by setting the property NAME. After the configuration has been activated (by issuing reload with the worker ID) that name can also be used to address the worker.

Workers are configured slitly differently depending on if the cluster class loader is used and the plugin is a separate module or if the plugin is built-in to SignServer.

*** Configuring using a module ***

To configure the worker using a module the cluster class loader must be activated (see Changing the default configuration of the Cluster Class Loader) and the code for the plugin available as .MAR-file. To setup a worker using a module archive issue the following command:

bin/signserver.sh module add dist-server/MODULE.MAR ENVIRONMENT
                        

Replace "MODULE.MAR" with the name of the module file and "ENVIRONMENT" with the name of the built-in configuration to load. For example to load the TSA module using the demo configuration issue the following command:

bin/signserver.sh module add dist-server/tsa.mar demo
                        

Notice the created workerId and use it when applying the configuration using the reload command:

bin/signserver.sh reload WORKER-ID
                        
*** Configuring using a built-in plugin ***

Configuring using a build-in plugin only works if you have set the option includemodulesinbuild=true in signserver_build.properties.

A worker is configured by setting properties for it. Specifically if the plugin is built-in it is specified by setting the property CLASSPATH to the fully qualified name of the class implementing the plugin.

The properties can be set manually using the setproperty command or by loading them all at once from a configuration file using the setproperties command. Sample configuration files are available in SIGNSERVER_HOME/sample-configs.

To setup a PDFSigner using the quick start configuration file issue the following command:

bin/signserver.sh setproperties sample-configs/qs_pdfsigner_configuration.properties
                        

Notice the created workerId and use it when applying the configuration using the reload command:

bin/signserver.sh reload WORKER-ID
                        
*** Remove Workers ***

You can list which workers you have with the command:

bin/signserver.sh getstatus brief all                    
                    

If will display for example:

===========================================
Executing Command on host : localhost
===========================================


Current version of server is : SignServer 3.2-svn


Status of Signer with Id 1 is :
  SignToken Status : Offline
  Signings: 0
                    

You can remove the worker with Id 1 with the command:

bin/signserver.sh removeworker 1
bin/signserver.sh reload all                    
                    

Working with Modules

*** Remove modules ***

If you have made changes to the module, and you are using the cluser classloader (i.e. not built in modules) you have to remove the module before deploying a new one.

bin/signserver.sh modules list

===========================================
  Executing Command on host : localhost
===========================================


Using cluster class loader.

Listing all available modules :
  Module : MRTDSODSIGNER, version 3200
    Parts : 
      server

bin/signserver.sh module remove MRTDSODSIGNER 3200

===========================================
  Executing Command on host : localhost
===========================================


Using cluster class loader.

  Removing module MRTDSODSIGNER version 3200 ...
  Removal of module successful.
                    
*** Add updated modules ***
Note
If you added configurations under src/module-configs you must rebuild the modules with the command 'ant', before you can use 'module add' with your updated configs.

After rebuilding the modules you can add updated modules.

bin/signserver.sh module add dist-server/pdfsigner.mar soft					
bin/signserver.sh reload all
bin/signserver.sh getstatus complete all
					

Making the SignServer highly-available

Here are some tips on configuration used to make the SignServer redundant. Usually is the SignServer set-up with three nodes (required minimum for MySQL cluster) where one node is a management node from were all deployment and administration is done and the other two services are service nodes processing the actual requests.

HTTP access requires a load balancer

HTTP based workers like the TSA can be clustered using a load balancer accessing a health check servlet returning the state of the SignServer. The basic settings of the health check servlet can be configured in the build configuration file but more advanced settings are done in 'src/web/healthcheck/WEB-INF/web.xml'. With the default settings will the servlet return the text 'ALLOK' when accessing the URL http://localhost:8080/signserver/healthcheck/signserverhealth. If something is wrong with the sign server will an error message be sent back instead.

The health check servlet can also be used to monitor the SignServer by creating a script that monitors the URL periodically for error messages.

Tip, heartbeat with ldirectord is a good solution for a load balancer and works well with the SignServer. KeepAlived is another open source solution.

The Main WebService using the Java client API manages the HA parts itself and then isn't a load balancer necessary.

Setting up a MySQL Cluster

The database backed of the SignServer can be made redundant using MySQL Cluster. Details on how to set-up the MySQL cluster can be found in the document SignServer_3_0_Installation_Guide.pdf that can be downloaded from www.signserver.org. More information about the MySQL Cluster can be found at http://www.mysql.com/products/database/cluster/.

Integration

JavaDoc

The JavaDoc for SignServer is available at SIGNSERVER_HOME/doc/api/index.html after running "ant javadoc".

Web Services

New to version 3.0 is the Main WebService interface. It replaces the RMI-SSL interface in version 1.0 and 2.0 for two reasons, the RMI-SSL were based on a commercial library and it only worked for Java clients.

The WebService interface have two calls, the main one is 'process' which takes a collection of process request to a processable worker and returns a collection of process responses, the second one is getStatus that performs a health check of the node and returns an OK message if the node is healthy.

The WebService stack used is the JAX-WS stack from SUN. And the actual process data is a externalized Base64 byte-arrays. The reason why the are externalized is to simply the integration towards non-Java platforms. See the source of the actual request to see how the data is structured.

The getStatus call can be used to implement high-availability towards the client. The Java client API described in the next section have built in support for different high availability policies.

The WebService WSDL file is located at the URL http://<hostname>:8080/signserver/signserverws/signserverws?wsdl

It's possible to turn off the WebService interface by disabling it in the build configuration.

Important, Due to class path conflict in JBoss 4.2.x own JBoss WebService stack and the JAX-WS stack used by the SignServer must the JBoss WebService stack be removed before the WebService is used. This is done by going to JBOSS_HOME/server/default/deploy and remove the directory jbossws.sar.

Since SignServer >=3.2.1 it is possible to supply extra request data called RequestMetadata containing key/value pairs that can be used by the signers. For instance the PDFSigner uses this feature to let the client supply a PDF password.

Java Client API

Built along with the WebService is a Java API that can be used by clients. It's located in dist-client/signserverwscli and the file signserverws.jar and all the files in the lib directory is required to use the API. The client API have support for different high availability policies to avoid the need for load balance hardware.

The client classes is in the package org.signserver.protocol.ws.client and the main code are SignServerWSClientFactory creating a client using the specified load balance policy, it returns a ISignServerWSClient that is used to perform the actual process requests.

Load Balance Policies

With version 3.0 is one load balance policy defined and it's called 'CallFirstNodeWithStatusOK' it calls the getStatus method on all the server nodes in the cluster simultaneously and the first node to respond OK it sends its process request to. This to ensure that only one node in the cluster actually performs the signing.

Other future load balance policies could be round robin or that all nodes are called with the requests simultaneously and the first response is used.

SigningAndValidation API

The SigningAndValidation API is a wrapper around the previous mentioned API in order to have a simplified interface that also is the same regardless if WebService or EJB Remote calls are used.

To use the API include the file signingandvalidationapi.jar as well as all JAR-files in the lib-folder available in SIGNSERVER_HOME/dist-client/signingandvalidationapi/.

Sample Code

*** Signing and validating an XML document ***
try {
    ISigningAndValidation signserver = new SigningAndValidationWS("localhost", 8080);

    // Document to sign
    byte[] unsigned = "<document><name>Some content</name></document>".getBytes();
    byte[] signed;

    // Signing
    GenericSignResponse signResp = signserver.sign("DemoXMLSigner", unsigned);
    signed = signResp.getProcessedData();
    System.out.println("Signed: " + new String(signed));

    // Validating
    GenericValidationResponse validateResp = signserver.validate("DemoXMLValidator", signed);
    System.out.println("Valid: " + validateResp.isValid());

    if(validateResp.getSignerCertificate() != null) {
        if(validateResp.getSignerCertificate() instanceof X509Certificate) {
            X509Certificate signerCert = (X509Certificate) validateResp.getSignerCertificate();
            System.out.println("Signed by: " + signerCert.getSubjectDN().getName());
        }
    }
} catch (Exception ex) {
    ex.printStackTrace();
}                                   
*** MRTD Signing ***
try {
    ISigningAndValidation signserver = new SigningAndValidationWS("localhost", 8080);

    // Bytes to sign
    ArrayList<byte[]> bytesToSign = new ArrayList<byte[]>();
    bytesToSign.add("Sample data 1".getBytes());
    bytesToSign.add("Sample data 2".getBytes());

    // Signing
    MRTDSignResponse signResp = (MRTDSignResponse) signserver.process("MRTDSigner", new MRTDSignRequest(1234, bytesToSign), new RequestContext());

    System.out.println("Certificate: " + signResp.getSignerCertificate());

    if(signResp.getProcessedData() instanceof Collection) {
        Collection<byte[]> signed = (Collection) signResp.getProcessedData();
        for(byte[] data : signed) {
            System.out.println("Signed: " + new String(Base64.encode(data)));
        }
    }
} catch (Exception ex) {
    ex.printStackTrace();
}                               

Web Server Interface

GenericProcessServlet

HTTP requests can be sent to the SignServer servlet GenericProcessServlet located at /signserver/process using either POST or GET.

URL: /signserver/process
Method: GET or POST
Request content-type: None, "x-www-form-urlencoded", "multipart/form-data" or other*
Request parameters:
  • workerName - Name of the worker that should handle the request. Required unless workerId specified.
  • workerId - Id of the worker that should handle the request. Required unless workerName specified.
  • data - The bytes that should be signed or validated. Required for x-www-form-urlencoded.
  • filerecievefile - File upload used with multipart/form-data.
  • pdfPassword - Password for changing PDF. Optionally and only used by PDFSigner.
  • encoding - Encoding of the data field. Optional. By specifying "base64" SignServer Base64-decodes the data property before passing it to the worker.
Response code:
  • HTTP 200 (OK): The request was successfull
  • HTTP 400 (Bad Request): The request could not be fulfilled. Some request data were missing or incorrect etc.
  • HTTP 401 (Unauthorized): The worker requires user authentication
  • HTTP 404 (Not Found): The requested workerName or workerId does not represent an existing worker
  • HTTP 413 (Request Entity Too Large): The data field or uploaded file is too large
  • HTTP 500 (Internal Server Error): There was an internal error when processing the request. Typically indicating an configuration problem or unexpected error at the server side.
  • HTTP 503 (Service Unavailable): The worker is not active, its crypto token is not activated or similar
Response content-type: Depending on the worker

* if the request content-type in a POST is specified as something else than "x-www-form-urlencoded" or "multipart/form-data" the message body is not parsed but instead directly passed to the worker specified by workerName or workerId in the URI's query string.

*** Samples ***
  • HTTP GET:
    http://localhost:8080/signserver/process?workerName=DemoXMLSigner&data=%3Croot%3Ehej2%3C/root%3E
    http://localhost:8080/signserver/process?workerName=DemoXMLSigner&encoding=base64&data=PGhlajI%2Bb2s8L2hlajI%2BCg%3D%3D

  • HTTP POST with multipart/form-data or x-www-form-urlencoded:
    For example see /signserver/demo/xmlsign.jsp (multipart/form-data) and /signserver/demo/genericsign.jsp (x-www-form-urlencoded).

  • HTTP POST with other content-type:
    See the TimeStampClient.

SODProcessServlet

Servlet recieving HTTP POST requests containing data group hashes and creates a MRTDSODSignerRequest and passes it to the specified MRTDSODSigner. The response from the servlet is the signed security object in binary format.

URL: /signserver/sod
Method: POST
Request parameters:
  • workerName - Name of the worker that should handle the request. Required unless workerId specified.
  • workerId - Id of the worker that should handle the request. Required unless workerName specified.
  • dataGroup1 to dataGroup16 - The data group hashes that should be put in the SO(d). At least one required.
  • encoding - Encoding of the data group hash fields. Optional. By specifying "base64" SignServer Base64-decodes the data property before passing it to the MRTDSODSigner.
  • ldsVersion - Request a specific LDS version: "0107" for V1.7 or "0108" for V1.8. Optional. If not specified the version from the configuration is used. If version is V1.8 unicodeVersion also needs to be specified.
  • unicodeVersion - Unicode version to store in the SOd. Optional. Only supported if ldsVersion "0108" specified. Specify "040000" for Unicode version 4.0.0.
Response code: The same response codes as for the GenericProcessServlet are used.
Response content-type: application/octet-stream
*** Samples ***
  • See /signserver/demo/mrtdsodsign.jsp.

Client Command Line Interface (CLI)

Requests can be sent to the workers using the Client CLI. After building SignServer the script bin/client.sh can be run.

$ bin/client.sh
INFO  usage: client <signdocument | validatedocument | timestamp | validatecertificate | signdatagroups>
                    

signdocument

Request signing of a document using HTTP(s) or web services.

usage: signdocument <-workername WORKERNAME | -workerid WORKERID>
                    [options]
Request a document to be signed by SignServer
 -data             Data to send to the worker.
 -host             Server name or IP address. Default: localhost
 -infile           File to read data to send to the worker from.
 -keyalias         Alias of the key in the keystore to use for
                   authentication.
 -keystore         Keystore with private key and certificate for client
                   certificate authentication.
 -keystorepwd      Password for reading the keystore.
 -outfile          File to write the result to. If not specified the
                   result is written to stdout.
 -password         Password for authentication.
 -pdfpassword      Password for changing the PDF (if required).
 -port             Server port. Default: 8080 (for HTTP), 8442 for HTTPS
                   and 8443 for HTTPS with client authentication.
 -protocol         Method of interacting with SignServer. HTTP or
                   WEBSERVICES. Default: HTTP.
 -servlet          Servlet to call. Default /signserver/process
 -truststore       Keystore with trusted certificates to use with HTTPS.
 -truststorepwd    Password for the keystore with trusted certificates.
 -username         Username for authentication.
 -workerid         ID of worker which should perform the operation.
 -workername       Name of worker which should perform the operation.

Sample usages:
a) signdocument -workername XMLSigner -data "<root/>"
b) signdocument -workername XMLSigner -infile /tmp/document.xml
c) signdocument -workerid 2 -data "<root/>" -truststore truststore.jks
-truststorepwd changeit
d) signdocument -workerid 2 -data "<root/>" -keystore superadmin.jks
-truststorepwd foo123
                        

validatedocument

Request a document to be validated.

usage: validatedocument <-workername WORKERNAME | -workerid WORKERID>
                        [options]
Request a document to be validated by SignServer
 -data             Data to send to the worker.
 -host             Server name or IP address. Default: localhost
 -infile           File to read data to send to the worker from.
 -keyalias         Alias of the key in the keystore to use for
                   authentication.
 -keystore         Keystore with private key and certificate for client
                   certificate authentication.
 -keystorepwd      Password for reading the keystore.
 -password         Password for authentication.
 -port             Server port. Default: 8080 (for HTTP), 8442 for HTTPS
                   and 8443 for HTTPS with client authentication.
 -truststore       Keystore with trusted certificates to use with HTTPS.
 -truststorepwd    Password for the keystore with trusted certificates.
 -username         Username for authentication.
 -workerid         ID of worker which should perform the operation.
 -workername       Name of worker which should perform the operation.

Sample usages:
a) validatedocument -workername XMLValidator -data "<root><Signature...
b) validatedocument -workername XMLValidator -infile /tmp/signed.xml
c) validatedocument -workerid 2 -infile /tmp/signed.xml -truststore
truststore.jks -truststorepwd changeit
d) validatedocument -workerid 2 -infile /tmp/signed.xml -keystore
superadmin.jks -truststorepwd foo123
                        

timestamp

$ bin/client.sh timestamp
usage: java -jar timeStampClient.jar <options> <url>
 -instr <string>      String to be time stamped, if neither instr or
                      infile is given, the client works in test-mode generating it's own
                      message.
 -base64              Give this option if the stored request/reply should
                      be base64 encoded, default is not.
 -help                Print this message.
 -infile <file>       File containing message to time stamp.
 -inrep <file>        Input file containing an earlier stored base64
                      encoded response, to verify.You must specify the verify flag also.
 -inreq <file>        Input file containing an earlier stored request to
                      use instead of creating a new. You must specify the request flag also.
 -outrep <file>       Output file to store the recevied TSA reply, if not
                      given the reply is not stored.
 -outreq <file>       Output file to store the sent TSA request, if not
                      given the request is not stored.
 -signerfile <file>   Input file containing the PEM encoded certificate of
                      the TSA signer.Used to verify a stored response.
 -sleep <num>         Sleep a number of milliseconds after each request.
                      Default 1000 ms.
 -url <url>           Url of TSA, e.g.
                      http://127.0.0.1:8080/signserver/process?workerId=1.
 -verify              Give this option if verification of a stored reply
                      should be done, work together with inrep and cafile. If given, no request
                      to the TSA will happen.

Sample usages:
a) timestamp -url http://localhost:8080/signserver/tsa?workerName=TimeStampSigner

                        

validatecertificate

Request a certificate to be validated by the specified service.

usage: Usage: java -jar validate.jar <options>

 -cert <cert-file>              Path to certificate file (DER or PEM)
                                (Required).
 -certpurposes <certpurposes>   A ',' separated string containing
                                requested certificate purposes.
 -der                           Certificate is in DER format.
 -help                          Display this info
 -hosts <hosts>                 A ',' separated string containing the
                                hostnames of the validation service nodes. Ex
                                'host1.someorg.org,host2.someorg.org' (Required).
 -pem                           Certificate is in PEM format (Default).
 -port <port>                   Remote port of service (Default is 8080 or
                                8442 for SSL).
 -service <service-name>        The name or id of the validation service
                                to process request. (Required)
 -silent                        Don't produce any output, only return
                                value.
 -truststore <jks-file>         Path to JKS truststore containing trusted
                                CA for SSL Server certificates.
 -truststorepwd <password>      Password to unlock the truststore.

The following values is returned by the program that can be used when scripting.
  -2   : Error happened during execution
  -1   : Bad arguments
   0   : Certificate is valid
   1   : Certificate is revoked
   2   : Certificate is not yet valid
   3   : Certificate have expired
   4   : Certificate doesn't verify
   5   : CA Certificate have been revoked
   6   : CA Certificate is not yet valid
   7   : CA Certificate have expired.
   8   : Certificate have no valid certificate purpose.

Sample usages:
a) validatecertificate -service CertValidationWorker -hosts localhost -cert
    certificate.pem
b) validatecertificate -service 5806 -hosts localhost -cert certificate.pem
    -truststore p12/truststore.jks -truststorepwd changeit
                        

signdatagroups

Sign the specified data groups and produce an SOd (MRTD).

$ bin/client.sh signdatagroups
usage: signdatagroups <options>
 -data             Data to send to the worker.
 -encoding         Encoding of the data option. None or base64. Default:
                   none.
 -host             Server name or IP address. Default: localhost
 -keyalias         Alias of the key in the keystore to use for
                   authentication.
 -keystore         Keystore with private key and certificate for client
                   certificate authentication.
 -keystorepwd      Password for reading the keystore.
 -password         Password for authentication.
 -port             Server port. Default: 8080 (for HTTP), 8442 for HTTPS
                   and 8443 for HTTPS with client authentication.
 -repeat           Run the operation this number of times. Default: 1
 -servlet          Servlet to call. Default /signserver/sod
 -truststore       Keystore with trusted certificates to use with HTTPS.
 -truststorepwd    Password for the keystore with trusted certificates.
 -username         Username for authentication.
 -workerid         ID of worker which should perform the operation.
 -workername       Name of worker which should perform the operation.

Sample usages:
a) signdatagroups -workername MRTDSODSigner -data "1=value1&2=value2&3=value3"
                        

Administration Web Service

The SignServer AdminWS can be used for remote administration of SignServer over client authenticated HTTPS. Access is granted based on a list of certificate serial number and issuer distinguished name pairs. Currently there is only one access level and all administrators granted access will be able to perform all operations.

The WSDL file is located at the URL http://<hostname>:8080/signserver/AdminWSService/AdminWS?wsdl

Authorizing administrators can be done using the Admin CLI command "wsadmins".

Usage: signserver wsadmins -add -certserialno <certificate serial number> -issuerdn <issuer DN>
Usage: signserver wsadmins -remove -certserialno <certificate serial number> -issuerdn <issuer DN>
Usage: signserver wsadmins -list
Example 1: signserver wsadmins -add -certserialno 123abcdef -issuerdn "C=SE, CN=Neo Morpheus"
Example 2: signserver wsadmins -remove -certserialno 123abcdef -issuerdn "C=SE, CN=Neo Morpheus"
Example 3: signserver wsadmins -list
                    

Notice that the certificate serial number should be entered with lower case characters. Also notice that the issuer DN currently should be entered in the reversed order and with spaces after each component. In the example above the issuer DN from the certificate actually is "CN=Neo Morpheus, C=SE".

To troubleshoot an "Administrator not authorized to resource" see the logs for how SignServer interprets the serialnumber and subject DN. Example:

19:00:33,946 INFO  [AdminWS] ADMIN OPERATION; subjectDN=C=SE, O=Markus Organization, OU=Internal Testing 1, CN=External RA Admin 1; serialNumber=4a3442e98e3ce428; issuerDN=C=SE, O=Markus Organization, OU=Internal Testing 1, CN=MarkusAdminCA1; authorized=false; operation=getWorkers; arguments=
                    

Common configuration

Configuring workers are done by setting properties in the worker configuration. There is one set of configuration options that are handled by the framework, and that applies to all workers, then there are worker specific properties handled by the worker implementation.

Properties are usually defined in the module configuration file used to install a module, or configured manually using one of the bin/signserver.sh setproperty variant.

Setting Authorization Type

SignServer

By default (if the property is not set) is client-certificate authentication required for a signature request to be processed. This can be changed with the AUTHTYPE property.

*** No authentication ***

AUTHTYPE = NOAUTH

Sets the server to not require any authentication.

*** Client certificate authentication ***

AUTHTYPE = CLIENTCERT

(default) requires a certificate of all the clients. The certificates must be in the application server's truststore. Authorized clients is configured manually using the CLI interface.

*** Username/password-based authentication ***

AUTHTYPE = org.signserver.server.UsernamePasswordAuthorizer

USER.[NAME] = [PASSWORD]
USER.[NAME] = [HASHED_PASSWORD]:[HASH_ALGORITHM]
USER.[NAME] = [HASHED_PASSWORD]:[HASH_ALGORITHM]:[SALT]

This authorizer requires a valid username and password. User accounts are configured by setting properties of the form shown above, where [NAME] is the username and [PASSWORD] is the clear-text password. In the second form [HASHED_PASSWORD] should be replaced with the output of the digest algorithm specified in [HASH_ALGORITHM]. The third form uses a hash value that is appended to the password before hashing it.

If a valid username and password is not supplied the worker throws an AuthorizationRequiredException which in case of the HTTP interfaces causes a HTTP Basic Authentication (RFC 2617).

*** Username-based authentication ***

AUTHTYPE = org.signserver.server.UsernameAuthorizer

Form 1: ACCEPT_ALL_USERNAMES = false (default) and usernames are specified:
ACCEPT_ALL_USERNAMES = false
ACCEPT_USERNAMES = user1;user2;user3

Form 2, ACCEPT_ALL_USERNAMES = true and no usernames are specified:
ACCEPT_ALL_USERNAMES = true

An Authorizer that can be used for instance if SignServer sits behind an Apache front-end which uses HTTP basic authentication. With this Authorizer the username is logged but the password is not checked as it is assumed to be checked by the front-end.

The Authorizer can be configured to either accept all usernames or only accept those usernames listed in one of its properties.

*** Remote address authentication ***

AUTHTYPE = org.signserver.server.RemoteAddressAuthorizer

ALLOW_FROM = Comma separated list of IP addresses to allow requests from. By default all other addresses are denied access.

If a worker is invoked directly using an EJB call and no REMOTE_IP is specified in the RequestContext the IP-address is set to the String "null". In that case, to allow requests using EJB calls, null can be added to the list of allowed addresses.

Note: When adding "null" to ALLOW_FROM not only locally running clients like the ClientCLI and AdminGUI is allowed access but also from workers that invoke the other worker directly using an EJB call. This is for instance the case for the XMLValidator which delegates the validation of the certificate to a CertValidator. If the CertValidator had a RemoteAddressAuthorizer allowing access from "null" then the XMLValidator would be able to use it. To restrict users from using the CertValidator (indirectly through the XMLValidator) an Autorizer could be configured for the XMLValidator.

*** Custom ***

This authorization functionality doesn't work for all use cases. Then it's possible to create a customized authorizer and specify it's class path as value in the AUTHTYPE property. The Processable will then automatically instantiate and use it. How to develop such a plug-in is explained in the developers section.

Archiving Responses

The archiving feature can be used to save all generated responses.

For the OldDatabaseArchiver the Admin CLI can be used to query the archive. See the CLI section for more information.

When a requst has been process each Archiver is called one at the time to archive any results.

ARCHIVERS: Used instead of the old ARCHIVE property to enable archinving by listing the class names of all the Archivers that should be used. Multiple Archivers can be specified separated by a "," (comma character). Exempel:

ARCHIVERS=org.signserver.server.archive.olddbarchiver.OldDatabaseArchiver,org.signserver.server.archive.otherarchiver.OtherArchiver123

ARCHIVE: Previously the archiving was enabled by setting the property to "TRUE". This is the same as to set

ARCHIVERS=org.signserver.server.archive.olddbarchiver.OldDatabaseArchiver

Default: FALSE.

Checking validity of signer certificates

By default the SignServer checks if the signer certificate of a signer is valid before letting the signer process a request. If the signers certificate is not valid an error message is returned. There are two properties that can be set to disable this check:

CHECKCERTVALIDITY: default value is true, meaning that the validity period of the certificate will be verified before processing. Set to false to ignore if the certificate is expired or not yet valid.

CHECKCERTPRIVATEKEYVALIDITY: default value is true, meaning that the validity period in the PrivateKeyUsagePeriod of the certificate will be verified before processing. This is only done if this extension exists (it is optional in a certificate). Set to false to ignore the PrivateKeyUsagePeriod.

MINREMAININGCERTVALIDITY: default value is 0. This property defines a minimum remaining validity time required of the signing certificate. If the signing certificate expires within the number of days specified an error occurs. Set to 0 (default) to disable this check.

Limiting the number of signatures

KEYUSAGELIMIT = Sets how many signatures that are allowed to be created with the same key by this worker (default is -1 = no limit). After the limit has been reached the worker is considered offline. Note that the counter is per key and not per worker so if multiple workers share the same key they will all increment the counter. This also means that the worker is active again after it has gotten a new certificate/key.

Plugins

Configuring a plug-in

A worker component is configured by entering its class path (and optionally its crypto token class path) in a memory bank called the global configuration and then issuing the reload command. There exists sample configurations for most of the plug-ins in the 'doc/sample-configs' directory.

SignServer Signers

There exists multiple signers. One is the time stamp signer generating RFC 3161 compliant timestamps using the Bouncycastle library. An MRTD signer creating "Machine Reader Travel Document" signatures using the RSA algorithm from pre-padded data and another is the MRTD SOD Signer which creates the complete Security Object (SOd) by signing the datagroups for the passport. There are also signers for automatically signing of specific document-types such as PDF, XML, ODF and OOXML and there is a general purpose signer that can sign any document-type and produces the output in Cryptographic Message Syntax (CMS).

Time-stamp Signer

Important, From 3.1 must the Time-Stamp Authority module be uploaded to the SignServer before it can be used. This is done with the command: 'bin/signserver.sh module add dist-server/tsa.mar'

The time-stamp signer have the class path: org.signserver.server.signers.TimeStampSigner

*** Overview ***

The time stamp server generates time stamp tokens and have the support for the following options:

  • Set of accepted policies
  • Set of accepted algorithms
  • Set of accepted extensions
  • Accuracy microseconds
  • Accuracy milliseconds
  • Accuracy seconds
  • Included certificate chain (currently doesn't include CRLs)
  • Ordering
  • TSA name

The time stamp signer currently don't support:

  • CRL inclusion
  • Signed attributes
  • Unsigned attributes

Timestamps requests are served through a http service at the URL:

'http://<host name>/signserver/process?workerId=<worker Id>'
                        

If no 'worker Id' parameter is specified then will the id of 1 be used as default.

The time-stamp signer requires a time-stamp certificate with the extended key usage 'time-stamp' only. The extended key usage extension must be critical.

*** Available Properties ***

The following properties can be configured with the signer:

TIMESOURCE = property containing the fully qualified name of the class implementing the ITimeSource that should be used (OPTIONAL). Below are the built-in TimeSourceS available:

org.signserver.server.LocalComputerTimeSource
This is the default TimeSource and uses the time from the local computer and always returns the time.
org.signserver.server.StatusReadingLocalComputerTimeSource
This TimeSource returns the time from the local computer but only if the status property INSYNC is returned as true from the Status Repository.

ACCEPTEDALGORITHMS = A ';' separated string containing accepted algorithms, can be null if it shouldn't be used. (OPTIONAL, Strongly recommended) Supported Algorithms are: GOST3411, MD5, SHA1, SHA224, SHA256, SHA384, SHA512, RIPEMD128, RIPEMD160, RIPEMD256

ACCEPTEDPOLICIES = A ';' separated string containing accepted policies, can be null if it shouldn't be used. (OPTIONAL, Recommended)

ACCEPTEDEXTENSIONS = A ';' separated string containing accepted extensions, can be null if it shouldn't be used. (OPTIONAL)

DEFAULTTSAPOLICYOID = The default policy ID of the time stamp authority (REQUIRED, if no policy OID is specified in the request then will this value be used.)

ACCURACYMICROS = Accuracy in micro seconds, Only decimal number format, only one of the accuracy properties should be set (OPTIONAL)

ACCURACYMILLIS = Accuracy in milliseconds, Only decimal number format, only one of the accuracy properties should be set (OPTIONAL)

ACCURACYSECONDS = Accuracy in seconds. Only decimal number format, only one of the accuracy properties should be set (OPTIONAL)

ORDERING = The ordering (OPTIONAL), default false. Only false is supported.

TSA = General name of the Time Stamp Authority. (OPTIONAL)

MRTD Signer

Important, From 3.1 must the MRTD Signer module be uploaded to the SignServer before it can be used. This is done with the command:

 'bin/signserver.sh module add dist-server/mrtdsigner.mar'
                    

The MRTD signer have the class path: org.signserver.server.signers.MRTDSigner

*** Overview ***

The MRTD Signer performs a RSA signing operation on incoming data. The data should already be padded. This signer i used to sign 'Machine Readable Travel Documents' i.e. electronic passports.

*** Available Properties ***

No configuration properties exists.

PDF Signer

The PDF signer has the class name: org.signserver.module.PDFSigner

*** Overview ***

The main purpose of the PDF signer is to add digital signatures to PDF documents.

The signer supports the addition of visible or invisible signatures. Both visible and invisible signatures serve the same purpose of signing document, and technically are equivalent in that sense. The difference is that when visible signature is applied to a document, signature image (in shape of rectangle) is placed at the specified place in the document, clicking on which will allow seeing properties of the signature (Adobe Acrobat Reader). On the other hand when invisible signature is applied, signature properties are accessed through menu items. For visible signatures properties such as : custom signature image, signature rectangle, page at which signature rectangle to be drawn and others can be specified (see Available Properties below)

PDF Signer can also apply timestamp to a signature. If the signature is timestamped, it can be viewable through signature properties in Adobe Acrobat Reader. Timestamping is used to prove that document was signed before the time specified by timestamp token. If the signature is not timestamped then the signature time specified in the signature properties is not considered to be trusted. It is strongly advised to apply timestamp to a signature, and the TSA module can be used for this purpose.

Also CRL or OCSP Response of the signer's certificate can be embedded inside the signature package. Embedding CRL or OCSP response with the package will help validate signature even after the signer's certificate is expired. (Though it will not totally guarantee the long term signature preservation. Topic of long term signature preservation for archival purposes is a large one and is discussed to be implemented in future versions of SignServer).

The PDF Signer can also be configured to enforce that certain PDF permissions are not available in the signed document and/or that certain permissions should be removed.

*** PDF passwords ***

PDF documents can optionally be protected by a password.

There are two different types of passwords:

  • User password:
    Also sometimes referred to as "open password" or "document password". It can be used for reading an encrypted document.
  • Owner password:
    Also sometimes referred to as "permission password" or "security restriction password". It can be used for reading an encrypted document and making changes to a document that has permissions.
If a document is protected by an owner password it has to be supplied with the request for SignServer to sign the document. If the document is protected by a user password, either the user password or the owner password has to be supplied with the request for SignServer to sign the document.

*** PDFSigner Requests ***

PDF signing requests can be served using either web services or the web server interface (HTTP). See Integration for general information about the different interfaces.

For the web server interface the GenericProcessServlet can be used. The PDFSigner supports the extra request field "pdfPassword" letting the client supply a PDF password to be used for opening the PDF for signing (not required unless the PDF is already password protected).

For the web services interface the request should contain an encoded GenericProcessesRequest and the response will be an GenericProcessResponse. It is possible to supply a PDF password by including it in the requestMetaData with the key "pdfPassword".

*** Worker Properties ***

The following properties can be configured with the signer:

REASON

The reason included in the PDF signature and displayed by the PDF reader.

Default: "Signed by SignServer".

LOCATION

The location included in the PDF signature and displayed by the PDF reader.

Default: "SignServer".

ADD_VISIBLE_SIGNATURE

Setting that control whether signature to be added should be visible or invisible.

Possible values: True or False.

Default: "False"

VISIBLE_SIGNATURE_PAGE

Specifies the page on which the visible signature will be drawn. This property is ignored if ADD_VISIBLE_SIGNATURE is set to False.

Possible values:
"First" : signature drawn on first page of the document,
"Last" : signature drawn on last page of the document,
page_number : signature is drawn on a page specified by numeric argument. If specified page number exceeds page count of the document ,signature is drawn on last page. If page_number specified is not numeric (or negative number) the signature will be drawn on first page

Default: "First".

VISIBLE_SIGNATURE_RECTANGLE

Specifies the rectangle signature is going to be drawn in.

This property is ignored if ADD_VISIBLE_SIGNATURE is set to False. Format is : (llx,lly,urx,ury).
Here :
llx =left lower x coordinate,
lly=left lower y coordinate,
urx =upper right x coordinate,
ury = upper right y coordinate

Default: "400,700,500,800".

VISIBLE_SIGNATURE_CUSTOM_IMAGE_BASE64 & VISIBLE_SIGNATURE_CUSTOM_IMAGE_PATH

If we want the visible signature to contain custom image, specify image as base64 encoded byte array. Alternatively custom image can be specified by giving a path to image on file system.

Note: if specifying a path to an image "\" should be escaped (thus C:\photo.jpg => "C:\\photo.jpg")

Note: if specifying image as base64 encoded byte array "=" should be escaped (this "BBCXMI==" => "BBCXMI\=\=")

If both of these properties are set then VISIBLE_SIGNATURE_CUSTOM_IMAGE_BASE64 will take priority.

If we do not want this feature then do not set these properties.

Default: not set (no custom image).

These properties are ignored if ADD_VISIBLE_SIGNATURE is set to False.

NOTE: in clustered environment it is more manageable and advised to specify image as base64 string, since image data will be stored in central database. Otherwise each node should contain copy of the image, and each image managed separately (ex: on image updates, or insertion of new image for different worker)

VISIBLE_SIGNATURE_CUSTOM_IMAGE_SCALE_TO_RECTANGLE

If we want our custom image to be resized to specified rectangle (set by VISIBLE_SIGNATURE_RECTANGLE) then set to True. If set to True image might look different that original (as an effect of resizing). If set to False the rectangle drawn will be resized to specified image's sizes.

If set to False llx and lly coordinates specified by VISIBLE_SIGNATURE_RECTANGLE property will be used for drawing rectangle (urx and ury will be calculated from specified image's size).

This property is ignored if ADD_VISIBLE_SIGNATURE is set to False or if custom image to use is not specified.

Possible values: True, False.

Default: "True".

CERTIFICATION_LEVEL

Set this property to have the document certified with a certifying signature.

Possible values:
NOT_CERTIFIED: The document is not certified.
FORM_FILLING: The document is certified but the form can be filled in without invalidating the signature.
FORM_FILLING_AND_ANNOTATIONS: The document is certified but the form can be filled in and annotations added without invalidating the signature.
NO_CHANGES_ALLOWED: The document is certified and no changes can be made.

Default: "NOT_CERTIFIED".

TSA_URL

If we want to timestamp document signature, specify timestamp authority URL.

If we do not want to timestamp document signature, do not set property.

Note: if path contains characters "\" or "=" , these characters should be escaped (thus "\" = "\\", "=" =>"\=")

Default: not set (no timestamping).

TSA_USERNAME & TSA_PASSWORD

If the TSA requires authentication for timestamping, specify username and password. If the TSA does not require authentication, do not set these properties. These properties are ignored if TSA_URL is not set (no timestamping).

Default: not set (tsa does not require authentication).

EMBED_CRL If we want to embed the CRL for signer certificate inside the signature package set to True, otherwise set to False.

Default: "False".

EMBED_OCSP_RESPONSE

If we want to embed the OCSP response for the signer certificate inside the signature package set to True, otherwise set to False.

Note: issuer certificate (of signing certificate) should be in certificate chain.

Default: "False".

ARCHIVETODISK

If we want the produced signed document to be stored in the local file system set this property to true and add the ARCHIVETODISK_PATH_BASE property explained below.

Default: "False".

ARCHIVETODISK_PATH_BASE

The file path to the folder to store the signed documents in.

Required if ARCHIVETODISK is True.

ARCHIVETODISK_PATH_PATTERN

Pattern used for creating sub-folders under the ARCHIVETODISK_PATH_BASE folder.

Current date can be put in by adding ${DATE:yyyy} where yyyy can be replaced be the same syntax as defined in the class java.text.SimpleDateFormat. Other fields are:

  • ${WORKERID}
  • ${WORKERNAME}
  • ${REMOTEIP}
  • ${REQUESTID}
  • ${TRANSACTIONID}
  • ${USERNAME}

Default: "${DATE:yyyy/MM/dd}".

ARCHIVETODISK_FILENAME_PATTERN

Pattern used for creating the filename. The same fields and syntax as for the ARCHIVETODISK_PATH_PATTERN property can be used.

Default: "${WORKERID}-${REQUESTID}-${DATE:HHmmssSSS}.pdf".

REFUSE_DOUBLE_INDIRECT_OBJECTS

True if PDF documents containing multiple indirect objects with the same name should be refused. Used to mitigate a collision signature vulnerability described in http://pdfsig-collision.florz.de/.

REJECT_PERMISSIONS

Reject signing of the document if any of the permissions in the comma separated list would be in the document.

Available permissions:

  • ALLOW_PRINTING
  • ALLOW_MODIFY_CONTENTS
  • ALLOW_COPY
  • ALLOW_MODIFY_ANNOTATIONS
  • ALLOW_FILL_IN
  • ALLOW_SCREENREADERS
  • ALLOW_ASSEMBLY
  • ALLOW_DEGRADED_PRINTING

Default: unset/empty (no permissions are rejected)

SET_PERMISSIONS

Replace the current permissions (if any) with the permissions specified in this comma separated list of permissions.

Available permissions: The same permission names as for the property REJECT_PERMISSIONS.

This property can not be specified if REMOVE_PERMISSIONS is used.

Notice 1: This property and the REMOVE_PERMISSIONS property only sets the permissions setting in the document. All permissions might not be enforced by the PDF reader and some permissions even though specified by this property to be allowed might not be allowed when opening the final document (i.e. if that would invalidate the signature and/or certification).

Notice 2: If the document is not already protected by an owner password and the SET_OWNERPASSWORD is not specified a random password will be used as owner password.

Default: unset (permissions are not set by this property)

REMOVE_PERMISSIONS

Remove all permissions specified in this comma separated list from the document.

Available permissions: The same permission names as for the property REJECT_PERMISSIONS.

This property can not be specified if SET_PERMISSIONS is used.

Notice: This property only removes the permissions listed even if some permissions (i.e. ALLOW_PRINTING) by the standard gives more permissions (i.e. also ALLOW_DEGRADED_PRINTING). To remove all permissions to print remove both ALLOW_PRINTING and ALLOW_DEGRADED_PRINTING. To still have ALLOW_DEGRADED_PRINTING it is possible to specify to only remove ALLOW_PRINTING.

See also Notice 1 and Notice 2 for REMOVE_PERMISSIONS which also applies to this setting.

Removing only ALLOW_DEGRADED_PRINTING has no effect as degraded printing is implicitly allowed if printing is allowed.

Default: unset/empty (no permissions are removed)

SET_OWNERPASSWORD

Sets the specified password as owner password in the document.

The same permissions as before will be used (unless other properties will change them). The same encryption algorithm as the original document will be used. If the original document did not use any encryption then the default encryption algorithm will be used.

Default: unset (if the permissions are changed, the existing owner password will be used or if no such password is used in the document a semi-random password will be created)

ODF Signer

*** Overview ***

ODF Signer, which stands for Open Document Format Signer is a plug-in to SignServer that applies server side signature to documents in ODF format. It has been tested with OpenOffice.org 3.1.

ODF Signer supports only "invisible" signatures, that is unlike PDF signer there's no pictorial representation of the digital signature. When you open signed document in OpenOffice.org you can verify signature using toolbars, or the notifier in status bar (red mark), which notifies user that the document is digitally signed.

*** Available Properties ***

Other than standard worker properties, ODF Signer does not have any other custom ODF signer specific properties.

XML Signer

*** Overview ***

The XML Signer creates enveloped XML signatures using XMLDSig.

The signed XML document can be validated using the XML Validator.

*** Available Properties ***

This signer has no extra properties above the standard worker properties.

OOXML Signer

*** Overview ***

OOXML Signer, which stands for Office Open XML Signer is a plug-in to SignServer that applies server side signature to documents in OOXML format. It has been tested with MS Office 2007.

Currently OOXML Signer supports only "invisible" signatures , that is unlike PDF signer there's no pictorial representation of the digital signature. When you open signed document in MS Office you can verify signature using toolbars, or the notifier in status bar (red mark), which notifies user that the document is digitally signed.

*** Available Properties ***

Other than standard worker properties, OOXML Signer does not have any other custom OOXML signer specific properties.

NOTE : In later versions of OOXML Signer it is planned to add support for visible signatures and custom signature image.

CMS Signer

The CMS signer has the fully qualified class name: org.signserver.module.cmssigner.CMSSigner

*** Overview ***

The CMS signer can sign arbitrary data and produces a CMS (RFC 3852) SignedData structure in binary format.

Currently the signed content is always embedded as well as the signer certificate.

SignServer Document Validators

Document Validators checks the signature and the certificate(s) in documents.

XML Validator

*** Overview ***

The XML validator validates the signature of XML documents. The certificate is checked by the configured certificate validation service.

*** Available Properties ***

VALIDATIONSERVICEWORKER = Name or id of validation service worker for handling certificate validation

RETURNDOCUMENT = True if the response should contain the validated document

STRIPSIGNATURE = True if the signature should be removed from the document if it is returned

SignServer Dispatchers

Dispatchers are workers that forwards the request to other workers.

FirstActiveDispatcher

Fully qualified class name: org.signserver.server.dispatchers.FirstActiveDispatcher

*** Overview ***

Dispatches the request to the first of the configured workers that has an active cryptotoken. This dispatcher can be useful if you want to have one worker to call that forwards the request to any of the configured workers that has a valid certificate etc.

*** Available Properties ***

WORKERS = Comma separated list of workerNameS to try to forward requests to.

SignServer Validation Service Framework

The validation service framework is used to validate certificates from one or more issuers. It can be used to have one central point of performing revokation statuses to simplify the integration of external PKIs within an enterprise.

The validation service framework also provides a validation cache that can be used to increase performance for those cases a application does multiple lookups of the same certificate within a short period of time.

Out-of-the-Box there exists a DefaultValidationService that should satisfy most use cases but it's possible to develop a custom ValidationService if necessary. See the developer section for more details.

All Validation Services is configured by specifying the org.signserver.validationservice.server.ValidationServiceWorker in the global configuration, then is the actual ValidationService configured in the worker configuration setting the class path in the property TYPE (Not necessary for the DefaultValidationService).

The validation service framework is mostly used with X509v3 certificates but other kinds of certificates is supported as well by design.

Another concept in the Validation Service Framework is that the client also can ask the service to check the type of certificate that the certificate might be used for. A certificate type could be IDENTIFICATION or ELECTRONIC SIGNATURE.

DefaultValidationService

*** Overview ***

The default validation service have a set of Validators. A validator is responsible to checking the validity against one or more issuers using for example CRL check or OCSP/XKMS lookup or just by checking some database. Currently there are no ready to use validators, these remain to be developed in future versions of the SignServer.

The Default Validation Service supports validations to be cached for some or all issuers for a specified amount of time.

If not configured otherwise will the validation service use the DefaultX509CertTypeChecker that determines the certificate type from the key usage in the certificate. Key Encipherment and Digital Signature indicates a IDENTIFICATION type and Non-reputation indicates ELECTRONIC SIGNATURE.

There exists a validation specific WebService that can be used for platform independent client calls. The WebService must be enabled during the build and isn't by default. The WebService WSDL file is located at the URL http://<hostname>:8080/signserver/validationws/validationws?wsdl and it contains two calls one is 'isValid' that performs the validation check and the other is a getStatus call that checks the health of the node and its underlying systems. The last calls can be used by clients for monitoring or implementing redundancy.

Important, Due to class path conflict in JBoss 4.2.x own JBoss WebService stack and the JAX-WS stack used by the SignServer must the JBoss WebService stack be removed before the WebService is used. This is done by going to JBOSS_HOME/server/default/deploy and remove the directory jbossws.sar.

*** Available Properties ***

The following properties can be configured with the default validation service:

The validation service have three types of properties, general properties (that applies for the service and all configured validators), validator properties (that only applies for a specific validator) and issuer properties (that only applies for an issuer configured in a specific validator).

General Properties:

CACHEDISSUERS = A ';' separated list of issuer names (usually issuer DNs) (Optional, no validation is cached if unset.)

CERTTYPECHECKER = Certificate type checker that should be used to determine the type of certificate (Optional, default is org.signserver.validationservice.server.DefaultX509CertTypeChecker)

TIMEINCACHE = Time in seconds a certificates validation should be cached (Optional, default is 10 seconds)

Validator properties:
Validator properties is specified with the prefix of 'validator<validatorId>.' or 'val<validatorId>.' were validator Id should be an integer between 1 and 255. For instance, to specify the type of a validator with an id of 1 then specify 'val1.classpath=some.classpath.SomeClass'. This validator will be initialized with all its validator specific properties (with 'val<id>.' prefix removed) as well as the general ones.

CLASSPATH = Class path to the validator that should be used. (Required for each configured validator)

Issuer properties: Issuer properties are specified as 'val<val id>.issuer<issuer id>.<property>' were issuer id is a positive integer between 1 and 255. All generic and validator specific properties (with the given validator id) will also be propagated to the specific issuer configuration.

CERTCHAIN = The certificate path of the CA certificates used to verify the certificate. Should be a appended BASE64 string. (Required for each configured issuer).

Here is an example configuration of a validation service to clarify things even further

# Set up the worker -> validation service wrapper
GLOB.WORKER1.CLASSPATH= org.signserver.validationservice .server.ValidationServiceWorker
#Uncomment and set class path to custom validation service, othervise is default #used.
#WORKER1.TYPE=

# Name of Service (Optional)
WORKER1.NAME=ValidationService1

# Define TestCA2 and TestCA3 as a cached for 15 seconds, TestCA1 is Not cached.
WORKER1.CACHEDISSUERS=CN=TestCA2;CN=TestCA3
WORKER1.TIMEINCACHE=15

# Define a validator in charge of issuer TestCA1 and TestCA2
WORKER1.VAL1.CLASSPATH=<Class path to some validator>
WORKER1.VAL1.ISSUER1.CERTCHAIN=EFWAASDFADFASDFKASDKFW1231.....
WORKER1.VAL1.ISSUER2.CERTCHAIN=EFWAASDFADFASDFKASDKFW1231.....

# Define a validator in charge of issuer TestCA3
WORKER1.VAL2.CLASSPATH=<Class path to some validator>
WORKER1.VAL2.ISSUER1.CERTCHAIN=EFWAASDFADFASDFKASDKFW1231.....
                        

The Validation CLI interface.

There exists a Java CLI tool that can be used to check the validity of a certificate from scripts. It supports a clustered SignServer installation by using the "Use first host that response OK" policy.

When compiling, make sure that setting validationclient.enabled is set to "true" in the build properties. The client is found in dist-client/validationclient. Just copy the validate.jar and all the files in the 'lib' directory to the location where you want to use the client.

Use the client with 'java -jar validate.jar <options>'.

Here is a list of available options:

-cert <cert-file> 			: Path to certificate file (DER or PEM) (Required).
-certpurposes <certpurposes>  	: A ',' separated string containing requested certificate purposes.
-der                           			: Certificate is in DER format.
-help                          			: Display this info
-hosts <hosts>                 		: A ',' separated string containing the hostnames of the validation service nodes. Ex 'host1.someorg.org,host2.someorg.org' (Required)
-pem                    	       		: Certificate is in PEM format (Default).
-port <port>                   		: Remote port of service (Default is 8080 or 8442 for SSL).
-service <service-name>        	: The name or id of the validation service to process request. (Required)
-silent                        			: Don't produce any output, only return value.
-truststore <jks-file>         		: Path to JKS truststore containing trusted CA for SSL Server certificates.(for HTTPS connections)
-truststorepwd <password>      	: Password to unlock the truststore.


The following return values is used:

-2   : Error happened during execution
-1   : Bad arguments
0   : Certificate is valid
1   : Certificate is revoked
2   : Certificate is not yet valid
3   : Certificate have expired
4   : Certificate doesn't verify
5   : CA Certificate have been revoked
6   : CA Certificate is not yet valid
7   : CA Certificate have expired.
8   : Certificate have no valid certificate purpose.
                   

SignServer Group Key Service Framework

*** Overview ***

The group key service framework is used to manage and distribute group keys to clients in an organisation. The keys can be generated on demand or pre-generated at times when the system is not utilized a lot. The group keys can be both symmetric and asymmetric but one service can only distribute one type of key. If several kinds of keys are required should multiple services be set up within the same server.

The group keys are stored encrypted in database. The encryption key can be configured to be switched automatically after a defined number of encryptions to avoid overexposure of the cryptographic data. It is also possible to switch the encryption key manually.

The Framework requires an ExtendedCryptoToken, the difference are that the extended token have additional support for key export and symmetric key operations.

The Group Key Service have CLI commands for administration of the service such as pre-generate keys, manual switch of encryption key and removal of group keys.

The communication to the group key service is mainly done through the main Web Service interface. But other ways of communicating with the server might come in the future.

Authorization to group keys is very important and therefore should a special plug-in be developed that looks up which clients that should have access to a specific group key which fit into the organisation needs. See the authorization chapter of how to develop a customized authorization plug-in.

The basic configuration of a group key service is very similar to that of a validation service. Two entries is required in the global configuration. The first is the class path for the Worker to GroupKeyService wrapper, then a class path reference to the extended crypto token used with the service. If not the default group key service should be used it is possible to define a custom one by specifying its class path in the TYPE worker property.

*** Available Properties ***

USEPREGENERATION = Setting defining of keys should be pre-generated or generated on the fly when needed. If the pool of pre-generated keys gets empty will new keys always be generated automatically. (Optional, default is true)

ENCKEYALG = Encryption algorithm used to encrypt the group keys stored in database. (Optional, default is "AES")

ENCKEYSPEC = Specification of the encryption key. (Optional, default is "256")

GROUPKEYALG = Defines the type of group keys that this service should generate (Optional, default is "AES")

GROUPKEYSPEC = Specification of the generated group keys. (Optional, default is "256")

KEYSWITCHTHRESHOLD = Setting defining the number of group keys that should be encrypted by the same encryption key before it's switched. (Optional, default is 100000)

Other workers

RenewalWorker

Fully qualified class name: org.signserver.module.renewal.worker.RenewalWorker

*** Overview ***

The RenewalWorker can be used to generate new keys and then contact EJBCA using web services to get a new certificate. The worker accepts GenericPropertiesRequestS and returns GenericPropertiesResponseS.

*** Worker Properties ***

EJBCAWSURL = URL to the EJBCA. Example: https://ca-server:8443/ejbca

TRUSTSTOREPATH = Path to the keystore containing the CA's SSL server certificate as a trusted entry.

TRUSTSTORETYPE = Type of keystore. JKS is supported.

TRUSTSTOREPASSWORD = Password protecting the truststore keystore.

*** Properties of renewee ***

KEYALG = Algorithm for the key generation. Examples: RSA, DSA or ECDSA

KEYSPEC = Key length (for RSA or DSA) or curve name (for ECDSA). Examples: 2048, 4096, secp256r1

EXPLICITECC = True if explicit domain parameters should be used instead of NamedCurves. Default: false

DEFAULTKEY = Key alias for the current key.

NEXTCERTSIGNKEY = Key alias for the next key.

*** Request Properties ***

WORKER = Name of the worker that should be renewed.

FORDEFAULTKEY = If the current key should be used instead of the next key or a new key. (Optional, default: false)

*** Response Properties ***

RESULT = "OK" if the renewal succeded otherwise "FAILURE".

MESSAGE = Error message if any.

*** Renewal modes ***
Renewee Request Result
DEFAULTKEY NEXTCERTSIGNKEY FORDEFAULTKEY DEFAULTKEY NEXTCERTSIGNKEY
- - - New key and alias Removed
present - - New key and alias Removed
- present - Alias from nextcertsignkey Removed
present present - Alias from nextcertsignkey Removed
present - TRUE Same alias Same alias
present present TRUE Same alias Same alias

Available CryptoTokens

There exists four types of crypto tokens (Formerly known as sign tokens), two for storing the keys in software, one general for communicating with cryptographic hardware through the PKCS11 interface and one for SmartCards. See the developer section for information about developing support for other HSMs.

Which CryptoToken a worker is using is determined by the its SIGNERTOKEN.CLASSPATH property which should contain the fully qualified class name of the CryptoToken implementation. In addition to that property one must also make sure that the other properties needed by the particular crypto token are available.

General properties

SIGNERTOKEN.CLASSPATH: Fully qualified class name of the crypto token implementation to use. See below for available crypto tokens.

KEYALG: Key algorithm to use when generating new keys (Only for cryptotokens supporting key generation).

KEYSPEC: Key specification to use when generating new keys (Only for cryptotokens supporting key generation).

P12CryptoToken

*** Overview ***

A CryptoToken using a PKCS#12 (.p12/.pfx) key-store in the local file-system.

In a clustered environment the key store must placed at the same location at all nodes.

The P12CryptoToken, doesn't support the destroyKey() method

*** SIGNERTOKEN.CLASSPATH ***

The fully qualified class name is: org.signserver.server.cryptotokens.JKSCryptoToken

*** Available Properties ***

KEYSTOREPATH: The full path to the key-store file to load. (required)

KEYSTOREPASSWORD: The password that locks the key-store. Used for automatic activation.

DEFAULTKEY: The key to use. If not specified the first found key is used. (optional)

JKSCryptoToken

*** Overview ***

A CryptoToken using a Java Key Store (.jks) in the file-system.

In a clustered environment must the key store be at the same location at all nodes.

The JKSCryptoToken, doesn't support the destroyKey() method

*** SIGNERTOKEN.CLASSPATH ***

The fully qualified class name is: org.signserver.server.cryptotokens.P12CryptoToken

*** Available Properties ***

KEYSTOREPATH: The full path to the key-store to load. (required)

KEYSTOREPASSWORD: The password that locks the key-store. Used for automatic activation.

DEFAULTKEY: The key to use. If not specified the first found key is used. (optional)

NEXTCERTSIGNKEY: The next key to use. See PKCS11CryptoToken. (optional)

PrimeCardHSMCryptoToken

*** Overview ***

Using PrimeCardHSM it's possible to use a SmartCard to generate 2048-bit RSA signatures. The SmartCard can perform about one signature a second. PrimeCardHSM is proprietary software by PrimeKey Solutions AB.

PrimeCardHSM requires PCSCD software and SmartCard drivers. See separate documentation about installing PrimeCardHSM.

The PrimeCardHSMCryptoToken, doesn't support the destroyKey() method.

*** SIGNERTOKEN.CLASSPATH ***

The fully qualified class name is: org.signserver.server.cryptotokens.PrimeCardHSMCryptoToken

*** Available Properties ***

DEFAULTKEY = Hash value of the signing key on the card. See PrimeCardHSM documentation for more information.(Required)

NEXTCERTSIGNKEY: The next key to use. See PKCS11CryptoToken. (optional)

AUTHCODE = Authentication code for automatic activation (Optional).

PKCS11CryptoToken

*** Overview ***

Using PKCS11 it's possible to use a HSM that has a PKCS11 module, such as Utimaco, nCipher, SafeNet or AEP KeyPer. SignServer uses the same underlying implementation of PKCS11 crypto tokens as EJBCA. To find out more about supported devices and get information how to configure them you can visit the HSM documentation at EJBCA.org. The only thing that differs are the token labels strings, which you should use from below for SignServer. A very useful tool from EJBCA is the ClientToolBox. If you can generate anbd test PKCS11 keys using the clientToolBox, you can use them with SignServer.

*** SIGNERTOKEN.CLASSPATH ***

The fully qualified class name is: org.signserver.server.cryptotokens.PKCS11CryptoToken

*** Available Properties ***

DEFAULTKEY = The key alias. (Required)

NEXTCERTSIGNKEY = The next key to use. This property can be used to hold the name of the next key to use. Certificate signing requests (CSR) can be made for this key can while to the current key (DEFAULTKEY) is still in production. After uploading the new certificate the value of NEXTCERTSIGNKEY can be moved to DEFAULTKEY. (optional)

PIN = Authentication code for activation. (Required)

SHAREDLIBRARY = Full path to the library containing the PKCS11 interface. (Required)

SLOT or SLOTLISTINDEX = Slot number or the index of the slot to use. (Required and only one of them can be used.)

ATTRIBUTESFILE = Path to file with PKCS#11 attributes used for key generation.

Sample p11attributes.cfg working with SafeNet Luna:

attributes(generate,*,*) = {
  CKA_TOKEN = true
}
attributes(generate,CKO_PUBLIC_KEY,*) = {
  CKA_ENCRYPT = true
  CKA_VERIFY = true
  CKA_WRAP = true
}
attributes(generate, CKO_PRIVATE_KEY,*) = {
  CKA_EXTRACTABLE = false
  CKA_DECRYPT = true
  CKA_SIGN = true
  CKA_UNWRAP = true
}
                        
*** Example usage ***

Edit qs_pdfsigner_configuration.properties and choose the sign token setting for the PKCS11 sign token. Run the following command to set up a PDF signer using the PKCS11 properties configured: bin/signserver.sh setproperties qs_pdfsigner_configuration.properties

Generate a keypair for the signer: bin/signserver.sh generatekey 8 -alias defaultKey -keyalg RSA -keyspec 2048

Test the keypair: bin/signserver.sh testkey 8

You also need a certificate for the signer. Generate a certificate request with the command: bin/signserver.sh generatecertreq 8 "CN=PKCS11 Signer token" SHA1WithRSA /tmp/certreq.pem

Add a user in EJBCA with a certificate profile suitable for signing, and enrol for a "Server Certificate" using the public web pages.

Create the certificate chain file with the command: cat /tmp/cert.pem /tmp/AdminCA1.pem > /tmp/certchain.pem

The signer certificate must be first, and the root CA certificate last.

Upload the signing certificate chain to the signer using the command: bin/signserver.sh uploadsignercertificatechain 8 GLOB /tmp/certchain.pem

After the certificate chain has been uploaded to the server, the configuration must be reloaded and the server must be restarted. It is not sufficient to only reload the configuration.

SoftCryptoToken

*** Overview ***

The SoftCryptoToken is a simple token managing it's own soft keys instead of using a PKCS12 file. It can be used for test and demonstration purposes. The keys are stored in the worker's properties and is generated when genCertificateRequest is called. One key is used for all purposes and a new key is generated for every certificate request.

The method destroyKey is not supported.

There is also a tool available for constructing the properties from a PKCS12 file in CryptoTokenUtils.java. To run the tool outside the IDE first build SignServer by running "ant". After that the tool can be executed with something similar to:

java -cp dist-server/signserver-ejb.jar:lib/1.6/bcprov-jdk.jar:dist-server/lib/SignServer-Common.jar:lib/ejbca-util.jar org.signserver.server.cryptotokens.CryptoTokenUtils createsoft src/test/dss10/dss10_signer1.p12 "signer 1" foo123
                        
*** SIGNERTOKEN.CLASSPATH ***

The fully qualified class name is: org.signserver.server.cryptotokens.SoftCryptoToken

*** Available Properties ***

KEYDATA = The serialized KeyPair generated by genCertificateRequest, usually is this setting configured by the SoftCryptoToken itself.

KEYALG = The algorithm used when generating new keys. (Optional, default is "RSA")

KEYSPEC = The key specification used when generating new keys. (Optional, default is "2048")

*** Example usage ***

First change the global property of WORKER<ID>.CRYPTOTOKEN.CLASSPATH of the worker you want to use the SoftCryptoToken with. After reload will an empty and inactive SoftCryptoToken be created.

Then generate a certificate request with the command, in this step will new keys be generated

bin/signserver.sh generatecertreq <id> "CN=Soft Signer token" SHA1WithRSA /tmp/certreq.pem
                        

Then upload the signing certificate to the worker using the command:

bin/signserver.sh uploadsignercertificatechain <id> GLOB /tmp/cert.pem
                        

After the certificate chain has been uploaded to the server, the configuration must be reloaded and the SoftCryptoToken will be active and ready to use.

Development

This section describes the details of how to develop your own plug-ins for the SignServer API. It goes through most of the necessary interfaces to get going.

Building customized code

It is possible to have your own code in a separate code tree to avoid a mix of custom code with SignServer project code. This makes it easier to maintain and update the code for future versions. This is done by configuring one or more of the 'custom.' parameters in the build configuration file. The are each described here:

custom.src.java = Should point to an external directory containing the package base of the Java code. These are then included in the compilation at build time.

custom.src.web = Should point to the base of a WAR source tree with WEB-INF/web.xml included. This will replace the default WAR deployed during the build.

custom.build.xml = This can point to a custom build.xml that will be imported from the main build.xml and lets the developer include his own ant tasks if necessary.

custom.commandfactory = Should point to a custom implementation of the interface org.signserver.cli.ISignServerCommandFactory. This gives to ability to extend (or replace) the default CLI with another one. The best way of extending the CLI is to look at how the DefaultSignServerCommandFactory is structured.

Plugin development

The main component in the SignServer is the Worker from which most other components inherits. To get a better overview of how the different component types relate to one and another see illustration 1 in the Overview section.

Most workers work in the same way but with different interfaces to implement but for all of them should the following steps be performed.

  • Create a custom class implementing the specified interface. There usually exists a base class implementing the most basic function to simply the implementation even further. If it exists it's recommended to inherit it.
  • You can define your own properties that the worker can use for its configuration.
  • Make sure the custom class is available to the application server
  • Redeploy the SignServer.
  • Register the worker in the application by setting a property WORKER<id>.CLASSPATH with a global scope in the global configuration. (Also make sure to set it's crypto tokens class-path, see separate section).
  • Reload the service with the CLI reload command.

Implementing Workers

*** The ISigner Interface ***

A Signer is a component used to perform some form of cryptographic processing of requested data and to create a custom signer class it should implement the org.signserver.server.signers.ISigner interface. There exists a BaseSigner that can be inherited taking care of some of the functionality. If the BaseSigner is inherited the only method that needs to be implemented is 'processData() '.

There exists a DummySigner implementation that is used for demonstration purposes.

*** The ITimedService Interface ***

There are two kinds of timed services, singleton or non-singleton. A singleton service is only run at one of the nodes at the time while non-singleton services are run at all nodes simultaneously. If a singleton service fails to run on one of the nodes will one of the other nodes take over the service automatically.

If a service should be singleton or not is determined by a standard property SINGLETON defined in the ServiceConfig class.

Other basic properties used to configure all services are: ACTIVE when set to "TRUE" means that the service is active and should be run. INTERVAL defining the interval in seconds of how often the service should be run. INTERVALMS defining the interval in milliseconds of how often the service should be run. CRON used instead of INTERVAL or INTERVALMS to specify on a calendar basis.

To create a custom timed service class it should implement the org.signserver.server.timedservices.ITimedService interface. There exists a BaseTimedService that can be inherited taking care of most of the basic functionality. If the BaseTimedService is inherited the the only method that needs to be implemented is the 'work()' method.

The work method that needs to be implemented is described here:

/**
 * Method that should do the actual work and should
 * be implemented by all services. The method is run
 * at a periodical interval defined in getNextInterval.
 *
 * @throws ServiceExecutionFailedException if execution of a service failed
 */
public void work() throws ServiceExecutionFailedException;
                        

There exists a DummyTimedService implementation that is used for demonstration purposes.

*** IValidationService Interface ***

Just as the other worker plug-ins have the validator service a base class taking care of most of the common methods and the only method that needs to be implemented is the 'validate' method below. But for most applications should the DefaultValidationService work. What is probably more interesting is to develop a custom IValidator used to integrate the default validation service against different certificate status repositories. See section called 'Other Customizations' for details of how to implement a Validator.

/**
 * Method used to check the validation of a certificate
 *
 * @param validationRequest
 * @return a ValidateResponse
 * @throws IllegalRequestException if data in the request didn't conform with the specification.
 * @throws CryptoTokenOfflineException if the crypto token isn't online.
 * @throws SignServerException for general failure exception during validation
 * @see org.signserver.validationservice.common.ValidateRequest
 * @see org.signserver.validationservice.common.ValidateResponse
 */
ValidateResponse validate(ValidateRequest validationRequest) throws IllegalRequestException, CryptoTokenOfflineException, SignServerException;
                        
*** IGroupKeyService Interface ***

To customize a group key service is slightly more work. Then need five methods be implemented: 'fetchGroupKey', 'pregenerateGroupKeys', 'swithEncryptionKey', 'removeGroupKeys' and 'getStatus'. The default implementation stores the group keys in database with a reference to the encryption key used, the encryption key is stored in the extended key store. See the JavaDoc and the code for the default group key service for more details of implementing a customized one.

/**
 * Main method of a Group Key Service responsible for fetching keys from
 * the database.
 *
 * @param fetchKeyRequest
 * @return a FetchKeyReponse
 * @throws IllegalRequestException if data in the request didn't conform with the specification.
 * @throws CryptoTokenOfflineException if the crypto token isn't online.
 * @throws SignServerException for general failure exception during key generation.
 * @see org.signserver.groupkeyservice.common.FetchKeyRequest
 * @see org.signserver.groupkeyservice.common.FetchKeyResponse
 */
FetchKeyResponse fetchGroupKey(FetchKeyRequest fetchKeyRequest) throws IllegalRequestException, CryptoTokenOfflineException, SignServerException;

/**
 * Method that instructs the group key service to pregenerate keys.
 * This method is called at periods when the server is having
 * a low load. This option is optional to implement, if the
 * service doesn't support this method it should return null.
 *
 *
 * @param pregenerateKeysRequest request data
 * @return a response containing number of keys generated, etc
 * @throws IllegalRequestException if requests contain unsupported data.
 * @throws CryptoTokenOfflineException if the crypto token isn't online.
 * @throws SignServerException for general failure exception during key generation.
 * @see org.signserver.groupkeyservice.common.PregenerateKeysRequest
 * @see org.signserver.groupkeyservice.common.PregenerateKeysResponse
 */
PregenerateKeysResponse pregenerateGroupKeys(PregenerateKeysRequest pregenerateKeysRequest) throws IllegalRequestException, CryptoTokenOfflineException, SignServerException;


/**
 * Method instructing the key service to switch the encryption key for
 * storing the group keys in the database. This to ensure that one encryption
 * key isn't exposed through to much data.
 *
 * This method is optional for the implementing service to implement, if
 * it's not implemented it should return null.
 *
 * @param switchEncKeyRequest request data.
 * @return a response containing the result of the operation such as new key index.
 * @throws IllegalRequestException if requests contain unsupported data.
 * @throws CryptoTokenOfflineException if the crypto token isn't online.
 * @throws SignServerException  for general failure exception during key generation.
 * @see org.signserver.groupkeyservice.common.SwitchEncKeyRequest
 * @see org.signserver.groupkeyservice.common.SwitchEncKeyResponse
 */
SwitchEncKeyResponse switchEncryptionKey(SwitchEncKeyRequest switchEncKeyRequest) throws IllegalRequestException, CryptoTokenOfflineException, SignServerException;

/**
 * Method instructing the key service to remove old group keys not used anymore
 * it up to the caller to check that the implementing service supports the type
 * of IRemoveGroupKeyRequest used. The request should contain data specifying which
 * keys that should be removed.
 *
 * This method is optional for the implementing service to implement, if
 * it's not implemented it should return null.
 *
 * @param removeGroupKeyRequests request data.
 * @return a response containing the result of the operation such as number of keys actually removed.
 * @throws IllegalRequestException if requests contain unsupported data.
 * @throws CryptoTokenOfflineException if the crypto token isn't online.
 * @throws SignServerException  for general failure exception during key generation.
 * @see org.signserver.groupkeyservice.common.RemoveGroupKeyResponse
 * @see org.signserver.groupkeyservice.common.IRemoveGroupKeyRequest
 */
RemoveGroupKeyResponse removeGroupKeys(IRemoveGroupKeyRequest removeGroupKeyRequests) throws IllegalRequestException, CryptoTokenOfflineException, SignServerException;


/**
 * Should return the actual status of the worker, status could be if
 * the signer is activated or not, or equivalent for a service.
 * @return a WorkerStatus object.
 */
public WorkerStatus getStatus();
                        

Implementing Crypto Tokens

*** The ICryptoToken Interface ***
  • A custom crypto token needs to implement the interface org.signserver.server.cryptotokens.ICryptoToken. See P12CryptoToken for an example implementation.
  • You can define own properties for a crypto token in the same way as for workers. The properties are sent to the crypto token upon initialization.
  • Make sure the custom class is available to the application server
  • Redeploy the SignServer.
  • Register the crypto token to a worker in the application by setting a property WORKER<id>.CRYPTOTOKEN.CLASSPATH with a global scope in the global configuration. (Also make sure to set it's crypto tokens class-path, see next section).
  • Reload the service with the CLI reload command.

The ICryptoToken interface have the following methods that needs to be implemented:

public interface ICryptoToken {
	public static final int PURPOSE_SIGN = 1;
	public static final int PURPOSE_DECRYPT = 2;

	public static final int PROVIDERUSAGE_SIGN    = 1;
	public static final int PROVIDERUSAGE_DECRYPT = 2;

   /**
    * Method called after creation of instance.
    *
    */
	public abstract void init(Properties props) throws CryptoTokenInitializationFailureException;

	/**
	 *  Method that returns the current status of the crypto token.
	 *
	 *  Should return one of the SignerStatus.STATUS_.. values
	 */
	public abstract int getCryptoTokenStatus();

    /**
     * Method used to activate SignTokens when connected after being off-line.
     *
     * @param authenticationcode used to unlock crypto token, i.e PIN for smartcard HSMs
     * @throws CryptoTokenOfflineException if SignToken is not available or connected.
     * @throws CryptoTokenAuthenticationFailureException with error message if authentication to crypto token fail.
     */
    public abstract void activate(String authenticationcode) throws CryptoTokenAuthenticationFailureException, CryptoTokenOfflineException;

    /**
     * Method used to deactivate crypto tokens.
     * Used to set a crypto token too off-line status and to reset the HSMs authorization code.
     *
     * @return true if deactivation was successful.
     */
    public abstract boolean deactivate();

    /** Returns the private key (if possible) of token.
    *
    * @param purpose should one of the PURPOSE_... constants
    * @throws CryptoTokenOfflineException if CryptoToken is not available or connected.
    * @return PrivateKey object
    */
    public abstract PrivateKey getPrivateKey(int purpose) throws CryptoTokenOfflineException;

    /** Returns the public key (if possible) of token.
    *
    * @param purpose should one of the PURPOSE_... constants
    * @throws CryptoTokenOfflineException if CryptoToken is not available or connected.
    * @return PublicKey object
    */
    public abstract PublicKey getPublicKey(int purpose) throws CryptoTokenOfflineException;


    /** Returns the signature Provider that should be used to sign things with
     *  the PrivateKey object returned by this crypto device implementation.
     *  @param providerUsage should be one if the ICryptoToken.PROVIDERUSAGE_ constants
     *  specifying the usage of the private key.
     * @return String the name of the Provider
     */
    public abstract String getProvider(int providerUsage);

    /**
     * Method returning the crypto tokens certificate if it's included in the token.
     * This method should only be implemented by soft crypto tokens which have the certificate
     * included in the key store.
     *
     * All other crypto tokens should return 'null' and let the signer fetch the certificate from database.
     *
     */

    public abstract Certificate getCertificate(int purpose) throws CryptoTokenOfflineException;


    /**
     * Method returning the crypto tokens certificate chain if it's included in the token.
     * This method should only be implemented by soft crypto tokens which have the certificates
     * included in the key store.
     *
     * All other crypto tokens should return 'null' and let the signer fetch the certificate from database.
     *
     */

    public abstract Collection<Certificate> getCertificateChain(int purpose) throws CryptoTokenOfflineException;

	/**
	 * Method used to tell the crypto token to create a certificate request using its crypto token.
	 */
	public ICertReqData genCertificateRequest(ISignerCertReqInfo info) throws CryptoTokenOfflineException;

	/**
	 * Method used to remove a key in the signer that shouldn't be used any more
	 * @param purpose on of ICryptoToken.PURPOSE_ constants
	 * @return true if removal was successful.
	 */
	public boolean destroyKey(int purpose);
}
                        
*** The Extended Crypto Token Interface ***

The default group key service need support for symmetric keys in addition the the functionality provided in the basic crypto token which mainly focuses on asymmetric key functionality.

The extended crypto token adds four more methods that need implementation used to generate exportable keys (symmetric or asymmetric) and to encrypt/decrypt data using symmetric keys.

public interface IExtendedCryptoToken extends ICryptoToken {

	/**
	 * Method instructing the crypto token to generate a key that is returned
	 *
	 * @param keyAlg the key algorithm to generate, it's up to the caller to check that the crypto token
	 * used supports the given value.
	 * @param keySpec specification of the key, it's up to the caller to check that the crypto token
	 * used supports the given value.
	 * @return either a java.security.Key or a java.security.KeyPair depending on type of keyAlg sent to the the crypto token.
	 * @throws IllegalRequestException if the token doesn't support the given key alg or key spec.
	 * @throws CryptoTokenOfflineException if the token isn't online.
	 */
	Serializable genExportableKey(String keyAlg, String keySpec) throws IllegalRequestException, CryptoTokenOfflineException;

	/**
	 * Instructs the crypto token to generate a key stored in the device returning only
	 * a alias reference to the key.
	 *
	 * @param keyAlg the key algorithm to generate, it's up to the caller to check that the crypto token
	 * @param keySpec keySpec specification of the key, it's up to the caller to check that the crypto token
	 * used supports the given value.
	 * @return a reference to the key in that can be used later for encryption/decryption.
	 *
	 * @throws IllegalRequestException if the token doesn't support the given key alg or key spec.
	 * @throws CryptoTokenOfflineException if the token isn't online.
	 */
	String genNonExportableKey(String keyAlg, String keySpec) throws IllegalRequestException,  CryptoTokenOfflineException;

	/**
	 * Method used to encrypt data using a key stored in the crypto token. This
	 * method should mainly be used for symmetric encryption.
	 * @param keyRef a alias reference to the key that should be used.
	 * @param data the data to encrypt.
	 * @return the encrypted data.
	 * @throws CryptoTokenOfflineException if the token isn't online.
	 */
	byte[] encryptData(String keyRef, byte[] data) throws CryptoTokenOfflineException;

	/**
	 * Method used to decrypt data using a key stored in the crypto token. This
	 * method should mainly be used for symmetric encryption.
	 * @param keyRef a alias reference to the key that should be used.
	 * @param data the data to decrypt.
	 * @return the encrypted data.
	 * @throws CryptoTokenOfflineException if the token isn't online.
	 */
	byte[] decryptData(String keyRef, byte[] data) throws CryptoTokenOfflineException;


}
                        

Other Customizations

The IValidator Interface

A Validator is used in the DefaultValidationService to connect to different kinds of certificate status repositories, such as CRL, OCSP, XKMS, database etc. It contains two methods 'validate' used for the actual certificate validation and 'testConnection' used by health check related functionality to check that the connection to the underlying validator resource is alright.

/**
 * Main method of a Validation Service responsible for validating certificates.
 *
 * Important a validator also have to support to check the revocation status of the
 * involved CA certificates and should only return Validation object with status REVOKED or VALID
 * If the validator doesn't support the given issuer it must return null.
 *
 *
 * @param cert the certificate to validate.
 * @return a Validation object or null if the certificate couldn't be looked up in this validator.
 * @throws IllegalRequestException if data in the request didn't conform with the specification.
 * @throws CryptoTokenOfflineException if the crypto token isn't online.
 * @throws SignServerException for general failure exception during validation.
 */
Validation validate(ICertificate cert) throws IllegalRequestException, CryptoTokenOfflineException, SignServerException;






/**
 * Optional method used to test the connection to a specific underlying validator implementation.
 *
 * @throws ConnectException if connection to underlying validator implementation failed.
 * @throws SignServerException for general failure exception during validation.
 */
void testConnection() throws ConnectException, SignServerException;
                    

The IAuthorizer Interface

It's possible to integrate the authorization of processable requests with external authorizations applications. All that is needed is a class implementing the IAuthorizer interface containing two methods, 'init' and 'isAuthorized'.

To register that the customized authorizer should be used by a worker, all that's needed to be done is to set the property AUTHTYPE to the class path of the authorizer implementation.

public interface IAuthorizer {

	/**
	 * Method called by the worker upon first call to the authenticator after instantiation.
	 *
	 * @param workerId id of worker.
	 * @param config active worker configuration of worker
	 * @param em the SignServer EntityManager
	 * @throws SignServerException if unexpected error occurred during initialization.
	 */
	void init(int workerId, WorkerConfig config, EntityManager em) throws SignServerException;

	/**
	 *
	 * Main method determining if the requester is authorized to process the data in the request.
	 *
	 * @param request the request data sent to the worker to process.
	 * @param requestContext containing the optional clientCert client certificate or remote IP of the user, may also contain customly defined data.
	 * @throws SignServerException if unexpected error occurred during authorization.
	 * @throws IllegalRequestException if the requester isn't authorized or couldn't be authenticated for some other reason.
	 */
	void isAuthorized(ProcessRequest request, RequestContext requestContext) throws IllegalRequestException, SignServerException;
}
                    

The Archiving API

Custom ArchiverS can be implemented by implementing the Archiver interface. See org.signserver.server.archive.Archiver.

Archiving API

Using the Global Configuration Store

The global configuration store is a memory bank that workers can use to store data used in ongoing operations. The data can be either node (i.e. only read by the current node) or global scoped.

To access the global configuration store use the getGlobalConfigurationSession() method from the BaseWorker (inherited by most of the base component implementations). The returned GlobalConfigurationSession have the following methods that can be used (the other ones should be avoided)

/**
* Method setting a global configuration property. For node. prefix will the
node id be appended.
* @param scope, one of the GlobalConfiguration.SCOPE_ constants
* @param key of the property should not have any scope prefix, never null
* @param value the value, never null.
*/
public void setProperty( java.lang.String scope,java.lang.String
key,java.lang.String value ) ;
/**
* Method used to remove a property from the global configuration.
* @param scope, one of the GlobalConfiguration.SCOPE_ constants
* @param key of the property should start with either glob. or node., never
null
* @return true if removal was successful, othervise false.
*/
public boolean removeProperty( java.lang.String scope,java.lang.String key )
;
/**
* Method that returns all the global properties with Global Scope and Node
scopes properties for this node.
* @return A GlobalConfiguration Object, nevel null
*/
public org.signserver.common.GlobalConfiguration getGlobalConfiguration( ) ;
                    

The getGlobalConfiguration returns a GlobalConfiguration and have a method String getProperty(String scope, String property) that can be used. The value of the property can be user-defined as long as it is guaranteed to be unique over the entire application. Reserved values are all property keys starting with "WORKER".

The Cluster Class Loader

Important, this feature is very new in version 3.1 and should still be considered experimental.

New to SignServer 3.1.x is the Cluster Class Loader. Simplifying the management of code in clusters. Instead of manually having to synchronize all the required JAR files to all nodes, it is possible to upload the code once and it will be accessible to all nodes in the cluster directly without having to restart the cluster. This is archived by storing the JAR resource data (such as class files) in database instead of in the application server class path.

Each worker will have their own Cluster Class Loader instance that will be reinitialized upon reload.

It is also possible to run multiple code versions of a worker simultaneously in a cluster, something that haven't been possible until now since only one version of class can exists in one JVM. This is a great feature for migration purposes where you have an old worker that is known to be stable, then it is possible to upload a new module beside the old one, with newer code, and migrate calling clients one by one. Under the hood is actually a version prefix appended on the fly to the class name by the Cluster Class Loader when converting the byte code into a class. For example a class called somepkg.SomeWorker with version 3 will be called v3.somepkg.SomeWorker internally in the JVM. A developer should have to thing about this when developing his module but it might cause problems when remotely debugging the SignServer since the IDE won't find the source class to the modified code. If remote debugging is going to be used should class versioning be turned off.

To improve the security of the code stored in database it is possible to enforce signature verification of all the uploaded code. This is a good feature if the database is in a different security zone or managed by different administrator than the SignServer nodes itself. If verification is turned on will the Cluster Class Loader check that the class is signed with a certificate issued by issuers stored in a specific trust key store for this purpose. Important, make sure the v the code signing certificate and it's issuers have a validity long enough to avoid production stop since the signature will not verify after the certificate have expired. The code is signed by a separate JKS key store when the module is uploaded to a cluster. The code signing certificate must have the extended key usage 'code signing' in order for the Cluster Class Loader to verify it.

Before code can be uploaded to the Cluster Class Loader must it's JAR files be packaged in something called a Module Archive (MAR). See section 15.2 for details about generating a MAR file.

Building Module Archives

A 'Module Archive' is a package containing all the jars required by the module along with a descriptor with information about the name of the module and it's version. A module archive is uploaded once and is then accessible for all the nodes in the cluster. A module archive can also have multiple parts indicating where in the system the code should be uploaded. In 3.1.x is only one part called 'server' supported, but in the future will other parts such as 'admin' exist. In that case will the code that should be executed on the server, such as worker code, be sent to the cluster, while the administrative part of the code is only sent to the node with an administrative web interface.

A 'Module Archive' have the postfix '.mar' and is managed with the CLI interface using the 'module' commands.

The MAR Descriptor

Every Module archive should have a descriptor file in it's META-INF directory. It follows the JAVA Properties notation and is used to specify general information about the module such as version and name of the module. This file is generated automatically when using the ANT tasks.

The MAR descriptor supports the following properties:

Property Description
version The version of the module archive, can only contain digits. If not set "1" will be used. (Optional)
modulename The name of the module, if not set will the MAR file name be used, but without '.mar'. The name will always be converted to upper case. (Optional)
default-description The default description of all the resources in the module (Optional)
parts The parts in the module archive, if not set will only the 'server' part be used. (Optional)

Including Worker Configurations

It is also possible to include a set of worker configurations in the 'server' part of the module archive, these settings is configured directly after all the JAR files have been uploaded. These worker configurations should be property files that follows the same notation as if they where used with the 'setproperties' CLI command.

By default it should be named 'part-config.properties' and be in the 'server' part directory. It is also possible to have multiple configurations that is used depending on the environment the SignServer cluster is used. For instance it is possible to have one configuration file for test, another for production and a third for development. This makes it easy to manage the module since exactly the same file will be used in all environments. In case of multiple configurations should every property file be named '<environment>-part-config.properties', for instance test-part-config.properties. Later when the module is uploaded and the environment 'test' is specified will the test configuration be used.

Important, if a part-config.properties file is included in the MAR file will the worker properties MODULENAME and MODULEVERION automatically the be set to all workers defined in the configuration file and there is no need to manually define these settings.

Using ANT

The simplest way to build a Module Archive is by using ANT. The SignServer have provided two ant tasks to do this.

All that is required to use these tasks is to add the following two lines in your target:

    <taskdef name="mar" classname="org.signserver.anttasks.MarAntTask"
       classpathref="signserver.test.compile.classpath"/>
    <taskdef name="part" classname="org.signserver.anttasks.PartAntTask"
       classpathref="signserver.test.compile.classpath"/>
                    

With these two lines included you will have access the the 'mar' and 'part' tasks. The tasks have the following properties.

MAR Task Properties

Property Description
version The version of the module archive, can only contain digits. If not set will "1" be used. (Optional)
modulename The name of the module, if not set will the destfile property be used, but only the file name without '.mar'. Will always be converted to upper case. (Optional)
description The default description of the module that is set in the MAR descriptor.(Optional)
destfile The path and file name of the mar file to generate. (Required)
verbose Set to true if verbose output should be done during execution.(Optional)
part One or more 'part' tasks is required in order to generate a MAR file. (Required)

PART Task Properties

Property Description
name The name of the part, if not set will the default 'server' (and the only part supported in 3.1.x) be used. (Optional)
fileset One or more 'filesets' are required containing JAR file or worker configurations. (Required)

Here is an example of a simple ANT task building a MAR file, it will have the module name of SOME, version of 3 and have a 'server' part with all the JARs in 'somejarlocation' and all the worker properties in the directory 'someworkerpropertieslocation' :

    <target name="gensomemar" depends="signserver.ear">
    <taskdef name="mar" classname="org.signserver.anttasks.MarAntTask"
       classpathref="signserver.test.compile.classpath"/>
    <taskdef name="part" classname="org.signserver.anttasks.PartAntTask"
       classpathref="signserver.test.compile.classpath"/>
    	<mar version="3" destfile="dist/some.mar" verbose="true">
    		<part>
    	         <fileset dir="${somelibrarylocation}">
    	           <include name="*.jar"/>
    	         </fileset>
    	         <fileset dir="${somejarlocation}">
    	           <include name="*.jar"/>
    	         </fileset>
    	         <fileset dir="${someworkerproperiteslocation}">
    	           <include name="*.properties"/>
    	         </fileset>
    		</part>
    	</mar>
    </target>

Building Manually

A Module Archive is just like a JAR or EAR file basically a ZIP with a certain file structure. And it is quite easy to create one manually if the ANT task cannot be used. The following rules should be followed when creating a MAR file:

The module descriptor file should be in META-INF/mar-descriptor.properties. If other than just the 'server' part is used, then it is important that the 'parts' property is set correctly. Every part should have a directory with the same name as the part containing all the JAR files and worker configuration files. In 3.1.x is only one part supported and it should be named 'server'. No subdirectories should exists in the parts directory.

Managing Module Archives

Managing of MAR files is done using the CLI command 'signserver.sh/.cmd module' it have three subcommands: add, remove and list. See chapter 17.2.5 for more details.

Here is an example usage of adding a module to a SignServer:

'bin/signserver.sh module add dist-server/tsa.mar demo'
                    

This will load the Time-Stamp Authority module with the demo environment, this requires that the mar file have a file called demo-part-config.properties in the server directory.

Changing the default configuration of the Cluster Class Loader

When enabled, the default configuration of the Cluster Class Loader is to support multiple versions but not requiring signature verification. This behaviour can be changed in the signserver_build.properties file under the 'Cluster Class Loader Configurations' section.

The following properties can be set:

Property Description
useclusterclassloader Set to true to enable the use of the cluster class loader. Default is true.
clusterclassloader.useclassversions Indicates if multiple versions of the same worker code should be supported. Default true. Turn this of if remote debugging should be used.
clusterclassloader.requiresignature Set to true if signing of resource data should be required. Default false
clusterclassloader.pathtotruststore Path to the JKS trust store containing all CA certificates that is trusted for signing of resource data. Only required if signature verification is used.
clusterclassloader.truststorepwd Password to unlock the trust store. Only required if signature verification is used.

Remember to do an 'ant clean' when changing settings in the signserver_build.properties

Testing

There exists some test scripts used to test that the SignServer functions correctly. They are described here.

Automatic JUnit Tests

Automatic JUnit tests are in the different projects and system tests in SignServer-Test-System.

Important: For the SignServer test suite to run successful the following properties should be set in signserver_build.properties:

  • signserverws.enabled=true
  • genericws.enabled=true
  • validationws.enabled=true
  • adminws.enabled=true
  • timestampclient.enabled=true
  • validationclient.enabled=true
  • signingandvalidationapi.enabled=true
  • clientcli.enabled=true
  • includemodulesinbuild=true
  • useclusterclassloader=true
  • clusterclassloader.useclassversions=true

To run the test suite do the following:

  • Set the environment variable SIGNSERVER_HOME
  • Make sure SignServer is deployed and the application server is running
  • Do 'ant test:run'
  • A protocol is generated in the directory 'bin/junit'

A single system test can be run with "ant test:runone -Dtest.runone=ClassName" where ClassName is replaced with the test class to run.

A single test can also be run the same way from any of the other projects that has tests by executing the command from their project directory.

Testing the TimeStamp Authority

*** The TSA Test Client ***

There exists a Time Stamp Authority test client that is built with the main distribution. For other workers it's recommended to test it with the WS CLI client described in the 'Main WebService' section.

It only works without client authentication requirements and through HTTP.

To run the client do

ant
cd dist-client
java -jar timeStampClient.jar "http://<hostname>:8080/signserver/tsa?signerId=1"
                        

It will continuously make one request per second. Run the test client without arguments to get a list of possible arguments, you can use it as a full time stamp client to get real document time stamps.

java -jar timeStampClient.jar
 -instr <string>      String to be time stamped, if neither instr or
                      infile is given, the client works in test-mode generating it's own
                      message.
 -base64              Give this option if the stored request/reply should
                      be base64 encoded, default is not.
 -help                Print this message.
 -infile <file>       File containing message to time stamp.

...snip...
                        
*** Manual Tests ***

The time stamp signer have been tested with the OpenTSA client with both HTTP and HTTPS.

Miscellaneous

Timed Services

A Timed Service (formerly called just service) is a task that is run on a timely basis, performing maintenance tasks like changing active key, or it could generate a report.

A Timed Service framework supports a couple basic properties that is used to calculate when and how a timed service should run. These properties are:

ACTIVE = "TRUE" if the service should be run, otherwise it is disabled.

SINGLETON = "TRUE" if the service only should be run on one of the nodes in the cluster at the time. If it's not set or set to FALSE is the service run simultaneously on all nodes in the cluster. If the node running a singleton service fails will another node sense this and start up the service.

INTERVAL = Property defining the interval in seconds the service should run.

INTERVALMS = Property defining the interval in milliseconds the service should run. Notice that the platform and application server might put a lower bound on the value. The lower limit for GlassFish is by default 7000 milliseconds but can be changed by editing minimum-delivery-interval-in-millis in domain.xml.

CRON = Property that should define a CRON expression of how often the service should run. It should conform to Unix CRON standard. (One and only one of INTERVAL, INTERVALMS or CRON is required)

SignerStatusReportTimedService

*** Overview ***

The SignerStatusReportTimedService is a timed service that outputs status for a set of workers to a file. The information includes each workers crypto token status ACTIVE/OFFLINE and if available also the numbers of signatures that has been performed with the key currently associated with the worker. If the worker has a configured limit of number of signatures, this value is also included.

Format:

workerName=WORKERNAME1, status=STATUS1, KEY3=VALUE3, KEY4=VALUE4, ...
workerName=WORKERNAME2, status=STATUS2, KEY3=VALUE3, KEY4=VALUE4, ...
workerName=WORKERNAME3, status=STATUS3, KEY3=VALUE3, KEY4=VALUE4, ...
...
                        

Rules:

  • Each line contains a set of properties for one worker.
  • Lines are separated by a system dependent newline character (CR, LF or CRLF).
  • Properties are of form KEY=VALUE and are separated by a comma and a space (", ").
  • The properties "workerName" and "status" are the only ones that must be present.
  • The property "workerName" is always the first property.

Properties:

  • workerName: name of the worker. Example: "sod71" or "sod72"
  • status: status of the worker's crypto token and key. Either "ACTIVE" or "OFFLINE".
  • validityNotBefore: the first date the signer is allowed to sign. Format is java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss z").
  • validityNotAfter: the last date the signer is allowed to sign.
  • signings: the number of signatures that has been performed with the key used by this worker.
  • signLimit: the maximum number of signatures this worker is allowed to perfom or -1 if there is no limit.

Examples:

workerName=Sod71, status=ACTIVE, validityNotBefore=2010-07-05 17:32:36 CEST, validityNotAfter=2010-09-08 17:32:36 EEST, signings=132, signLimit=100000,
workerName=Sod72, status=OFFLINE, validityNotBefore=2010-07-05 17:32:33 CEST, validityNotAfter=2010-09-08 17:32:33 EEST, signings=100000, signLimit=100000,
workerName=Sod73, status=OFFLINE, validityNotBefore=2010-07-05 17:32:33 CEST, validityNotAfter=2010-09-08 17:32:33 EEST, signings=0, signLimit=100000,
workerName=Sod74, status=OFFLINE,
                        

Examples explained:

Sod71 has done 132 signings and is ACTIVE and validityNotAfter indicates that it can continue to sign until 8th September if not the sign limit is reached before

Sod72 has performed all of its 100000 signings and can not sign until it gets a new key and certificate.

Sod73 has not reached its limit and is still in validity time but is OFFLINE for some other reason.

Sod74 is OFFLINE and has no certificate configured.

*** Available Properties ***

WORKERS = Comma separated list of worker names (signers) that should be monitored.

OUTPUTFILE = File that the information will be written to. If the file exists the content will be overwritten. The application server needs to have write access to this file when the service is executed.

Installing a service

To install a service you use the same commands as for installing a worker:

bin/signserver.sh setproperties configuration.properties
                    

Example:

> bin/signserver.sh setproperties doc/sample-configs/qs_signerstatusreport_configuration.properties

Using Glassfish JNDI provider...
===========================================
  Executing Command on host : localhost
===========================================
Configuring properties as defined in the file : doc/sample-configs/qs_signerstatusreport_configuration.properties
Setting the property ACTIVE to TRUE for worker 2
Setting the property INTERVAL to 10 for worker 2
Setting the global property WORKER2.CLASSPATH to org.signserver.server.timedservices.SignerStatusReportTimedService with scope GLOB.
Setting the property WORKERS to PDFSigner1 for worker 2
Setting the property NAME to SignerStatusReporter for worker 2
Setting the property OUTPUTFILE to /tmp/statusreport for worker 2

> bin/signserver.sh reload 2

Using Glassfish JNDI provider...
===========================================
Executing Command on host : localhost
===========================================
SignServer reloaded successfully
Current configuration is now activated.
                    

The Global Configuration Store

The available workers and its crypto tokens and services is configured in something called the global configuration store that is slightly different from a worker configuration.

Is is dynamically configured and activated immediately. I can contain any type of data (in string representation) and can be of two types, either with global scope or node scope. A Global scoped property can be accessed by all nodes in the cluster while a Node scoped property in only used within a node and cannot be accessed by the other nodes.

SignServer specific

Database failure is handled differently. If a node looses connection to the database it put itself in a state called 'unsynchronised' and will continue its operation without storing the data to database by using a cached global configuration. It is possible to later resynchronise one nodes cached global configuration data with the database with a CLI command called 'resync'. But it is only possible to sync one of the nodes global configuration to the database.

Status Repository

The status repository holds local (per JVM) status information (properties) with optional expiration times. After the expiration time the property is not returned.

This could be used by having workers read status from the repository while it is an external service updating it.

Logging

SignServer uses Log4j for logging and there are a few different loggers available where the first two can be useful for audit logging:

  • Worker Log (org.signserver.server.log.IWorkerLogger)
  • System Log (org.signserver.server.log.ISystemLogger)
  • Debug Log (any other class name)

Worker Log

The purpose of the Worker Loggers are to log each transaction handled by the worker. Each worker can choose to have its own configuration for the logger. By default the AllFieldsWorkerLogger is used which used logs all the available fields one after each other separated by semi colons.

Which Worker Logger configuration to use is configured by setting the WORKERLOGGER property to the full class name of the IWorkerLogger implementation in the worker's configuration. Examples:

WORKERLOGGER=org.signserver.server.log.AllFieldsWorkerLogger
                    
WORKERLOGGER=org.signserver.module.tsa.CustomTimeStampLogger1
                    
WORKERLOGGER=org.signserver.server.log.PatternWorkerLogger
LOGTIMEZONE=GMT
LOGDATEFORMAT=yyyy-MM-dd:HH:mm:ss:z
LOGPATTERN=\$\{(.+?)\}
LOGORDER=AUDIT; LOG_ID: ${LOG_ID}; CLIENT_IP: ${CLIENT_IP}; REQUEST_FULLURL: ${REQUEST_FULLURL}; RequestTime: ${LOG_TIME}; ResponseTime: ${REPLY_TIME}; EXCEPTION: ${EXCEPTION};
                    

System Log

The System Logger is instead for logging all other audit events that are not associated with a particular worker. The default System Logger is the AllFieldsSystemLogger that logs all the available fields one after each other separated by semi colons.

Debug Log

The debug log is just the normal log that can be useful for finding out configuration problems etc.

Configure Log4j for Audit logs

For JBoss you can configure JBOSS_HOME/server/default/conf/jboss-log4j.xml to put the audit logs in a separate file.

<appender name="SIGNSERVER_AUDIT" class="org.jboss.logging.appender.DailyRollingFileAppender">
    <errorHandler class="org.jboss.logging.util.OnlyOnceErrorHandler"/>
    <param name="File" value="${jboss.server.log.dir}/signserver_audit.log" />
    <param name="Append" value="true" />

    <!-- Rollover at midnight each day -->
    <param name="DatePattern" value="'.'yyyy-MM-dd" />
    <layout class="org.apache.log4j.PatternLayout">
        <param name="ConversionPattern" value="%d %-5p [%c] %m%n" />
    </layout>
</appender>

<category name="org.signserver.server.log.ISystemLogger">
    <appender-ref ref="SIGNSERVER_AUDIT"/>
</category>
<category name="org.signserver.server.log.IWorkerLogger">
    <appender-ref ref="SIGNSERVER_AUDIT"/>
</category>
                    

Installation Packages

From version 3.1 and upwards will there be binary installation packages released alongside the regular source packages. The packages includes all software necessary except for Java, were JDK 1.6+ is required.

At the current moment are the platforms Linux (mainly Debian distribution is tested but it should work for other distributions as well) and Windows XP/2003 supported. The SignServer have two packages, one server part that should be installed in every node in the cluster and one management package containing the CLI.

Using the Installation Packages

The installation package can be used either by using a GUI or on the command line by specifying the argument '-mode text'

For an advanced set-up, for instance if many nodes should be installed with similar configuration, it is possible to preconfigure the installation by specifying a properties file containing some or all the properties asked during the installation. The properties will be used directly during installation and there will be no questions about it. See each package section for details about supported properties.

The configuration file should be in the following locations:

Unix SignServer Installation            : /etc/signserver/signserver.conf
Windows SignServer Installation         : %SYSTEMROOT%\signserver.conf
                                         (i.e C:\WINDOWS\signserver.conf)
                    

After installation will all the settings be saved to the configuration file by the installation program to simplify re-installation.

If all necessary properties is given in the property file, it's possible to install the package silently by specifying '--mode unattended' on the command line.

*** SignServer Node ***

The server part of the SignServer package contains everything (except Java) that is needed to set-up a node in a cluster. It contains a preconfigured version of JBoss that is ready to use.

The steps performed during the installation process are:

Unix:

  • By default is everything unpacked in /opt/signserver-<version> .
  • If a /etc/signserver/signserver.conf file exists, it's read and used during installation.
  • The user and group 'signserver' is created
  • JBoss init.d script is configured to run at runlevel 3,4,5
  • Directory /etc/signserver/ is created to contain all configuration files
  • Database configuration file /etc/signserver/database-conf.xml is populated.
  • Log configuration file /etc/signserver/log-conf.xml is populated and configured to log to the directory /var/log/signserver
  • If no HTTP SSL certificate is specified in the configuration file will dummy key stores be generated to /etc/signserver.
  • Tomcat is configured for HTTPS and it's configuration file is placed in /etc/signserver/webserver-conf.xml
  • Finally is Jboss started and ready to be used.

Windows:

  • By default is everything unpacked in C:\Program\SignServer\SignServer-<version> .
  • If a c:\WINDOWS\signserver.conf file exists it's read and used during installation.
  • JBoss is configured to be run as a service that is started automatically.
  • Database configuration file <INSTALLDIR>\database-conf.xml is populated.
  • Log configuration file <INSTALLDIR>\log-conf.xml is populated and configured to log to the default directory <INSTALLDIR>\jboss\server\default\log
  • If no HTTP SSL certificate is specified will dummy key stores be generated to <INSTALLDIR>
  • Tomcat is configured for HTTPS and it's configuration file is placed in <INSTALLDIR>\webserver-conf.xml
  • Finally is Jboss started and ready to be used.

The supported properties in the configuration file /etc/signserver/signserver.conf (or %SYSTEMROOT%\signerserver.conf for windows) are:

Property Name Description Example value Where to manually reconfigure
SIGNSERVER_NODEID A unique string value (containing alphanumeric characters only) identifying the node in a cluster. node1 Unix: /etc/signserver/signserver.conf
Windows:
%Systemroot%\signserver.conf
database.type Type of database, currently are Hypersonic, Mysql, Mysql Cluster, Postgres and MS SQL 2000 supported hsqldb, mysql, mysqlndb, postgres, mssql2000 Unix:
/etc/signserver/database-conf.xml
Windows: %Installdir%\database-conf.xml
database.hosts The hostnames of the databases used. (not used for hsqldb). localhost Unix:
/etc/signserver/database-conf.xml
Windows: %Installdir%\database-conf.xml
database.port The port of the database (not used for hsqldb). 1433 Unix:
/etc/signserver/database-conf.xml
Windows: %Installdir%\database-conf.xml
database.name The name of the database (not used for hsqldb). signserver Unix:
/etc/signserver/database-conf.xml
Windows: %Installdir%\database-conf.xml
database.username The username used for authentication against the database (not used for hsqldb). signserver Unix:
/etc/signserver/database-conf.xml
Windows: %Installdir%\database-conf.xml
database.password The password used for authentication against the database (not used for hsqldb). foo123 Unix:
/etc/signserver/database-conf.xml
Windows: %Installdir%\database-conf.xml
httpserver.hostname Hostname used as CN in generated SSL Server certificate. host1.someorg Only used during the of SSL Server certificate generation phase of installation.
httpserver.storepath Path to the key store (JKS file) containing the SSL server certificate. /etc/signserver/tomcat.jks Unix:
/etc/signserver/webserver-conf.xml
Windows: %Installdir%\webserver-conf.xml
httpserver.password Password to unlock the SSL server certificate key store. foo123 Unix:
/etc/signserver/webserver-conf.xml
Windows: %Installdir%\webserver-conf.xml
httptrust.storepath Path to the key store (JKS file) containing the CA trust store. /etc/signserver/truststore.jks Unix:
/etc/signserver/webserver-conf.xml
Windows: %Installdir%\webserver-conf.xml
httptrust.password Password unlocking the CA truststore. foo123 Unix:
/etc/signserver/webserver-conf.xml
Windows: %Installdir%\webserver-conf.xml
syslog.hostname Host name of the Syslog server. This setting also indicates that Syslog should be used. loghost.someorg.org Unix:
/etc/signserver/log-conf.xml
Windows: %Installdir%\log-conf.xml
*** SignServer Management ***

This package installs the CLI interface on the management station (which can be the same as a node). The following steps are performed during installation:

Unix:

  • By default is everything unpacked in /opt/signserver-<version> .
  • If a /etc/signserver/signserver.conf file exists it's read and used during installation.
  • The user and group 'signserver' is created
  • A link from /opt/signserver-<version>/bin/signserver.sh is done to /usr/local/bin.

Windows:

  • Everything is unpacked in C:\Program\SignServer\SignServer-<version> by default.
  • If a c:\WINDOWS\signserver.conf file exists it's read and used during installation.

The signserver.conf supports the following settings:

Property Name Description Example value Where to manually reconfigure
hostname.masternode Hostname of master node in the cluster. node1.someorg.org Unix:
/etc/signserver/signserver.conf
Windows: %Installdir%\signserver.conf
hostname.allnodes Hostname of all hosts in cluster, separated by ';'. node1.someorg.org;node2.someorg.org Unix:
/etc/signserver/signserver.conf
Windows: %Installdir%\signserver.conf

Generating Installation Packages

Before generating a installation package must Bitrock InstallBuilder be installed on a Linux workstation. Then set the build mode in signserver_build.properties and go to src/install/bitrock. If a SignServer package should be generated must the environment variable JBOSS_PREP point the a prepared JBoss installation that will be included in the package.

Then execute the script './buildsignserverpkgs.sh <version>' to start the generation process. The packages will be generated in BitRocks default output directory.

References

How To

Setting up an Apache Web Server as a proxy in front of SignServer

This section will show you how to use an Apache Web Server Proxy in front of SignServer.
The resulting server will

  • Make the TSA available through the nice url http://tsa.company.com/

This example was created on Ubuntu 64-bit Server 8.10 using the Apache Web Server 2.2 package, but should be easy to adapt to any system able to run Apache.

Start by installing SignServer as normal. If you intend to have the CA on the same machine as the proxy you should modify $SIGNSERVER_HOME/signserver_build.properties to only listen to localhost

httpsserver.bindaddress.pubhttp=127.0.0.1
httpsserver.bindaddress.pubhttps=127.0.0.1
httpsserver.bindaddress.privhttps=127.0.0.1

Install the Apache web server and enable required modules:

$sudo su
#apt-get install apache2
#cd /etc/apache2/mods-enabled/
#ln -s ../mods-available/proxy.load proxy.load
#ln -s ../mods-available/proxy_http.load proxy_http.load
#ln -s ../mods-available/rewrite.load rewrite.load

A sample configuration how to fix up nice URLs for OCSP so that you can point your TSA clients to http://tsa.company.com/ instead of http://tsa.company.com:8080/signserver/process?workerId=1.
This configuration combines mod_proxy with mod_rewrite to be able to set the workerName or workerId, so you can have different TSAs available on different URLs.

<VirtualHost tsa.company.com:80>
ServerName tsa.company.com
ServerAlias tsa.company.com
CustomLog /var/log/apache2/access.log combined

RewriteEngine on
RewriteLogLevel 5
RewriteLog "/var/log/apache2/rewrite.log
RewriteRule ^/$ /?workerName=TSA [PT]

ProxyRequests Off
<Proxy *>
  Order deny,allow
  Allow from all
</Proxy>
ProxyPass / http://127.0.0.1:8080/signserver/process
ProxyPassReverse / http://127.0.0.1:8080/signserver/process
</VirtualHost>

Setting up an Apache Web Server with mod_jk in front of SignServer

Instead of using a mod_proxy you can use mod_jk which uses a JK connector between apache and tomcat. You can easily combine it with mod_rewrite to change URLs.

This section will show you how to use an Apache with mod_jk in front of SignServer. mod_jk have many features and by using it you can virtually do anything you want with hosts, ports and URLs.

This example was created on Ubuntu 64-bit Server 8.10 using the Apache Web Server 2.2 package, but should be easy to adapt to any system able to run Apache.

# sudo apt-get install apache2 libapache2-mod-jk
# vim /etc/libapache2-mod-jk/workers.properties
-----
worker.list=jboss

# Define a worker using ajp13
worker.jboss.port=8009
worker.jboss.host=127.0.0.1
worker.jboss.type=ajp13
-----
# cd /etc/apache2/mods-enabled
# ln -s ../mods-available/rewrite.load rewrite.load
# vim /etc/apache2/sites-available/tsa.primekey.se
-----
<VirtualHost tsa.company.com:80>
ServerAdmin webmaster@company.com
ServerName tsa.company.com
ServerAlias tsa.company.com

JkLogFile /var/log/apache2/mod_jk.log
JkLogLevel debug
JkMount /* jboss
JkMount / jboss
</VirtualHost>
-----
# vim /etc/apache2/mods-available/jk.load
-----
LoadModule /usr/lib/apache2/modules/mod_jk.so
JkWorkersFile /etc/libapache2-mod-jk/workers.properties
-----

Finally restart apache and you can run:

$ bin/client.sh timestamp http://tsa.company.com/signserver/process?workerName=TSA