Click the PKI-by-PrimeKey-SignServer-logo to visit www.signserver.org
Search signserver.org for:
Click here to learn about PrimeKey Support Services!

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 it 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

Major changes from previous versions

Changes between version 3.5 and 3.6

  • Underlaying CESeCore library upgraded to version 6.1
  • Separation between community and enterprise editions
  • Separate worker and crypto tokens
  • New application: SignServer TimeMonitor (enterprise edition)
  • Querying of database archive from WS and GUI
  • HSM keep alive service

Changes between version 3.4 and 3.5

  • Support for JBoss AS 7.1, JBoss EAP 6.1 and GlassFish 3.1
  • Support for MariaDB
  • Support for JDK 7
  • All worker configuration can now be done from the Admin GUI
  • Document signer and validator for XAdES-BES and XAdES-T
  • Support for different signature algorithms in XML signers
  • Various AdminGUI/remote administration improvements
  • Support for the group key framework has been discontinued

Changes between version 3.3 and 3.4

  • Secure logging to database from CESeCore
  • Query audit log from CLI, GUI or over web services
  • See ChangeLog.txt and RELASE_NOTES.txt for details.

Changes between version 3.2 and 3.3

  • New client web services API
  • MS Authenticode time-stamp signer
  • Support for archiving of time-stamp requests
  • Logging of all changes to service components
  • Stress test tool for measuring performance
  • Dropped support for JBoss 4.2.x.
  • Dropped support for cluster class loader
  • Dropped support for WSRA
  • Upgrade of cryptographic library
  • Many more minor changes and bug fixes. See ChangeLog.txt and RELASE_NOTES.txt for details.

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. Each worker can contain a crypto token or reference a crypto token from an other worker.
Crypto Worker Is a worker not performing any operations on its own and instead only hosts a Crypto Token that can be referenced by other workers.
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.
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)
XAdES Signer A Signer signing XML documents using XAdES
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.
Archiver Implementation handling archiving of a worker's response and/or request 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. 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.

The main way of communicating with the SignServer is through HTTP (web server) interface. There is also a web services (SOAP WS) interface available but that uses a special binary format for encoding the requests and responses.

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 6: OpenJDK 6 or Oracle JDK 6 Update 10 or later*
    Java 7: OpenJDK 7** or Oracle JDK 7*
  • Application server: JBoss 5.1.0.GA***, JBoss EAP 5.1, JBoss AS 7.1.1, JBoss EAP 6.1 or GlassFish Server Open Source Edition 2.1.1 or 3.1.2
  • Database: MySQL or MariaDB 5.5, HypersonicSQL (bundled with JBoss 5), Oracle Database 10/11g or without****
  • Build tool: Apache Ant 1.8.0 or later

* When using Oracle JDK you must install the 'Unlimited Strength Jurisdiction Policy Files' for JDK for the parts of SignServer that makes use of strong crypto to work. The policy files can be found at the same place as the JDK download at Oracle. Further information on this can be found in the Oracle documentation on the JCE.
** If the application server supports JDK 7. Works for GlassFish 3 and JBoss 7/EAP 6.
*** JBoss 5.1.0.GA is available in two different versions (standard and JDK6) which differs in web services stacks. The one called JBoss 5.1.0.GA-JDK6 should be used.
**** See SignServer without Database

2. Unpack SignServer

Download and unzip the latest SignServer release archive from SourceForge or for the absolutely 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 (/opt/jboss could be a symbolic link).

export APPSRV_HOME=/opt/jboss
                        
*** 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

Skip this section and instead follow the instructions in SignServer without Database if you decide to run SignServer without a database management system.

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/sql-scripts/create-tables-signserver34-*.sql.

*** MariaDB binlog format configuration ***

For MariaDB you will have to set binlog_format to "row", for instance in /etc/mysql/my.cnf:

binlog_format=row
                        
*** Configure database driver for JBoss 5 or GlassFish ***

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

*** Configure database driver for JBoss AS 7 or JBoss EAP 6 ***

In JBoss 7/EAP6 it is not enough to just drop the JAR archive with a database JDBC driver into the deployments directory. Instead you will have to perform the following steps (for MySQL or MariaDB):

  1. Create the necessary directories (relative to JBoss 7 base directory):
    On JBoss 7.1.1 or EAP 6.0:
    mkdir -p modules/com/mysql/main/
    
    On JBoss 7.2 or EAP 6.1:
    mkdir -p modules/system/layers/base/com/mysql/main/
    
    Or for MariaDB, mariadb-java-client-1.1.2.jar:
    mkdir -p modules/org/mariadb/main/
    
    On JBoss 7.2 or EAP 6.1:
    mkdir -p modules/system/layers/base/org/mariadb/main/
    
  2. Place the mysql.jar or mariadb.jar file in the directory you just created.
  3. Create, in the created directory, the JDBC module configuration file module.xml with the following contents (replace mysql.jar with the full name of your jar file for example mysql-connector-java-5.1.18-bin.jar):
    <?xml version="1.0" encoding="UTF-8"?>
    <module xmlns="urn:jboss:module:1.0" name="com.mysql">
      <resources>
        <resource-root path="mysql.jar"/>
      </resources>
      <dependencies>
        <module name="javax.api"/>
        <module name="javax.transaction.api"/>
      </dependencies>
    </module>
    
    
    Or for MariaDB, mariadb-java-client-1.1.2.jar:
    <?xml version="1.0" encoding="UTF-8"?>
    <module xmlns="urn:jboss:module:1.0" name="org.mariadb">
      <resources>
        <resource-root path="mariadb-java-client-1.1.2.jar"/>
      </resources>
      <dependencies>
        <module name="javax.api"/>
        <module name="javax.transaction.api"/>
      </dependencies>
    </module>
    
  4. Register the driver by running the following two commands in the JBoss 7 CLI administration tool:
    /subsystem=datasources/jdbc-driver=com.mysql.jdbc.Driver:add(driver-name=com.mysql.jdbc.Driver,driver-module-name=com.mysql,driver-xa-datasource-class-name=com.mysql.jdbc.jdbc.jdbc2.optional.MysqlXADataSource)
    :reload
    
    Or for MariaDB, mariadb-java-client-1.1.2.jar:
    /subsystem=datasources/jdbc-driver=org.mariadb.jdbc.Driver:add(driver-name=org.mariadb.jdbc.Driver,driver-module-name=org.mariadb,driver-xa-datasource-class-name=org.mariadb.jdbc.MySQLDataSource)
    :reload
    

For PostgreSQL you would use the following values instead:

<?xml version="1.0" encoding="UTF-8"?>
<module xmlns="urn:jboss:module:1.0" name="org.postgresql">
  <resources>
    <resource-root path="postgresql-9.1-903.jdbc4.jar"/>
  </resources>
  <dependencies>
    <module name="javax.api"/>
    <module name="javax.transaction.api"/>
  </dependencies>
</module>
/subsystem=datasources/jdbc-driver=org.postgresql.Driver:add(driver-name=org.postgresql.Driver,driver-module-name=org.postgresql,driver-xa-datasource-class-name=org.postgresql.xa.PGXADataSource)
:reload

*** Configure data source for JBoss 5 ***

This is done automagically by the SignServer build script later during "ant deploy".

*** Configure data source for GlassFish ***

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
*** Configure data source for JBoss AS 7.1 ***

The examples are for installing a MariaDB datasource using the jboss-cli with the driver installed as described above.

A normal datasource (Note: no --enabled=true for JBoss AS 7.1):

data-source add --name=signserverds --driver-name="org.mariadb.jdbc.Driver" --connection-url="jdbc:mysql://127.0.0.1:3306/signserver" --jndi-name="java:/SignServerDS" --use-ccm=true --driver-class="org.mariadb.jdbc.Driver" --user-name="signserver" --password="signserver" --validate-on-match=true --background-validation=false --prepared-statements-cache-size=50 --share-prepared-statements=true --min-pool-size=5 --max-pool-size=150 --pool-prefill=true --transaction-isolation=TRANSACTION_READ_COMMITTED --check-valid-connection-sql="select 1;"

Then restart the application server.

*** Configure data source for JBoss EAP 6 ***

The examples are for installing a MariaDB datasource using the jboss-cli with the driver installed as described above.

A normal datasource (Note: --enabled=true for JBoss EAP 6.x):

data-source add --name=signserverds --driver-name="org.mariadb.jdbc.Driver" --connection-url="jdbc:mysql://127.0.0.1:3306/signserver" --jndi-name="java:/SignServerDS" --use-ccm=true --driver-class="org.mariadb.jdbc.Driver" --user-name="signserver" --password="signserver" --validate-on-match=true --background-validation=false --prepared-statements-cache-size=50 --share-prepared-statements=true --min-pool-size=5 --max-pool-size=150 --pool-prefill=true --transaction-isolation=TRANSACTION_READ_COMMITTED --check-valid-connection-sql="select 1;" --enabled=true

Then restart the application server.

5. Configure web server keystores

*** JBoss 5 SSL configuration ***

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 and put it in a 'p12' subdirectory. Place a keystore called truststore.jks in the 'p12' directory containing the trusted root certificate(s).

*** GlassFish SSL configuration ***

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

*** JBoss 7/EAP 6 SSL configuration ***

Copy the keystore file as JBOSS7_HOME/standalone/configuration/keystore/keystore.jks and the trust store as JBOSS7_HOME/standalone/configuration/keystore/truststore.jks.

Configure interfaces using the approproate bind address (ie. 0.0.0.0 or 127.0.0.1).

/interfaces=/interface=http:add(inet-address="0.0.0.0")
/interfaces=/interface=httpspub:add(inet-address="0.0.0.0")
/interfaces=/interface=httpspriv:add(inet-address="0.0.0.0")
                        

Set-up the private port which requires client certificate. Use appropriate values for key-alias (hostname), password (keystore password), ca-certificate-password (truststore password), and supported protocols.

/socket-binding-group=standard-sockets/socket-binding=httpspriv:add(port="8443",interface="httpspriv")
/subsystem=web/connector=httpspriv:add(protocol=HTTP/1.1, scheme=https, socket-binding=httpspriv, secure=true)
/subsystem=web/connector=httpspriv/ssl=configuration:add(key-alias="localhost")
/subsystem=web/connector=httpspriv/ssl=configuration:write-attribute(name=password, value="serverpwd")
/subsystem=web/connector=httpspriv/ssl=configuration:write-attribute(name=certificate-key-file, value="${jboss.server.config.dir}/standalone/configuration/keystore/keystore.jks")
/subsystem=web/connector=httpspriv/ssl=configuration:write-attribute(name=verify-client, value=true)
/subsystem=web/connector=httpspriv/ssl=configuration:write-attribute(name=ca-certificate-password, value="changeit")
/subsystem=web/connector=httpspriv/ssl=configuration:write-attribute(name=ca-certificate-file, value="${jboss.server.config.dir}/standalone/configuration/keystore/truststore.jks")
/subsystem=web/connector=httpspriv/ssl=configuration:write-attribute(name=protocol,value="TLSv1,TLSv1.1,TLSv1.2") 
                        

Set-up the public SSL port which doesn't require the client certificate. Use appropriate values for key-alias (hostname), password (keystore password), and supported protocols.

/socket-binding-group=standard-sockets/socket-binding=httpspub:add(port="8442",interface="httpspub")
/subsystem=web/connector=httpspub:add(protocol=HTTP/1.1, scheme=https, socket-binding=httpspub, secure=true)
/subsystem=web/connector=httpspub/ssl=configuration:add(key-alias="localhost")
/subsystem=web/connector=httpspub/ssl=configuration:write-attribute(name=password, value="serverpwd")
/subsystem=web/connector=httpspub/ssl=configuration:write-attribute(name=certificate-key-file, value="${jboss.server.config.dir}/standalone/configuration/keystore/keystore.jks")
/subsystem=web/connector=httpspub/ssl=configuration:write-attribute(name=protocol,value="TLSv1,TLSv1.1,TLSv1.2")
                        

If the server is not so fast, we have to wait a little before we can reload, otherwise it will be bad

:reload
                        

6. Configure application server

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

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 5.1.0.GA the file is available under: server/default/deployers/jbossws.deployer/META-INF/

*** Fix web service problem in JBoss AS 7/EAP 6 ***

Configure WSDL web-host rewriting to use the request host. Needed for webservices to work correctly when requiring client certificate.

/subsystem=webservices:write-attribute(name=wsdl-host, value=jbossws.undefined.host)
/subsystem=webservices:write-attribute(name=modify-wsdl-address, value=true)
                        

If the server is not so fast, we have to wait a little before we can reload, otherwise it will be bad

:reload
                        
*** 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/ext/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.

*** JBoss 7 and Oracle JDK BouncyCastle issues ***

When using Oracle JDK and JBoss 7 you need to install BC jars as a module in JBoss 7. See JBAS-7882.

How to install modules are described in docs.jboss.org/author/display/MODULES/Defining+a+module.

*** Fix XML Security library issue in JBoss 5 ***

JBoss 5 bundles an older version of the XML Security library which conflicts with the one included in SignServer. Run the below Ant target to copy the SignServer version and its dependencies to the JBoss endorsed folder:

bin/ant j2ee:copy-xmlsec
                        
*** Fix XML Security library issue in JBoss 7 ***

JBoss 7 bundles version 1.5.1 of the XML Security library. The library bundled with SignServer is not properly overriding the JBoss-bundled version. To work around this issue copy the JAR file from SignServer into JBoss' modules directory.

On Linux/Unix systems the following command can be used:

cp lib/ext/xmlsec-1.5.7.jar $APPSRV_HOME/modules/org/apache/santuario/xmlsec/main/xmlsec-1.5.1.jar
						

On Windows systems the following command can be used:

copy lib\ext\xmlsec-1.5.7.jar %APPSRV_HOME%\modules\org\apache\santuario\xmlsec\main\xmlsec-1.5.1.jar
						
*** Install Hibernate in GlassFish 3 ***

If you are using GlassFish 3 and run with a database you will have to install Hibernate. Run pkg install in the GlassFish folder:

./bin/pkg install hibernate
                        
*** JBoss 7/EAP 6 and PKCS11 ***

JBoss 7/EAP 6 isolates away most sun classes. That means you will not be able to send certificates through remote EJB calls, and will not be able to use the Sun PKCS#11 provider. These classes can be made available by editing the file modules/sun/jdk/main/module.xml (JBoss 7.1/EAP6.0) and adding the following packages to the list of system export paths:

<path name="sun/security/x509"/>
<path name="sun/security/pkcs11"/>
<path name="sun/security/pkcs11/wrapper"/>
                        

This will allow an application to use these internal Sun/Oracle/OpenJDK classes.

This is not needed in JBoss EAP 6.1/JBoss 7.2, because the two first packages are exported by default since JBPAPP6-1748. One package is however needed still. In JBoss EAP 6.1 the file is located in modules/system/layers/base/sun/jdk/main/module.xml.

<path name="sun/security/pkcs11/wrapper"/>
                        

7. Configure build

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

cp conf/signserver_build.properties.sample conf/signserver_build.properties
                    
*** 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
clientws.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
                        

See Signed log for how to configure for signed audit logs in the database.

8. Build and deploy SignServer

Run "bin/ant build deploy" to build SignServer and deploy it to the selected application server.

bin/ant clean build deploy
                    

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

9. Accessing SignServer

After startup a few different user interfaces are available.

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


Current version of server is : SignServer 3.5.0alpha0
                    
*** Graphical User Interface ***
bin/signserver-gui
bin/signserver-gui -ws
						
*** 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 by setting properties using "setproperty" or "setproperties" etc.

*** 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 setproperties doc/sample-configs/CONFIGURATION.PROPERTIES
                        

After adding or changing a property for a worker (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 reload 4711
                    

Quick start demo setup

This is a quick start guide to quickly get you setup with a crypto token and a set of workers/signers for testing and demonstration purposes.

*** Setup a sample crypto token ***

Set up a crypto token called CryptoTokenSoft which uses a hard coded software keystore:

$ bin/signserver setproperties doc/sample-configs/soft-crypto-configuration.properties

Activate the configuration using the assigned worker ID that was printed (for instance 1):

$ bin/signserver reload 1
*** Add sample workers ***

Workers can then be set up using the setproperties followed by the reload command. Sample configurations are available in doc/sample-configs which by default uses the sample crypto token:

$ bin/signserver setproperties doc/sample-configs/CONFIGURATION.properties

Activate the configuration using the assigned worker ID that was printed (for instance 2):

$ bin/signserver reload 2

See the following section for some example for specific workers.

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. Setup the soft crypto token (if not already done) and activate it with its ID:
    $ bin/signserver setproperties doc/sample-configs/soft-crypto-configuration.properties
    $ bin/signserver reload 1
  3. Load the Timestamp demo configuration and notice the generated worker ID (in this example 2):
    $ bin/signserver setproperties doc/sample-configs/qs_timestamp_configuration.properties
  4. Activate the configuration with:
    $ bin/signserver reload 2
  5. You can check the status and configuration with:
    $ bin/signserver getstatus complete all
  6. Run the test client to see that everything is up:
    $ bin/signclient 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. Setup the soft crypto token (if not already done) and activate it with its ID:
    $ bin/signserver setproperties doc/sample-configs/soft-crypto-configuration.properties
    $ bin/signserver reload 1
  3. Load the PDF signer demo configuration and notice the generated worker ID (in this example 3):
    $ bin/signserver setproperties doc/sample-configs/qs_pdfsigner_configuration.properties
  4. Activate the configuration with:
    $ bin/signserver reload 3
  5. You can check the status and configuration with:
    $ bin/signserver 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 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 setproperties doc/sample-configs/qs_validator_dummy_configuration.properties
  2. Activate the configuration with:
    $ bin/signserver reload 6
  3. The status of the Worker can now be viewed with:
    $ bin/signserver 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 setproperties doc/sample-configs/qs_xmlvalidator_configuration.properties
  3. Verify the configuration with (notice that VALIDATIONSERVICEWORKER is set to "CertValidationWorker"):
    $ bin/signserver getconfig 7
  4. Activate the configuration with:
    $ bin/signserver reload 7
  5. The status of the Validator can now be viewed with:
    $ bin/signserver 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. Setup the soft crypto token (if not already done) and activate it with its ID:
    $ bin/signserver setproperties doc/sample-configs/soft-crypto-configuration.properties
    $ bin/signserver reload 1
  3. Load the MRTD SOD signer demo configuration and notice the generated worker ID (in this example 8):
    $ bin/signserver setproperties doc/sample-configs/qs_mrtdsodsigner_configuration.properties
  4. Activate the configuration with:
    $ bin/signserver reload 8
  5. The status of the signer can now be viewed with:
    $ bin/signserver 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 CryptoTokenSoft, make a copy of doc/sample-configs/pkcs11-crypto-configuration.properties and configure the necessary properties for the HSM and apply that file using setproperties and reload with its worker ID.
(note after changing properties in the file it needs to be loaded again with setproperties)

Now when configuring a worker make sure to have the worker property CRYPTOTOKEN=CryptoTokenP11.

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

bin/signserver setproperties doc/sample-configs/pkcs11-crypto-configuration.properties
bin/signserver reload 9
bin/signserver setproperties doc/sample-configs/qs_mrtdsodsigner_configuration.properties
bin/signserver setproperty 10 CRYPTOTOKEN CryptoTokenP11
bin/signserver reload 10
bin/signserver activatecryptotoken 9 tokenpin
bin/signserver generatecertreq 9 "C=SE,CN=MRTD SOD Signer" SHA256WithRSA mrtdsodsigner.req

Where 9 is the workerId that you got when running the 'setproperties' command for the pkcs11 crypto token.
Tokenpin is the password for the HSM slot configured in the properties file.
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 uploadsignercertificate 10 glob cert.pem
bin/signserver uploadsignercertificatechain 10 glob certchain.pem
bin/signserver 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

Upgrade

See SIGNSERVER_HOME/doc/RELEASE_NOTES.txt and UPGRADE.txt for information about upgrading from an earlier version of SignServer.

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 (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.

getproperty: List the value of a worker or global property.

Usage:

signserver getproperty <signerid | signerName | global | node> <propertykey>
                        

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. If DN components contains commas, these needs to be escaped with backslashes. Alternatively a certificate file (PEM or DER format) can be specified, from which the serial number and issuer DN is fetched.

Usage:

Example 1: signserver addauthorizedclient 1 EF34242D2324 "CN=Test Root CA"
Example 2: signserver addauthorizedclient 1 EF3456789ABC "CN=Client,O=Test Organization,C=SE"
Example 3: signserver addauthorizedclient 1 client.pem
                        

removeauthorizedclient: Removes added client certificate entries.

listauthorizedclients: Displays the current list of acceptable clients.

renewsigner: Sends a request for renewal of the specified worker to the specified renewal worker. If the authcode parameter is omitted the command prompts for the password. See also the section about the RenewalWorker.

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 chosen Archiver if it archives the data in way that it can be queried using this commands. For Archivers other than the default "OldDatabaseArchiver" and Base64DatabaseArchiver querying might have to be done directly in a database, filesystem 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 title as the archive id and with the file extension depending on the type of item, for instance ".request" or ".response".

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 title and the file extension depending on the type of item.

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 title and the file extension depending on the type of item.

archive query: Used to query contents of the archive. Actual archived data is not fetched by this command.

Usage:

signserver archive query -limit <number> [-criteria  \"<field> <op> <value>\" [-criteria...]] [-from <index>] [-header] [-request|-response]\n"
        + "<field> is a field name from the archive: archiveId, requestCertSerialNumber, requestIP, requestIssuerDN, signerid, time, type\n"
        + "<op> is a relational operator: GT, GE, LT, LE, EQ, NEQ, LIKE, NULL, NOTNULL\n"
	+ "-request shows only entries for requests\n"
	+ "-response shows only entries for responses\n"
        + "Example: signserver archive query -limit 10 -criteria \"signerid EQ 1\"\n"
	+ "Example: signserver archive query -limit 10 -criteria \"signerid EQ 1\" -request\n"
        + "Example: signserver archive query -limit 10 -criteria \"time GT 1359623137000\" -criteria \"requestIP EQ 127.0.0.1\n"
        + "Example: signserver archive query -limit 10 -criteria \"signerid EQ 1\" -outpath /tmp/out\n\n"
			

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 (in hexadecimal) and issuer DN with space after each comma separating DN components. If DN components contains commas, these needs to be escaped with backslashes.

An example on how to enter the issuer DN when using a certificate issued from EJBCA with the default (as specified by EJBCA) LDAP DN order:

C=SE, O=TestOrganization, CN=IssuingCA

An example using escaped DN components

C=SE, O=TestOrganization\, The, CN=IssuingCA\, The

This is the reversed order compared to how the issuer DN is stored in the certificate.

An example on how to enter the issuer DN when using a certificate issued from EJBCA with the Use LDAP DN order option disabled:

CN=ReverseIssuingCA, O=TestOrganization, C=SE

Alternatively a certificate file can be specified, from which the serial number and issuer DN will be taken.

Samples:

Example 1: signserver wsadmins -add -certserialno 123ABCDEF -issuerdn "CN=Neo Morpheus, C=SE"
Example 2: signserver wsadmins -add -cert wsadmin.pem
                        

wsadmins -remove:

Removes an administrator from the list of authorized administrators.

wsadmins -allowany:

Sets whether any administrator with a certificate accepted by the web server/proxy is authorized or not. When set (true) it overrides the WSADMINS global property. Takes an optional boolean parameter, if left out sets to true (allow all). This can be used for initial setup.

Auditors Related

wsauditors -list:

Lists auditor certificates (certificate serial number and issuer DN) for administrators authorized to use the Admin Web Service interface to query the audit log of SignServer.

wsauditors -add:

Authorizes an auditor to use the Admin Web Service interface by certificate serialnumber (given in hexadecimal) and issuer DN.

wsauditors -remove:

Removes an auditor from the list of authorized administrators.

Archive Auditors Related

wsarchiveauditors -list:

Lists archive auditor certificates (certificate serial number and issuer DN) for auditors authorized to use the Admin Web Service interface to query the archive of SignServer.

wsarchiveauditors -add:

Authorizes an auditor, by specifying a certificate serial number (in hexadecimal) and issuer DN, to use the Admin Web Service interface for querying the archive.

wsarchiveauditors -remove:

Removes an auditor from the list of authorized archive auditors.

auditlog -query:

Query the CESeCore audit log.

Usage:

signserver auditlog -query -limit <number> [-criteria  "<field> <op> <value>" [-criteria...]] [-from <index>] [-header]
                        

-limit sets the maximum number of rows matched, this option is required to avoid putting too much load on the server.

<field> is a field name from the audit log: additionalDetails, authToken, customId, eventStatus, eventType, module, nodeId, searchDetail1, searchDetail2, sequenceNumber, service, timeStamp.

<op> is a relational operator: GT, GE, LT, LE, EQ, NEQ, LIKE, NULL, NOTNULL

When given the -header option, a column header is outputted before the results.

If databaseprotection.enableverify is enabled at the server side the signature of each row displayed are verified. If the verification fails for any of the rows matching the search criteria, an error message is displayed. The error message contains information about the first row that failed.

Database CLI

Note
This is a SignServer Enterprise Edition (EE) feature.

The SignServer Database CLI uses Java Persistence API (JPA) to connect to the SignServer database. The CLI is configured by the dbcli.* properties in signserver_cli.properties.

The CLI needs to have the JDBC driver of the selected database available on the classpath. This can be achieved by setting the OPTIONAL_CLASSPATH environment variable when calling the bin/signserver-db script or by putting the JAR under lib/ext/jdbc/ and calling it jdbc.jar. The last method is required to be able to run the JUnit tests.

Sample usage:

bin/signserver-db audit
                    
*** Verify Auditlog Command ***
Usage: verifylog -all
       verifylog [-node NODENAME[:OFFSET] ...]

Verifies logs from all nodes starting at sequence number 0 or only from the specified nodes and optional sequence number offsets specified.
If the nodename is suffixed with a colon and an number then the verification for that node is started from that sequence number.
The JDBC connector of the database might have to be put on the classpath. See the example below.

Example: a) signserver-db audit verifylog -all
Example: b) signserver-db audit verifylog -node server1 -node server2:708
Example: c) OPTIONAL_CLASSPATH=/usr/share/java/mysql-connector-java.jar signserver-db audit verifylog -all
                        

The command can be run to verify the signature of every entry in the auditlog as well as checking the sequence number in order to make sure that it does not contain any gaps.

The keys used to verify the log are configured in conf/databaseprotection.properties.

Sample output:

2013-07-04 15:29:10,073 INFO  [VerifyLogCommand] The following nodes exists: [server1, server2]
2013-07-04 15:29:10,074 INFO  [VerifyLogCommand] Start sequences: {server1=0, server2=0}
2013-07-04 15:29:10,635 INFO  [SoftCryptoToken] Invalid authentication code. Token id=400.
2013-07-04 15:29:10,716 INFO  [SoftCryptoToken] Activated Crypto Token with id 400.
2013-07-04 15:29:10,722 INFO  [VerifyLogCommand] Progress: node=server1 rowCount=3
2013-07-04 15:29:10,722 INFO  [VerifyLogCommand] Last sequence number: 2
2013-07-04 15:29:10,745 INFO  [VerifyLogCommand] Progress: node=server2 rowCount=11
2013-07-04 15:29:10,745 INFO  [VerifyLogCommand] Last sequence number: 7
2013-07-04 15:29:10,747 INFO  [VerifyLogCommand] Audit log validation completed in 0 seconds. 11 rows found. Errors: 0 Warnings: 0
2013-07-04 15:29:10,747 INFO  [VerifyLogCommand] Verification finished with success
2013-07-04 15:29:10,747 INFO  [VerifyLogCommand] Last sequences: {server1=2, server2=7}
                        
*** Archiving of the audit log ***

As the Database CLI audit verifylog command checks for gabs in the sequence numbering entries from the audit log can not be archived/moved to other storage without special care. However since the command now supports the option to specify from which sequence number to start the verification the following scheme for archiving is proposed:

  1. Run the command to verify the complete log audit log:
    audit verifylog -all
    Note down the last sequence number for each node. Ie:
    Last sequences: {server1=2, server2=7}
  2. All entries from 0 up to the entry before the last can now be archived and removed from the database. In our example that would be entry 0 and 1 for node server1 and entries from 0 to 6 for node server2.
  3. The next time the log should be verified start the verification from the last sequence numbers:
    audit verifylog -node server1:2 -node server2:7
    Again note down the last sequence number for each node and all entries up to the sequence number before the last for each node can now be archived.
Note
It is important to not remove the row with the last sequence number for any node as if the application is restarted the sequence numbering would than start again from 0 for that node.

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 is built by default (unless the property admingui.enabled is set to the value "false" in signserver_build.properties), and can be started using the script bin/signserver-gui.

On startup, the connect to SignServer dialog offers the possibility to either connect to a locally running SignServer instance or a remote one over web services. If the "-ws" command line option is specified the later option is already selected when the dialog opens.

See also the Admin GUI troubleshooting section.

*** Connect to SignServer dialog ***

First select either to connect to a local or remote instance. If a remote one is selected then also specify URL to SignServer server as well as keystore and truststore for setting up the HTTPS connection. Then click the button Connect. By clicking the button Load defaults the settings from the file default_connect.properties is loaded. The current settings are stored to connect.properties and displayed the next time the dialog is openned.

Connect to: Select to either connect to a "Local SignServer" using the EJB interface or a "Remote SignServer" using web services on the specified URL.

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 path 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 -> Add Worker/Load Configuration?: Opens the dialog to import a configuration or set-up a worker manually by specifying worker parameters. When selecting "Load from file" it is possible to load a configuration file. This is equivalent of the "setproperties" Admin CLI command. Selecting "Add worker" enables setting up a worker from scratch by manually specifying a worker ID (the default selected will generate an ID dynamically), worker name, fully qualified class name for the implementation, and (optionally) a signer token implementation. Additional properties can be added using the table below. When the required parameters are given, the "Next" button will enable moving to the next step where additional manual editing of the resulting configuration can be made (the format is the same as the worker properties files). Clicking the "Apply" button from this stage will load the current configuration. The dialog can be dismissed in both states using the "Cancel" button.

File -> Export...: Opens the Export configuration dialog. This is the equivalent of the "dumpproperties" Admin CLI command. The dialog gives the option to export all workers, the selected workers or none. In addition it also gives the option to include all global configurations not related to any worker (always enabled if no workers choosen for export).

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 -> Destroy key...: Opens the Remove key dialog for the selected worker and asks for a key to remove from the crypto token.

Edit -> Remove worker...: Removes the selected workers from the SignServer configuration.

Edit -> Reload from database...: Reloads the global configuration or the selected workers from the database. This is only needed if the configuration was changed from an other node and the nodes uses a shared database.

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

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

Allows adding webservice administrators, auditors, and archive auditors. The administrators can be added by explicitly entering the client certificate's serial number in hexadecimal (leading zeroes and letter case is not significant) and the issuer DN with space after each comma separating DN components. If DN components contains commas, these needs to be escaped with backslashes.

An example using a certificate issued from EJBCA with the default (as specified by EJBCA) LDAP DN order:

C=SE, O=TestOrganization, CN=IssuingCA

This is the reversed order compared to how the issuer DN is stored in the certificate. An example using a certificate issued from EJBCA with the Use LDAP DN order option disabled:

CN=ReverseIssuingCA, O=TestOrganization, C=SE

Alternatively a certificate file can be loaded, from which the serial number and issuer DN will be taken.

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.

Specify certificate serial number in hex and the Issuer DN of the client certificate. If DN components contains commas, these needs to be escaped with backslashes. Alternatively a certificate file (PEM or DER format) can be loaded, from which the serial number and issuer DN is fetched.

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. If the checkbox "Allow any administrator with a valid certificate..." is selected, any user with a valid certificate will be authorized. Having this enabled will override the administrators added in the list above. This is meant primarily for allowing a temporary certificate for setting up initial configuration.

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. The "..." button can be used to read the values for serial number and issuer DN from a certificate file in PEM or DER format.

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.

*** Main window: Audit log ***

In the "Audit log" tab controls for querying and filter the audit log exists.

  • Current conditions: Lists query conditions used to filter the search results.
  • Add: Opens a dialog box for adding query conditions.
  • Remove: Removes the selected query condition.
  • First: Go to the first search results page.
  • Previous: Go to the previous search results page.
  • Reload: Loads or reloads the search result according the the current search condition(s), index and the selected number of entries per page.
  • Next: Go to the next search results page.
  • Displaying results: Displays the first row index and the last in the current result.
  • Entries per page:: The maximum number of rows to display in one page.

Double clicking or pressing the Enter key on a selected row opens a window showing details for the row.

If databaseprotection.enableverify is enabled at the server side the signature of each row displayed are verified. If the verification fails for any of the rows in a page, an error message is displayed. The error message contains information about the first row that failed.

*** Main window: Archive ***

In the "Archive" tab controls for querying and filter the archive.

  • Current conditions: Lists query conditions used to filter the search results.
  • Add: Opens a dialog box for adding query conditions.
  • Remove: Removes the selected query condition.
  • First: Go to the first search results page.
  • Previous: Go to the previous search results page.
  • Reload: Loads or reloads the search result according the the current search condition(s), index and the selected number of entries per page.
  • Next: Go to the next search results page.
  • Displaying results: Displays the first row index and the last in the current result.
  • Entries per page:: The maximum number of rows to display in one page.

When selection one or more rows from the search result, the "Fetch selected archive data items" button is enabled. Clicking this button opens a dialog allowing to select a download directory and downloading the archived data of the selected rows.

*** 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.

*** Remove key dialog ***

Enter the key alias of the key to remove from the crypto token. Note that multiple workers might be using the key. If the crypto token supports key removal the key will be deleted and it might not be possible to restore it.

*** 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, auditors, and archive auditors and gives the ability to add, remove or edit them. It is also possible to get the serial number and issuer DN from a certificate file in PEM or DER format by using the "From file" button.

If already connected over WS, it is possible to click the "Load current" button to fill in the values from the currently used administrator certificate.

If the "Allow any aministrator with a valid certificate" is checked all administrators are given access even if they are not present in the list. This is for instance useful when first setting up the system. After adding your administrators the checkbox can be unchecked. It is recommended to add your self using the "Load current" button to be sure the correct information is filled in before disabling access for admins not in the list.

*** Admin GUI troubleshooting ***
  • AdminGUI login using smartcard fails on 64-bit (x86_64) version of Windows:
    The 64-bit version of Oracle Java does not support PKCS#11. A 32-bit version of Java and the PKCS#11 shared library should be used instead on that platform.

  • AdminGUI login using smartcard fails if path to DLL contains parenthesis:
    For instance the following path would cause problem: c:\program files (x86)\middleware\pkcs11.dll
    The problem is Java bug 7196009.
    Until this has been fixed you will need to install the middleware (PKCS#11/smartcard library) to a path without parenthesis.

  • IPv6 dualstack can give permission denied when trying to connect from AdminGUI:
    Trying to connect to SignServer over web services using the AdminGUI on Windows where both IPv4 and IPv6 is available can give "permission denied".
    One workaround is to edit signserver-gui.cmd and adding the following to the command:
    -Djava.net.preferIPv4Stack=true

  • AdminGUI login using smartcard fails most of the time with some cards:

    The card prompts for the PIN but then doesn't ask for which certificate to login with. Instead an error message with the text "Received fatal alert: bad_certificate" is displayed. This error message indicates that the server did not accept the provided certificate (ie, the issuer was not in the server's truststore). However, in this case the error could be because no certificate was possible to read from the card. This has been observed with some type of smart cards.

    A workaround that has been working in those cases are:

    1. Start the GUI without the card inserted
    2. Press Connect (without the card inserted)
    3. There will be an error message saying that "slotListIndex is 0 but token has 0 slots". Just ignore it.
    4. Now insert the card and press Connect again
    5. This time after the PIN prompt you are asked for which certificate to login with

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.

*** Configuring ***

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 setproperties sample-configs/qs_pdfsigner_configuration.properties
                        

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

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

You can list which workers you have with the command:

bin/signserver getstatus brief all                    
                    

If will display for example:

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


Current version of server is : SignServer 3.3.0alpha0


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 removeworker 1
bin/signserver reload 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/.

Healthcheck

*** Setting up the Health check servlet ***

In SignServer there exists a health check service that can be used for health monitoring. It is also useful for cluster, as it can be checked by load balancers to determine if a node should be active in the cluster (healthy) or taken out of the cluster (unhealthy).

The servlet is located at the URL: http://localhost:8080/signserver/healthcheck/signserverhealth and configured in signserver_build.properties.

The following configuration parameters may be set to configure authorization and what the service checks:

healthcheck.authorizedips - A semicolon-delimited list of IP addresses authorized to access the healthcheck servlet, if the list contains the keyword "ANY", any IP address is authorized access (defaults to 127.0.0.1).

healthcheck.minimumfreememory - Number of megabytes of memory that must be free before removing the node out of the cluster (defaults to 1).

healthcheck.checkdbstring - The string that should be used to do a minimal check that the database is working. May differ between databases. (defaults to Select count(*) from signerconfigdata, the property is not used when running without database).

healthcheck.maintenancefile - The path to a file containing the maintenance state, this file is a standard Java property file and should have a property (by default named DOWN_FOR_MAINTENANCE"). If this property has the value true, none of the standard health checks will be performed, and instead the result will be a string of the form MAINT: DOWN_FOR_MAINTENANCE. If this property is not set (or an invalid file is given), the maintenance functionallity is disabled.

healthcheck.maintenancepropertyname - The property name to be used in the maintenance file. This will also affect the error message returned when in maintenance mode (the part of the string after MAINT: (defaults to DOWN_FOR_MAINTENANCE).

*** Available tests and responses ***
  • No errors
    If all tests passed the HTTP result code is "200 OK" and page contains only the text "ALLOK".

  • Down for maintenance
    If the down for maintenance file indicates that the server is down for maintenance an HTTP response code in 5xx range is returned with an error page containing "MAINT: " followed of the name of the maintenance property as configured. No further checks are performed.

  • Database test
    A test is performed that SignServer is able to query the database. When running without database a check is made that the configured directory is initialized correctly and is not empty. If anything failed one or more error messages are included in an error page returned with the HTTP response code in the 5xx range.

  • Memory test
    Checks the available free memory. If anything failed an error message is included in an error page returned with the HTTP response code in the 5xx range.

  • Workers test
    Each (non-disabled) worker is checked for a number of things. If anything failed one or more error messages are included in an error page returned with the HTTP response code in the 5xx range.

    • Token offline: Workers having a crypto token can be reported as offline
    • Worker status and errors: Each worker implementation can put different requirements on when it is status is considered to be offline.
    • Signer certificate: Signers requiring a certificate are checked that they have a certificate matching the configured key-pair and that the certificate is valid according the certificate validity time and the configured minimum remaining validity time.
    • TimeStampSigner certificate missing EKU: If a TimeStampSigner certificate does not include the required EKU its status is set to offline.
    • TimeStampSigner certificate not included in certificate chain If a TimeStampSigner certificate chain property does not include the signer certificate its status is set to offline.
  • Disabled workers
    Workers that are disabled by having the worker property DISABLED=true are not considered in the Health check report.

Integration

JavaDoc

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

Client Web Service

The SignServer ClientWS interface can be used to request signings from SignServer.

The WSDL file is located at the URL http://<hostname>:8080/signserver/ClientWSService/ClientWS?wsdl and locally in the sources under modules/SignServer-Client-ClientWS/xml-resources/web-service-references/ClientWS/wsdl/localhost_8080/signserver/ClientWSService/ClientWS.wsdl.

Operations

processData

Generic operation for request signing of any binary (or character) data.

Parameters:

  • worker (string)
    Name of worker in SignServer which should handle the request.
  • metadata (sequence of key-value pairs)
    Optional additional request data. For instance the PDFSigner accepts the PDF password as a request data.
  • data (base64Binary)
    The document/data to process.

Output:

  • archiveId (string)
    Identifier for the request if archiving was used.
  • data (base64Binary)
    The signed binary/document.
  • metadata (sequence of key-value pairs)
    Any optional additional response data.
  • requestId (integer)
    Identifier for the request/response.
  • signerCertificate (base64Binary)
    The signer certificate in binary format if available.

Faults:

  • RequestFailedException
  • InternalServerException

processSOD

Operation for requesting an SOD to be created and signed.
The ePassport production system calls this operation to get an SOD for the supplied data groups.

Parameters:

  • worker (string)
    Name of worker in SignServer which should be used for constructing the SOD.
  • metadata (sequence of key-value pairs)
    Optional additional request data. Not used.
  • sodData (a sodRequest structure)
    The sodRequest should contain a sequence of datagroups (id 1-16 and their values), optionally also the version of the LDS to use and the version of Unicode.

Output:

  • archiveId (string)
    Identifier for the request if archiving was used.
  • data (base64Binary)
    The SOD binary.
  • metadata (sequence of key-value pairs)
    Any optional additional response data.
  • requestId (integer)
    Identifier for the request/response.
  • signerCertificate (base64Binary)
    The signer (DS) certificate in binary format if available.

Faults:

  • RequestFailedException
  • InternalServerException

The old Web Services interface

The SignServerWS is the old web services interface now replaced by SignServer ClientWS. It was new to version 3.0 and at the time replaced the RMI-SSL interface from 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 SignServerWS WSDL file is located at the URL http://<hostname>:8080/signserver/signserverws/signserverws?wsdl

The interface has 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.

Notice: All though the SignServerWS interface uses web services the actual process data is base64 encoded byte arrays in a special binary format. You will have to lookup the Java source code for the exact format of the request and response data. An alternative is to instead use the much simpler Web Server Interface or the newer ClientWS interface.

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.

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

This interface is only supported using HTTPS. The reason is that JBoss 4 does not rewrite the protocol part of the WSDL URL so we had to hard code it for it to work with HTTPS. For details about this see DSS-327.

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 available in the file lib/SignServer-Client-SignServerWS.jar (the old SignServerWS interface) and lib/SignServer-Client-ClientWS.jar (the ClientWS interface).

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 lib/SignServer-Client-SigningAndValidationAPI.jar.

Sample Code

*** Signing and validating an XML document ***
try {
    System.setProperty("javax.net.ssl.trustStore", "p12/truststore.jks");
    System.setProperty("javax.net.ssl.trustStorePassword", "changeit");
  
    ISigningAndValidation signserver = new SigningAndValidationWS("localhost", 8442, true);

    // 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();
}                                   

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. This can also be specified using the generic meta data parameters described below, using the key "pdfPassword". Optional and only used by PDFSigner.
  • REQUEST_METADATA - Meta data to pass on. Specified in Java properties file syntax. Optional.
  • REQUEST_METADATA.x - Sets a meta data parameter with the key specified by x. Overrides a value using the same key specified in the REQUEST_METADATA map. Optional.
  • encoding - Encoding of the data field. Optional. By specifying "base64" SignServer Base64-decodes the data property before passing it to the worker.
  • processType - The type of request. Can be any of "signDocument", "validateDocument", or "validateCertificate". Optional. If not specified, defaults to "signDocument".
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, text/plain for the validators.
Response content: The signed document for signers.
A string starting with "VALID" or "INVALID" for document validators. *Note to integrators: In future versions of SignServer there might be more information added after VALID/INVALID, such as a ;-separated list of addtional information or more lines with information.
A ;-separated string containing validation status code (see list below), valid purposes, status message, revocation reason (-1 if not revoked), and revocation date (empty when not revoked) for certificate validators.
Validation status codes:
  • VALID The certificate is valid
  • REVOKED The certificate has been revoked
  • NOTYETVALID The certificate is not yet valid
  • EXPIRED The certificate has expired
  • DONTVERIFY The certificate doesn't verify
  • CAREVOKED The CA certificate has been revoked
  • CANOTYETVALID The CA certificate is not yet valid
  • CAEXPIRED The CA certificate has expired
  • BADCERTPURPOSE The certificate has no valid certificate purpose
  • ISSUERNOTSUPPORTED The issuer of the certificate is not supported

* 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.

  • Samples of content output for certificate validation:
    • VALID;;This certificate is valid;-1;
    • ISSUERNOTSUPPORTED;;Issuer of given certificate isn't supported;-1;
    • REVOKED;;This certificate is revoked;3;1376565200519

WorkerServlet

HTTP requests can be sent to the SignServer servlet WorkerServlet located at /signserver/worker/* using either POST or GET.
Requests are forwarded to the GenericProcessServlet, except that the worker name is taken from the URL.
Worker name or ID given through request parameters are ignored.

URL: /signserver/worker/* (* denotes a worker name)
Method: GET or POST
Request content-type: None, "x-www-form-urlencoded", "multipart/form-data" or other*
Request parameters:
  • 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
*** Samples ***
  • HTTP GET:
    http://localhost:8080/signserver/worker/DemoXMLSigner?data=%3Croot%3Ehej2%3C/root%3E
    http://localhost:8080/signserver/worker/DemoXMLSigner?encoding=base64&data=PGhlajI%2Bb2s8L2hlajI%2BCg%3D%3D

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.
 -metadata         Additional meta data to send to the signer. The
                   parameters should be given in the form KEY=VALUE.
                   This option can be given multiple times.
 -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,
                   CLIENTWS 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
e) signdocument -workerid 2 -data "<root/>" -metadata param1=value1
-metadata param2=value2
                        

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.
 -metadata <arg> Additional meta data to send to the signer. The
                   parameters should be given in the form KEY=VALUE.
                   This option can be given multiple times.
 -password         Password for authentication.
 -port             Server port. Default: 8080 (for HTTP), 8442 for HTTPS
                   and 8443 for HTTPS with client authentication.
 -protocol <arg>   Method of interaction with SignServer.
                   WEBSERVICES, or HTTP. Default: WEBSERVICES.
 -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
e) validatedocument -workername XMLValidator -protocol HTTP -infile
/tmp/signed.xml
f) validatedocument -workername XMLValidator -infile /tmp/signed.xml -metadata param1=value1 -metadata param2=value2
                        

timestamp

$ bin/signclient timestamp
usage: timestamp <options> [url]
 -base64                Give this option if the stored request/reply
                        should be base64 encoded, default is not.
 -certreq               Request signer certificate
 -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.
 -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.
 -keyalias <arg>        Alias of the key in the keystore to use for
                        authentication.
 -keystore <arg>        Keystore with private key and certificate for
                        client certificate authentication.
 -keystorepwd <arg>     Password for reading the keystore.
 -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.
 -print                 Prints content of a request, response and/or token
 -reqpolicy <oid>       Request timestamp issued under a policy OID
 -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.
 -truststore <arg>      Keystore with trusted certificates to use with
                        HTTPS.
 -truststorepwd <arg>   Password for the keystore with trusted
                        certificates.
 -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
b) timestamp -print -inreq query.tsq
c) timestamp -print -inrep reply.tsr
                        

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'.
                                When using the HTTP protocol, only one
                                host name can be specified. (Required).
 -pem                           Certificate is in PEM format (Default).
 -port <port>                   Remote port of service (Default is 8080 or
                                8442 for SSL).
 -protocol <protocol>           Protocol to use, either WEBSERVICES or
                                HTTP. Default: WEBSERVICES.
 -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
c) validatecertificate -service CertValidationWorker -hosts localhost
    -cert certificate.pem -protocol HTTP
                        

signdatagroups

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

$ bin/client.sh signdatagroups
usage: signdatagroups <options>
Request MRTD data groups to be signed
 -data <arg>            Data to send to the worker.
 -encoding <arg>        Encoding of the data option. None or base64.
                        Default: none.
 -host <arg>            Server name or IP address. Default: localhost
 -keyalias <arg>        Alias of the key in the keystore to use for
                        authentication.
 -keystore <arg>        Keystore with private key and certificate for
                        client certificate authentication.
 -keystorepwd <arg>     Password for reading the keystore.
 -metadata <arg>        Additional meta data to send to the signer. The
                              parameters should be given in the form KEY=VALUE.
                              This option can be given multiple times.
 -password <arg>        Password for authentication.
 -port <arg>            Server port. Default: 8080 (for HTTP), 8442 for
                        HTTPS and 8443 for HTTPS with client
                        authentication.
 -protocol <arg>        Method of interacting with SignServer. HTTP or
                        CLIENTWS. Default: HTTP.
 -repeat <arg>          Run the operation this number of times. Default: 1
 -servlet <arg>         Servlet to call. Default /signserver/sod
 -truststore <arg>      Keystore with trusted certificates to use with
                        HTTPS.
 -truststorepwd <arg>   Password for the keystore with trusted
                        certificates.
 -username <arg>        Username for authentication.
 -workerid <arg>        ID of worker which should perform the operation.
 -workername <arg>      Name of worker which should perform the operation.

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

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 (in hex)> -issuerdn <issuer DN>
Usage: signserver wsadmins -add -cert <PEM or DER file>
Usage: signserver wsadmins -remove -certserialno <certificate serial number (in hex)> -issuerdn <issuer DN>
Usage: signserver wsadmins -list
Example 1: signserver wsadmins -add -certserialno 123abcdef -issuerdn "C=SE, CN=Neo Morpheus"
Example 2: signserver wsadmins -add -cert cert.pem
Example 3: signserver wsadmins -remove -certserialno 123abcdef -issuerdn "C=SE, CN=Neo Morpheus"
Example 4: signserver wsadmins -list
                    

Notice that the certificate serial number should be entered as the hexadecimal representation (leading zeros and upper/lowercase is not significant). 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".

An administrator can also be added by supplying a client certificate as an argument. The serial number and issuer DN is then taken from that certificate.

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=
                    

Apache HTTP Server as proxy

This section will show you examples on how the Apache Web Server (version 2.2.20) can be used as a proxy in front of SignServer. This guide is only informative, you should also always consult the current Apache documentation for the modules used. The proxy could be used for multiple reasons including:

  • Use standard ports (80, 443) instead of unprivileged ports used by the application server
  • Making workers accessible through more nice looking URLs.
    For example "http://tsa.example.com" instead of "http://example.com:8080/signserver/tsa?workerName=TimeStampSigner1"
  • Use any of the access control and authentication mechanism available in Apache
  • Redirect HTTP traffic to HTTPS
  • Only accepting requests to specified locations

As the requests should go through the proxy you will probably want to configure the application server to only listen to localhost and/or use a firewall blocking the application server ports from external requests. To configure JBoss to only listen to localhost set the following properties in signserver_build.properties:

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 (the following commands are for Ubuntu but should be similar in other distributions as well):

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

Example: Rewrite URLs for TSA (using mod_proxy and mod_rewrite)

A sample configuration how to fix up nice URLs for time-stamping so that you can point your TSA clients to http://tsa.example.com/ instead of http://tsa.example.com:8080/signserver/process?workerName=TimeStampSigner1.
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.example.com:80>
    ServerName tsa.example.com
    ServerAlias tsa.example.com
    CustomLog /var/log/apache2/access.log combined

    RewriteEngine on
    RewriteLogLevel 5
    RewriteLog "/var/log/apache2/rewrite.log
    RewriteRule ^/$ /?workerName=TimeStampSigner1 [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>
                    

Example: Rewrite URLs and redirect to HTTPS (using AJP)

The following example configures three virtual hosts. The first signserver.example.com:80 just redirects all requests to use HTTPS and thus the virtual host signserver.example.com:443. The second virtual host is configured to proxy requests to the /signserver path on the application server using the AJP protocol. It is also configured to use HTTPS with a server certificate. The last virtual hosts auth.signserver.example.com using an additonal IP address is configured to require client certificate authentication.

Notice: Some application servers (i.e. JBoss 4) might have problems writing the correct port number in the endpoint URL in the web services WSDL file when using a proxy (i.e. writing 8443 instead of 443).

<VirtualHost signserver.example.com:80>
    ServerName signserver.example.com
    ServerAlias signserver.example.com

    RewriteEngine On
    RewriteCond %{HTTPS} off
    RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}

    # Configure log
    LogLevel warn
    ErrorLog /var/log/apache2/error.log
    CustomLog /var/log/apache2/access.log combined

</VirtualHost>

<VirtualHost signserver.example.com:443>
    ServerName signserver.example.com
    ServerAlias signserver.example.com

    ProxyRequests Off
    <Proxy balancer://mycluster-3>
        BalancerMember ajp://localhost:8009/signserver
    </Proxy>
    ProxyPass / balancer://mycluster-3/

    RewriteEngine   On

    # Treat requests to / and /signserver/ as the same for web services endpoints to work.
    RewriteCond     %{THE_REQUEST}  /signserver/
    RewriteRule     ^/signserver/(.*)$ /$1 [PT]

    # Configure secure SSL for this server using SSL certificate generated by EJBCA
    SSLEngine on
    SSLCipherSuite HIGH
    SSLProtocol all -SSLv2
    SSLCertificateFile /home/markus/Documents/PrimeKey/MarkusCA/example.com/signserver.example.com-cert.pem
    SSLCertificateKeyFile /home/markus/Documents/PrimeKey/MarkusCA/example.com/signserver.example.com-key.pem

    # Configure log
    LogLevel warn
    ErrorLog /var/log/apache2/error.log
    CustomLog /var/log/apache2/access.log combined
</VirtualHost>

# Note: auth.signserver.example.com must have a different IP address
<VirtualHost auth.signserver.example.com:443>
    ServerName auth.signserver.example.com
    ServerAlias auth.signserver.example.com

    ProxyRequests Off
    <Proxy balancer://mycluster-4>
        BalancerMember ajp://localhost:8009/signserver
    </Proxy>
    ProxyPass / balancer://mycluster-4/

    RewriteEngine   On
    # Treat requests to / and /signserver/ as the same for web services endpoints to work.
    RewriteCond     %{THE_REQUEST}  /signserver/
    RewriteRule     ^/signserver/(.*)$ /$1 [PT]

    # Configure secure SSL for this server using SSL certificate generated by EJBCA
    SSLEngine on
    SSLCipherSuite HIGH
    SSLProtocol all -SSLv2
    SSLCertificateFile /home/markus/Documents/PrimeKey/MarkusCA/example.com/auth.signserver.example.com-cert.pem
    SSLCertificateKeyFile /home/markus/Documents/PrimeKey/MarkusCA/example.com/auth.signserver.example.com-key.pem

    SSLVerifyClient require
    SSLVerifyDepth 1
    SSLCACertificateFile /home/markus/Documents/PrimeKey/MarkusCA/example.com/truststore.pem

    # Configure log
    LogLevel warn
    ErrorLog /var/log/apache2/error.log
    CustomLog /var/log/apache2/access.log combined
</VirtualHost>
                    

Example: Granting access to specific workers only

This example shows how it is possible to limit access to only specified resources.

If you are going to grant different users access to different workers always remember to first deny access from the root location. The reason is that there are other ways to access a worker than the "/worker/*" pattern. For instance /process, /tsa, /pdf and /sod etc as well as using the web services interfaces /signserverws, /SignServerWSService, /validationws, /ValidationWSService and /ClientWSService all can be used to invoke any worker.

If you instead relay on SignServer to do the authentication/authorization it could still be good from a security point to only grant access to the locations you intend to use. In that case you would probably want to also give access to the web services interfaces, /worker and /process etc.

Also remember if you are proxying from multiple virtual hosts (i.e. if you have one with and one without client authentication as in the example above) that you might want to add the access restrictions to all of them.

    ...
    # First, deny access globally and then only give access to resources explicitly
    <Location />
    	Order Deny,Allow
    	Deny from all
    </Location>

    # Allow index page
    <LocationMatch "^/$">
	Order Allow,Deny
	Allow from all
    </LocationMatch>

    # Allow demo web pages
    <Location /demo/>
	Order Allow,Deny
	Allow from all
    </Location>

    # Allow documentation
    <Location /doc/>
	Order Allow,Deny
	Allow from all
    </Location>

    # Allow web page resources
    <LocationMatch "\.(css|js|jpg|png)$">
	Order Allow,Deny
	Allow from all
    </LocationMatch>
    
    # Allow the Admin interface
    <Location /AdminWSService/>
	Order Allow,Deny
	Allow from all
    </Location>

    # Grant everybody access to the XMLSigner
    <Location /worker/XMLSigner>
	Order Allow,Deny
	Allow from all
    </Location>

    # Grant valid users access to the CMSSigner
    <Location /worker/CMSSigner>
	Order Allow,Deny
        Allow from all
        AuthType Basic
        AuthName "Restricted CMSSigner access"
    	AuthUserFile /home/markus/.htpasswd
    	Require valid-user
    </Location>
    ...
                    

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 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.

Logging: This authorizer will add the remote IP address to the log field AUTHORIZED_ADDRESS.

*** List-based Address Authorizer ***

AUTHTYPE = org.signserver.server.ListBasedAddressAuthorizer

An authorizer that supports white- and blacklisting direct and forwarded addresses (coming via a proxy).

WHITELISTED_DIRECT_ADDRESSES = A comma-separated list of IP addresses allowed direct access.

BLACKLISTED_DIRECT_ADDRESSES = A comma-separated list of IP addresses denied direct access.

WHITELISTED_FORWARDED_ADDRESSES = A comma-separated list of IP addresses allowed access as a forwarded address.

BLACKLISTED_FORWARDED_ADDRESSES = A comma-separated list of IP addresses denied access as a forwarded address.

MAX_FORWARDED_ADDRESSES = Number of IP addresses to inspect in the list of forwarded addresses. (Default: 1).

It is not possible to specify both a whitelist and a black list at the same time for each of direct and forwarded addresses. One of each list (direct and forwarded) must be specified. When specifying a whitelist for forwarded addresses, requests without an X-Forwarded-For header will always be denied. When there are multiple addresses in the X-Forwarded-For header (in the case of using multiple proxies) the number of addresses specified in MAX_FORWARDED_ADDRESSES counting from the end of the list (or the entire list if it is shorter than this) is considered for white- and blacklisting. If specified, MAX_FORWARDED_ADDRESSES must have a value >= 1. It is not allowed to set it 0 to disable checking forwarded addresses. RemoteAddressAuthorizer should be used in this case.

Examples:

1. To accept requests from all direct addresses except for 10.0.0.5 and for all forwarded addresses except 13.170.18.12 and 13.170.18.13 use:
BLACKLISTED_DIRECT_ADDRESSES=10.0.0.5
BLACKLISTED_FORWARDED_ADDRESSES=13.170.18.12, 13.170.18.13

2. To only accept direct requests from 10.0.0.1 and 10.0.0.2 and from the forwarded address 216.34.181.97 use:
WHITELISTED_DIRECT_ADDRESSES=10.0.0.1, 10.0.0.2
WHITELISTED_FORWARDED_ADDRESS=216.34.181.97

3. To only allow direct access from the proxy servers 10.0.0.1 and 10.0.0.2 but allow them to forward from all address except the to banned addresses 13.170.18.12 and 13.170.18.13 use:
WHITELISTED_DIRECT_ADDRESSES=10.0.0.1, 10.0.0.2
BLACKLISTED_FORWARDED_ADDRESSES=13.170.18.12, 13.170.18.13

4. To accept direct requests from all addresses except 10.0.0.5 but only forwarded from 216.34.181.97 use:
BLACKLISTED_DIRECT_ADDRESSES=10.0.0.5
WHITELISTED_FORWARDED_ADDRESS=216.34.181.97

5. To accept direct request from a proxy server 10.0.1.1 allowing forwarding from another proxy 10.0.2.2 in turn proxying the request from the client with address 192.0.43.10 use:
WHITELISTED_DIRECT_ADDRESSES=10.0.1.1
WHITELISTED_FORWARDED_ADDRESSES=10.0.2.2,192.0.43.10
MAX_FORWARDED_ADDRESSES=2

6. To blacklist a set of IP addresses, set the MAX_FORWARDED_ADDRESSES value to a value gauranteed to be larger than the number of proxies you have control over, like in the following example: BLACKLISTED_FORWARDED_ADDRESSES=10.0.1.1,10.0.2.2,10.0.3.3 MAX_FORWARDED_ADDRESSES=10

Logging: This authorizer will add the remote IP address to the log field AUTHORIZED_ADDRESS and the proxied address (if it's available in the request) in the log field AUTHORIZED_FORWARDED_ADDRESS.

*** DispatchedAuthorizer ***

AUTHTYPE = org.signserver.server.DispatchedAuthorizer

AUTHORIZEALLDISPATCHERS = True, if any Dispatcher should be authorized. (Default: true, currently only true is supported)

Only accepts requests that has gone through a Dispatcher. This Authorizer only checks the present of the DISPATCHER_AUTHORIZED_CLIENT field in the request context to know that the request has passed a Dispatcher.

*** 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 and Base64DatabaseArchiver, in some extent, the Admin CLI can be used to query the archive. See the CLI section for more information.

When a request 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 archiving 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.

See also the section about all available Archivers.

Accounter

An Accounter is responsible for somehow charging a client for a successful request or to deny the requst if the client has insufficient funds.

When a request has been processed, and if the worker marked the request as successfully fulfilled, the configured Accounter (if any) is called. The Accounter implementation could potentially query an external database and make a purchase for the service.

The Accounter to use is configured using the ACCOUNTER worker property. By default no Accounter is used. Example:

ACCOUNTER=org.signserver.server.GlobalConfigSampleAccounter

See also the section about all available Accounters.

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

By default SignServer keeps track of the number of signings performed with each key by holding counters in the database that are updated for each signing. The following worker properties controls the key usage counter:

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.

DISABLEKEYUSAGECOUNTER = By default all key usages are counted but by specifying this as "TRUE" key usages performed by this worker will not be counted. Disabling the key usage counter can be a gain in performance as it will be less database transactions. However, if you have requirements on the number of allowed signings for one worker make sure to not use the same key with another worker for which the counter is disabled as those uses will then be missed.

The key usage counter can not be disabled for a worker if KEYUSAGELIMIT is also specified.

Other properties

DISABLED = Setting this to true disables a worker. A disabled worker can not perform any operations and any requests to it will fail. However, disabled workers are not included in the Health check report.

EXPLICITECC = Setting this to true uses explicit domain parameters instead of NamedCurves when generating a certificate request using the RenewalWorker or through to admin GUI. (default: false)

NOCERTIFICATES = Setting this to true tells SignServer to not warn if no signer certificate is configured for this worker. This could be useful for special types of workers not performing any signing operations.

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).

Common Properties

Properties that have common use among most signers:

INCLUDE_CERTIFICATE_LEVELS = Number of certificate levels to include. This property is supported for all signers except MRTDSODSigner, MRTDSigner, and MSAuthCodeTimeStampSigner. The property is optional and defaults to include all certificates in the chain, except for XAdESSigner, where the default is to only include one certificate (the signing certificate). Setting this to 0 (include no certificates) is not supported for TimeStampSigner. To include all certificates specify at least the same value as number of certificates in the certificate chain.

Time-stamp Signer

The time-stamp signer has the class name: 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 TIMESOURCE0_INSYNC is not expired and returned as true from the Status Repository.

Worker properties:

  • LEAPSECOND_HANDLING: NONE, PAUSE or STOP. Default is NONE.

    NONE: Leap seconds are not considered and time-stamp tokens are issued as usual.

    PAUSE: The TimeSource will query the status property LEAPSECOND from the Status Repository. If this property is not expired, and has the value POSITIVE or NEGATIVE and current time is in the interval surrounding a potential leap second (23:59:58,989 - 00:00:01,010) (at month shifts, in UTC time), the TimeSource will make a pause to ensure the time value is not fetch on the leap second. The value NONE is interpreted as there is no leap second and the time value will be returned immediately as usual. If the value has expired, no valid time will be returned.

    STOP The TimeSource will query the status property in the same way as for the PAUSE strategy. During the interval surrounding a potential leap second no time will be returned. This will cause the response to the clients to be timeSourceNotAvailable. If the LEAPSECOND status property value has expired, no valid time will be returned.

SIGNATUREALGORITHM = property specifying the algorithm used to sign the timestamp (default: SHA1withRSA)

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.

INCLUDEORDERING = If set to true, always include the ordering attribute, even when ORDERING is set to false. It is not allowed to set this to false when ORDERING is set to true. (OPTIONAL), default false.

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

TSA_FROM_CERT = Setting this property to true sets the general name of the Time Stamp Authority to the subject DN of the signing certificate. This can not be set to true if the TSA property is set. (OPTIONAL) (the default is to not set the general name)

REQUIREVALIDCHAIN = Set to true to perform an extra check that the SIGNERCERTCHAIN only contains certificates in the chain of the signer certificate. (OPTIONAL), default false.

MAXSERIALNUMBERLENGTH = The maximum size (in bytes) used when generating serial numbers, must be between 8 and 20 (64 - 160 bits) (Default: 8) The generated serial number will always be positive (so the sign bit is always a zero).

WORKERLOGGER = As for other workers this property can be used to specify which worker logger to use. By default the DefaultTimeStampLogger is used.

INCLUDESTATUSSTRING = Specifies if the status string is to be included in the response. Setting this to true triggers a bug in some versions of OpenJDK's jarsigner utility. (OPTIONAL), default true.

INCLUDESIGNINGTIMEATTRIBUTE = Specifies if the signingTime signed CMS attribute should be included in the response. (OPTIONAL), default true.

*** TimeStampSigner Certificates ***

Specifying a signer certificate is required as information from that certificate will be used to indicate which signer signed the time-stamp token.

The signer certificate chain contains all certificates included in the token if the client requests the certificates. The signer certificate MUST be included in the configured certificate chain. Other certificates might also be included in the chain (typically intermediate CA certificates). However, if REQUIREVALIDCHAIN=true is specified only the signer certificate directly followed by its issuer and then the issuer's issuer and so on is allowed. All certificates will be verified if there is a certificate coming after it. No check is made that the last certificate is a root certificate as that certificate is usually not included.

MS Authenticode Time Stamp Signer

The class name is: org.signserver.server.signers.tsa.MSAuthCodeTimeStampSigner

*** Overview ***

This time stamp signer is compatible with the Microsoft Authenticode time-stamping code signing.

*** Available Properties ***

TIMESOURCE = property containing the fully qualified name of the class implementing the ITimeSource that should be used (OPTIONAL). This property has the same values as for TimeStampSigner above.

SIGNATUREALGORITHM = property specifying the algorithm used to sign the timestamp (default: SHA1withRSA)

INCLUDE_SIGNING_CERTIFICATE_ATTRIBUTE = Specifies if the signing certificate attribute (id-aa-signingCertificate) [RFC2634] should be included in the response (OPTIONAL, default: false).

*** Howto ***

There is a howto about testing Authenticode signing available in doc/howtos/test_ms_authcode.txt

MRTD Signer

The MRTD signer has the class name: org.signserver.module.mrtdsigner.MRTDSigner

*** Overview ***

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

*** Available Properties ***

No configuration properties exists.

MRTD SOD Signer

The MRTD SOD signer has the class name: org.signserver.module.mrtdsodsigner.MRTDSODSigner

*** Overview ***

The MRTD SOD Signer creates the complete security object (SOd) for a MRTD (Machine Readable Travel Document, i.e. electronic passports, residence permit etc) by signing the provided data groups (DGs).

Note 1: The Document Signer (DS) certificate is included in the SOd.
Note 2: The SOd is verified (including certificate path) before it is returned so the certificate chain must contain the Country Signing CA (CSCA) certificate.
Note 3: See also the integration guide for SODProcessServlet or the ClientWS interface.

*** Available Properties ***

DODATAGROUPHASHING = True if this signer first should hash the DG values. Otherwise the values are assumed to be hashes already. (Optional, default is false)
DIGESTALGORITHM = Message digest algorithm that is applied or should be applied to the values. (Optional, default is SHA256)
SIGNATUREALGORITHM = Signature algorithm for signing the SO(d). (Optional, default is SHA256withRSA all though SHA256withRSAandMGF1 is recommended by Doc9303)
LDSVERSION = Version of Logical Data Structure (LDS). For LDS version 1.7 enter "0107" and for version 1.8 "0108". (Optional, default is 0107)
UNICODEVERSION = Version of Unicode used in the datagroups. Required if LDS 1.8 is used. Example: "040000" for Unicode version 4.0.0.

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 old 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.

This will cause time stamp requests to be issued via HTTP requests. Under high load this can lead to thread deadlocks in the application server if using a localhost URL (using a time stamp signer running in the same server). In this case, use the internal mechanism described below).

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 "\" = "\\", "=" =>"\=")

Note: this property can not be set at the same time as TSA_WORKER (see below).

Default: not set (no timestamping).

TSA_WORKER

Specify a worker ID or worker name for a time stamp signer

This will use internal calls and can only be used for a time stamp authority running in the same SignServer instance.

Note: use this option instead of TSA_URL when using a time stamp signer running in the same SignServer instance to avoid thread deadlocks under high load.

Note: this property can not be set at the same time as TSA_URL (see above).

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.

Note: OCSP responses must contain a nextUpdate field in order for off-line validation to work with Adobe Reader. For EJBCA OCSP Responder see configuration of ocsp.untilNextUpdate in ocsp.properties.

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 (from the PDF reference, version 1.6, page 99, TABLE 3.20):

ALLOW_PRINTING Print the document to a representation from which a faithful digital copy of the PDF content could be generated. When this is not set (and ALLOW_DEGRADED_PRINTING is set), printing is limited to a low-level representation of the appearance, possibly of degraded quality.
ALLOW_MODIFY_CONTENTS Modify the contents of the document by operations other than those controlled by ALLOW_MODIFY_ANNOTATIONS, ALLOW_FILL_IN, and ALLOW_SCREENREADERS.
ALLOW_COPY Copy or otherwise extract text and graphics from the document, including extracting text and graphics (in support of accessibility to users with disabilities or for other purposes).
ALLOW_MODIFY_ANNOTATIONS Add or modify text annotations, fill in interactive form fields, and, if ALLOW_MODIFY_CONTENTS is also set, create or modify interactive form fields (including signature fields).
ALLOW_FILL_IN Fill in existing interactive form fields (including signature fields), even if ALLOW_MODIFY_ANNOTATIONS is not set.
ALLOW_SCREENREADERS Extract text and graphics (in support of accessibility to users with disabilities or for other purposes).
ALLOW_ASSEMBLY Assemble the document (insert, rotate, or delete pages and create bookmarks or thumbnail images), even if ALLOW_MODIFY_CONTENTS is not set.
ALLOW_DEGRADED_PRINTING Print the document (possibly not at the high-est quality level, depending on whether ALLOW_PRINTING is also set).

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)

DIGESTALGORITHM

Sets the hash algorithm used for the message digest and signature hash.

Setting this property will also imply a minimum PDF version depending on the hash used. The resulting PDF will be upgraded to this version if it's higher than the version used in the original PDF. Since upgrading the version requires re-creating the file (i.e. not appending the new signature) this is not supported on already signed document (i.e. using a hash algorithm requiring a higher version than the original document). Attempting to sign such a document will result in a failure.

Supported hash algorithms.

Algorithm PDF version
SHA1 1.3
SHA256 1.6
SHA384 1.7
SHA512 1.7
RIPEMD160 1.7

Default SHA1.

ODF Signer

Fully qualified class name: org.signserver.module.odfsigner.ODFSigner

*** 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

Fully qualified class name: org.signserver.module.xmlsigner.XMLSigner

*** Overview ***

The XML Signer creates enveloped XML signatures using XMLDSig.

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

*** Available Properties ***

SIGNATUREALGORITHM = property specifying the algorithm used to sign the data (default: depending on the signer's private key: SHA1withDSA for DSA keys, SHA1withRSA for RSA keys, and SHA1withECDSA for ECDSA keys.)

*** Supported Signature Algorithms ***
  • SHA1withDSA
  • SHA1withRSA
  • SHA256withRSA
  • SHA384withRSA
  • SHA512withRSA
  • SHA1withECDSA
  • SHA256withECDSA
  • SHA384withECDSA
  • SHA512withECDSA

XAdES Signer

Fully qualified class name: org.signserver.module.xades.signer.XAdESSigner

*** Overview ***

The XAdES Signer creates XML signatures according to the specified profile of XAdES.

*** Available Properties ***

XADESFORM = Which profile of XAdES to use. Currently BES and T is supported. Default: BES
COMMITMENT_TYPES = List of commitment types to be indicated in the signature. Multiple values can be given separated by ",". See list below for valid values. Optionally the constant NONE can be used to explicitly state that no commitment types should be included (this constant can only be used alone). Optional. Default: no commitment types are included.
SIGNATUREALGORITHM = The algorithm used to sign the data. The same set of algorithms as for the same property in XMLSigner is supported. Optional. Default: depending on the signer's private key: SHA1withDSA for DSA keys, SHA256withRSA for RSA keys, and SHA1withECDSA for EC keys.
CLAIMED_ROLE = Claimed role to include in the signature. If the CLAIMED_ROLE_FROM_USERNAME property is also set, this value is used as a fallback when there is no user name provided in the request. Optional. Default: no default claimed role defined.
CLAIMED_ROLE_FROM_USERNAME = If this is set to true, use the user name from the request (provided by an authorizer) as the value for claimed role. If there is no user name provided fall back to the value set by CLAIMED_USER. If this is set to true and CLAIMED_ROLE is not set and the request doesn't contain a user name, the request will result in an error. Optional. Default: false.
INCLUDE_CERTIFICATE_LEVELS = Number of certificate levels to include in the document's KeyInfo (also see the common properties above). Minimum and default value is 1 which includes only the signer certificate. The value 2 includes the signer certificate and its issuer. To include all certificates specify at least the same value as number of certificates in the certificate chain. TSA_URL = URL of timestamp authority. Required if XADESFORM=T and TSA_WORKER not specified.
Note: this property can not be set at the same time as TSA_WORKER (see below).
TSA_WORKER = Specify a worker ID or worker name for a time stamp signer. Required if XADESFORM=T and TSA_URL not specified.
This will use internal calls and can only be used for a time stamp authority running in the same SignServer instance.
Note: Use this option instead of TSA_URL when using a time stamp signer running in the same SignServer instance to avoid thread deadlocks under high load.
Note: This property can not be set at the same time as TSA_URL (see above).
TSA_USERNAME = Login username used if the TSA uses HTTP Basic Auth.
TSA_PASSWORD = Login password used if the TSA uses HTTP Basic Auth.

*** Commitment Types ***
Value Description
NONE Don't include any commitment type. This can not be used in conjunction with the other constants below
PROOF_OF_APPROVAL Indicates that the signer has approved the content of the signed data object
PROOF_OF_CREATION Indicates that the signer has created the signed data object (but not necessarily approved, nor sent it)
PROOF_OF_DELIVERY Indicates that the TSP providing that indication has delivered a signed data object in a local store accessible to the recipient of the signed data object
PROOF_OF_ORIGIN Indicates that the signer recognizes to have created, approved and sent the signed data object
PROOF_OF_RECEIPT Indicates that signer recognizes to have received the content of the signed data object
PROOF_OF_SENDER Indicates that the entity providing that indication has sent the signed data object (but not necessarily created it)

OOXML Signer

Fully qualified class name: org.signserver.module.ooxmlsigner.OOXMLSigner

*** 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 with or without the content encapsulated.

Currently the signer certificate is always included.

*** Available Properties ***

SIGNATUREALGORITHM = property specifying the algorithm used to sign the data (default: depending on the signing key: SHA1withDSA for DSA keys, SHA1withECDSA for ECDSA keys, otherwise SHA1withRSA)

DETACHEDSIGNATURE = property specifying if a detached signature (a.k.a. "external signature") should be used. That is a signature where the content is not included/encapsulated. Default is false.

ALLOW_DETACHEDSIGNATURE_OVERRIDE = property specifying if the requestor can request an other value for DETACHEDIGSNATURE than what is configured. Default is false.
If set to true a request could include a metadata property with an other value for DETACHEDSIGNATURE.

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

XAdES Validator

*** Overview ***

The XAdES validator validates the signature of XAdES documents and validatates the certificate chain. The validator will also validate embedded timestamp tokens in XAdES form T-signed documents.

*** Available Properties ***

TRUSTANCHORS = Trusted certificates. In PEM format. When validating a XAdES form T-signed document, must include the trusted certificate for the time stamp authory as well. Required.

CERTIFICATES = Intermediate CA certificates that might be needed to build a trust path from the signer certificates to any of the trusted certifivcates. In PEM format.

REVOCATION_CHECKING = True if revocation checking should be performed. The intermediate CA certificates (if any) and the signer certificate needs to have an Authority Information Access URL to an online OCSP responder or an CRL Distribution Point from where a CRL can be downloaded. If both are available the OCSP responder will be consulted first and then the CRL if the reseponder were unavailable. Default: true

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.

RequestedPolicyDispatcher

Fully qualified class name: org.signserver.module.tsa.RequestedPolicyDispatcher

*** Overview ***

Dispatches the Time-stamp request to an other signer based on the requested TSA Policy according to an configured mapping table. This dispatcher can be useful if you want to have multiple signers (Time Stamp Units) signing with different TSA policies but don't want the client to have to call different workers.

See also the DispatchedAuthorizer which if configured by a signer can allow all requests that has gone through a Dispatcher.

*** Available Properties ***

DEFAULTWORKER = Worker name or ID to dispatch to in case no policy was requested.

USEDEFAULTIFMISMATCH = If true dispatches to DEFAULTWORKER in case no mapping existed for the requested policy OID (default: false)

MAPPINGS = Mapping from requested policy OID to a worker name.
The property is of the form:
POLICYOID1:WORKERNAMEORID1; POLICYOID2:WORKERNAMEORID2; POLICYOID3:WORKERNAMEORID3;

INCLUDESTATUSSTRING = Specifies if the status string is to be included in the response. This setting only affects the behavior when USEDEFAULTIFMISMATCH is false, and there is no mapping for the requested policy. In case there is a mapping (or no mapping and USEDEFAULTIFMISMATCH is true, the state of INCLUDESTATUSSTRING of the used signer is used to determine if the status string is included. Setting this to true triggers a bug in some versions of OpenJDK's jarsigner utility. (OPTIONAL), default true.

UserMappedDispatcher

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

*** Overview ***

Dispatches the request to a worker based on a mapping from username and workername.

*** Available Properties ***

USERNAME_MAPPING = Comma separated list of mappings from user name to worker name.
The property is of the form:
username1:workername1, username2:workername2

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 and/or Digital Signature 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.

*** 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 = Fully qualified class name of 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.....
                        

Certificate Validators

*** CRLValidator ***

Class name: org.signserver.validationservice.server.CRLValidator

*** OCSPValidator ***

Class name: org.signserver.validationservice.server.OCSPValidator

*** OCSPCRLValidator ***

Class name: org.signserver.validationservice.server.OCSPCRLValidator

*** NoRevocationCheckingValidator ***

Class name: org.signserver.validationservice.server.NoRevocationCheckingValidator

Certificate Validator that validates the certificate chain but does not perform any revocation checking. This can be useful for demonstation purposes or when revocation checking should not be performed.

*** DummyValidator ***

Class name: org.signserver.validationservice.server.DummyValidator

Certificate Validator that only works for specific issuers and certificates and is only available for testing and demonstration purposes as no real certificate validation is performed. The keystores under res/test/dss10/ with certificates issued by "DSS Root CA 10" can for instance be used together with this validator.

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 lib/SignServer-Client-ValidationCLI.jar.

Use the client with 'java -jar lib/SignServer-Client-ValidationCLI.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.
                   

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)

WORK_LOG_TYPES = Property specifying a comma-separated list of log types that should be used for logging invocations of the service.
The following values can be used:

INFO_LOGGING Use Log4J info logging
SECURE_AUDITLOGGING Use CESeCore secure audit logging
By default, if this property is not set, INFO_LOGGING is used. It is possible to turn off logging by setting this property to an empty value. Errors during service invocations will always be logged at error level using Log4J. If the property contains SECURE_AUDITLOGGING, the error will additionally be logged to the audit log.

SignerStatusReportTimedService

Fully qualified class name: org.signserver.module.signerstatusreport.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. See also the SignerStatusReportWorker which is an alternative way of offering this reports.

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.

HSMKeepAliveTimedService

Fully qualified class name: org.signserver.server.timedservices.hsmkeepalive.HSMKeepAliveTimedService

*** Overview ***

The HSMKeepAliveTimedService is a timed service that can be used to periodically run the test key operation on selected crypto workers. This is intended as a measure to prevent HSM connections timing out. The service will use the key alias TESTKEY for the workers when set, otherwise it will fall back on DEFAULTKEY. Notice that the service will not fallback on DEFAULTKEY if TESTKEY is set, but didn't succeed when testing the key.

*** Available Properties ***

CRYPTOTOKENS = Comma-separated list of worker names or worker IDs of workers whos keys should be tested. This would typically be crypto workers i.e. corresponding to different slots in an HSM, but could also be regular workers with crypto tokens configured directly). This property is required, but can be set to an empty value if only audit logging is needed (see below).

NOTE: if secure audit logging is used and a separate crypto token is used for logging, the service logging described above using the WORK_LOG_TYPES property and the SECURE_AUDITLOGGING value can be used to write to the audit log at the same time as testing crypto worker keys, to keep the auditlog crypto token from timing-out.

Installing a service

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

$ bin/signserver setproperties configuration.properties
                    

Example:

$ bin/signserver setproperties doc/sample-configs/qs_signerstatusreport_configuration.properties
===========================================
  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 reload 2
===========================================
Executing Command on host : localhost
===========================================
SignServer reloaded successfully
Current configuration is now activated.
                    

Other workers

CryptoWorker

The Crypto Worker is a worker not performing any operations on its own and instead only hosts a Crypto Token that can be referenced by other workers.

Fully qualified class name: org.signserver.server.signers.CryptoWorker

*** Worker properties ***

See the Available CryptoTokens for the required properties of the configured crypto token.

RenewalWorker

*** Overview ***

The RenewalWorker can be used for generation a new key-pair and renewing a worker's certificate from EJBCA using web services (WS). The RenewalWorker should be configured with its own CryptoToken and an SSL client authentication certificate with permissions set up in EJBCA to issue certificates. Some properties are configured for the RenewalWorker such as the EJBCA WS endpoint URL and truststore details, other properties should be set on the worker that should be renewed (the renewee) and some arguments are provided when the worker is invoked.

Known limitation: It might not be possible to have multiple renewal workers using different crypto tokens because the keys and certificates used by the TLS connection for the web service is setup globally.

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

*** Requesting the worker ***

After setting up an RenewalWorker and installing its certificate signers (and other workers), can easily be renewed using the SignServer AdminGUI. See Renew Signer dialog. As the RenewalWorker is a worker it can also be invoked using the normal client APIs. Using the demo web pages: Generic Signing Demo:

Sign by Direct Input
Worker name: MyRenewalWorker
Data:

WORKER=MySigner
AUTHCODE=foo123

Using the Client CLI:

bin/signclient signdocument -workername MyRenewalWorker -data "WORKER=MySigner
AUTHCODE=foo123"

(Notice that the command is on two lines)

The renewal can also be initiated from the Admin CLI:

bin/signserver renewsigner MySigner -renewalworker MyRenewalWorker -authcode foo123
                    
*** RenewalWorker operations ***

The RenewalWorker starts by generating a new key-pair (unless an NEXTCERTSIGNKEY is already set for the renewee or the request property FORDEFAULTKEY=true is set in the request). The HSM/keystore password needs to be submitted as part of the request (AUTHCODE request property) to generate a new key-pair. After the key-pair has been generated and tested successfully the key alias is set as the NEXTCERTSIGNKEY property. A certificate signing request is created for the key and the worker sends the request to EJBCA to issue a certificate for the configured end entity. After receiving the certificate and certificate chain they are installed for the worker and the DEFAULTKEY property is updated with the value from NEXTCERTSIGNKEY and that property is removed.

*** Worker Properties ***

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

TRUSTSTOREPATH = Path to the keystore containing the CA's SSL server certificate as a trusted entry. Used instead of TRUSTSTOREVALUE. If this property is not specified, TRUSTSTOREVALUE must be set.

TRUSTSTOREVALUE = Keystore containing the CA's SSL server certificate as a trusted entry. Used instead of TRUSTSTOREPATH. If this property is not specified, TRUSTSTOREPATH must be set. If TRUSTSTORETYPE is not PEM the keystore is stored in the property in base64 encoding.

TRUSTSTORETYPE = Type of keystore. JKS and PEM is supported. This property must be set.

TRUSTSTOREPASSWORD = Password protecting the truststore keystore. This property must be set if TRUSTSTORETYPE is not PEM.

KEYSTOREPASSWORD = The password that locks the key-store. Required for JKS.

DEFAULTKEY = Key alias to use from the crypto token. This property must be set.

*** Properties of renewee ***

RENEWENDENTITY = Name of the existing end entity in EJBCA

REQUESTDN = Subject DN to set in the certificate signing request (PKCS#10).

SIGNATUREALGORITHM = Signature algorithm to use when signing the certificate signing request (PKCS#10)

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

RENEWWORKER = Name of the default RenewalWorker to use (Optional). Specify this to have the current RenewalWorker already selected in the AdminGUI when renewing signers.

DEFAULTKEY = Key alias for the current existing key. The worker will update this property.

NEXTCERTSIGNKEY = Key alias for the next existing key. If this property exists a new key-pair will not be generated. The worker will update/remove this property.

*** Request Properties ***

WORKER = Name of the worker that should be renewed.

AUTHCODE = HSM/keystore password for activation.

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 succeeded 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

StatusPropertiesWorker

Fully qualified class name: org.signserver.module.statusproperties.StatusPropertiesWorker

*** Overview ***

The StatusPropertiesWorker can be used to query and setting status properties in the status repository.

*** Worker Properties ***

(none)

*** Request Properties ***

GET - Comma-separated list of status properties to query

x.VALUE - Where x is a status property: Sets the value of the property

x.EXPIRATION - Where x is a status property: Sets the expiration time for x (x.VALUE must also be specified)

If no property is specified all valid status properties are returned

*** Response Properties ***

x.VALUE = See Request Properties

x.EXPIRATION = See Request Properties

TimeMonitorManager

Note
The TimeMonitorManager is an Enterprise Edition feature.

Fully qualified class name: org.signserver.module.timemonitormanager.TimeMonitorManager

*** Overview ***

Similar to the StatusPropertiesWorker, the TimeMonitorManager also supports setting status properties in the status repository. In addition the TimeMonitorManager also supports dynamic configuration of the TimeMonitor as well as gives a complete view of the state of the TimeMonitor.

*** Worker Properties ***

All worker properties starting with either "TIMEMONITOR." or "TIMESERVER." are sent to the TimeMonitor if it asks for it.

See the SignServer TimeMonitor manual for the list of available properties.

*** Request Properties ***

x.VALUE - Where x is a status property: Sets the value of the property

x.EXPIRATION - Where x is a status property: Sets the expiration time for x (x.VALUE must also be specified)

*** Response Properties ***

x.UPDATE = The time when the property was written

*** Status output ***

Much information about the state of the TimeMonitor is available in the getstatus output of the TimeMonitorManager:

  • Time monitor: Indicates if the application is detected to be 'Running', 'Disabled', 'Not running?' or 'Unavailabe'. The state is determined by if the manager has seen an update from the TimeMonitor before the status properties are starting to expire.
  • Last update: The last time the TimeMonitor contacted the manager.
  • Current time: Current time of the server.
  • Time state: The last time state from the TimeMonitor.
  • Report state: The last report state from the TimeMonitor.
  • Leap state: The last leap state from the TimeMonitor.
  • Configuration: Either 'out of sync' or 'up to date' depending on if the current configuration has been read by the TimeMonitor or not. After changing a property in the TimeMonitorManager it is normal that the cofiguration is marked as 'out of sync' until the TimeMonitor fetches it.
  • Status properties values: Prints the current value and possibly the expiration time for the TIMESOURCE0_INSYNC and LEAPSECOND status properties.
  • Timings: Prints the current time values from the TimeMonitor.
  • Configuration: Prints the configuration values in the manager (not necesarly read by the TimeMonitor yet).
  • Last TimeMonitor log entries: Prints the last log entries obtained from the last update from the TimeMonitor.

Sample output:

Status of Worker with id 300 (TimeMonitorManager) is:
   Worker status : Active
   Time monitor  : Running
   Last update   : 2014-08-26 11:43:39,176
   Current time  : 2014-08-26 11:43:39,580
   Time state    : INSYNC
   Report state  : REPORTED
   Leap state    : NONE
   Configuration : Up to date

   Status Repository values:
      TIMESOURCE0_INSYNC:        true
      LEAPSECOND:                NONE

   Timings:
      NTP server time offset:           0 ms
      NTP server query time:          507 ms
      NTP leap status query time:       8 ms
      Report time:                      7 ms
      Total required run time:        522 ms

   Configuration:
      NTP server hosts:            192.168.30.25
      NTP query samples:                2
      NTP query timeout:              200 ms
      Max accepted offset:            997 ms
      Warn offset:                    500 ms
      Status expire time:             900 ms
      Leap status expire time:      60000 ms
      Warn run time:                  800 ms
      Minimum run time:               550 ms

   Last TimeMonitor log entries:
      2014-08-26 11:36:29,253 INFO  Started
      2014-08-26 11:36:29,287 INFO  State changed to: UNKNOWN,REPORTED,UNKNOWN
      2014-08-26 11:36:44,255 INFO  Config changed to: 1ccdf46b
      2014-08-26 11:36:44,782 INFO  Time back in calibration: offset abs(0)  max accepted offset 997
      2014-08-26 11:36:44,793 INFO  State changed to: INSYNC,REPORTED,NONE
                        

TimeMonitorStatusReportWorker

Note
The TimeMonitorStatusReportWorker is an Enterprise Edition feature.

Fully qualified class name: org.signserver.module.timemonitormanager.TimeMonitorStatusReportWorker

*** Overview ***

Worker that outputs the TimeMonitor state line as described in the SignServer TimeMonitor manual.

*** Response ***

Sample output:

1409055102120,INSYNC,REPORTED,NONE,1ccdf46b,0,507,7,6
                        

SignerStatusReportWorker

Fully qualified class name: org.signserver.module.signerstatusreport.SignerStatusReportWorker

*** Overview ***

The SignerStatusReportWorker is a worker that returns a status report for a configured set of workers. 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. This worker returns the report in the same format as defined for the SignerStatusReportTimedService.

*** Worker Properties ***

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

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.P12CryptoToken

*** 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.JKSCryptoToken

*** 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. (Only required for auth-activation, otherwise the activatecryptotoken CLI command can be used)

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

SLOTLABELTYPE = Indicates how the slot should be identified. Supported values are SLOT_NUMBER, SLOT_INDEX or SLOT_LABEL. (Required)

SLOTLABELVALUE = The slot to use, identified with the type specified in SLOTLABELTYPE: (Required)

  • SLOT_NUMBER is the number (ID) of the slot
  • SLOT_INDEX is the zero-base index of the slot in the list of available slots as returned by the PKCS#11 provider
  • SLOT_LABEL this is the label of the slot

This properites are not allowed if the legacy properties below are specified.

SLOT or SLOTLISTINDEX = Legacy properties for indicating which slot to use. Only available for backwards compatibility. Instead use the SLOTLABELTYPE and SLOTLABELVALUE properties.

ATTRIBUTESFILE = Path to file with PKCS#11 attributes used for key generation. (Optional, not allowed if ATTRIBUTES specified)

ATTRIBUTES = PKCS#11 attributes used for key generation specified directly in the property value. (Optional, not allowed if ATTRIBUTESFILE specified)

Sample p11attributes.cfg:

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

# Work-around for performance issue in the Apache XMLSec library
disabledMechanisms = {
    CKM_SHA1_RSA_PKCS
    CKM_SHA256_RSA_PKCS
    CKM_SHA384_RSA_PKCS
    CKM_SHA512_RSA_PKCS
    CKM_MD2_RSA_PKCS
    CKM_MD5_RSA_PKCS
    CKM_DSA_SHA1
    CKM_ECDSA_SHA1
}
                        

Notice: The PKCS#11 attributes configuration is global per shared library. If specified in multiple workers only the configuration from the first worker loaded will be used. Changing the property might not take effect without restarting the application server.

CACHE_PRIVATEKEY = If set to true the private key reference is cached in the worker so that it is not queried for each signature. This could potentially improve performance in some environments. (Default: false)

*** Default global properties ***

Some worker properties can instead by specified as default values in the global configuration so they does not have to be repeated in every worker. Individual workers can override the default global values (if any) by specifying the property as usual.

Global default values are specified as global values in the global configuration with the name prefixed with "DEFAULT.". The following properties can currently be specified in the global configuration:

  • SHAREDLIBRARY
  • SLOTLABELTYPE
  • SLOTLABELVALUE
  • SLOT
  • SLOTLISTINDEX
  • ATTRIBUTES
  • ATTRIBUTESFILE
  • PIN
*** Example usage ***

Edit (preferably a copy of) pkcs11-crypto-configuration.properties to match your PKCS#11 token. Run the following command to set up the token:

bin/signserver setproperties pkcs11-crypto-configuragtion.properties

Reload the configuration using the ID that was printed (in this example 8):

bin/signserver reload 8

Activate the crypto token by specifying the PIN code:

bin/signserver activatecryptotoken 8

Unless your DEFAULTKEY worker property points to an existing key in the HSM the activation will look like it failed. Don't worry and instead continue creating a key that can be used for testing slot activation:

Generate a keypair in the token to be used as test key:

bin/signserver generatekey 8 -alias testkey1 -keyalg RSA -keyspec 2048

Set the key as test key:

bin/signserver setproperty 8 DEFAULTKEY testkey1
bin/signserver reload 8
bin/signserver activatecryptotoken 8

Test the keypair: bin/signserver testkey 8

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

Add a user in EJBCA with a certificate profile suitable for signing, and enroll 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.

The signer certificate should then be uploaded to the worker wich should use it. Upload the signing certificate chain to the signer using the command: bin/signserver uploadsignercertificatechain 9 GLOB /tmp/certchain.pem bin/signserver reload 9

OldPKCS11CryptoToken

*** Overview ***

The OldPKCS11CryptoToken implementation (before the use of CESeCore) is only available as a fallback for a limited time. This implementation is deprecated. The PKCS11CryptoToken should be used instead.

*** SIGNERTOKEN.CLASSPATH ***

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

*** Available Properties ***

Currently most properties from the PKCS11CryptoToken can be used.

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 lib/signserver-ejb.jar:lib/ext/1.6/bcprov-jdk.jar:lib/SignServer-Common.jar:lib/ext/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 generatecertreq <id> "CN=Soft Signer token" SHA1WithRSA /tmp/certreq.pem
                        

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

bin/signserver 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.

Archivers

See also the section about the ARCHIVERS worker property that can be set to one or more of the available Archiver implementations described below.

OldDatabaseArchiver

The default archiver used if the the property ARCHIVE=true is set. Or if the ARCHIVERS property contains its class name. This Archiver archives to the database table "ArchiveData" using the same datasource as SignServer uses for accessing the database for its configuration etc.

The data is stored in an XML encoded Base64PutHashMap. In the "dataEncoding" column this format is indicated as DATA_ENCODING_XML.

The fully qualified class name is: org.signserver.server.archive.olddbarchiver.OldDatabaseArchiver

*** Worker Properties ***

ARCHIVERx.ARCHIVE_OF_TYPE = Where "x" is the index of the Archiver in the ARCHIVERS property. Determines what this Archiver should archive. Alternatives are: "REQUEST", "RESPONSE" or "REQUEST_AND_RESPONSE". Default is "RESPONSE".
Example: ARCHIVER0.ARCHIVE_OF_TYPE=REQUEST_AND_RESPONSE

Currently archiving of requests is only supported by TimeStampSigner and MSAuthCodeTimeStampSigner.

ARCHIVERx.USE_FORWARDED_ADDRESS = Where "x" is the index of the archiver in the ARCHIVERS property. If this property is set to "true", IP addresses in the comma-separated list given in the X-Forwarded-For header is used as the remote IP stored in the archive in case this header is set, by default the last forwarded address is used. If the header is not included, the IP address the request comes from is used (the same behavior as when this property isn't set, or set to "false"). This is useful when running a proxy in front of SignServer, to record the orginal IP address of the client, instead of the proxy's IP address. Defaults to "false".

ARCHIVERx.MAX_FORWARDED_ADDRESSES = Where "x" is the index of the archiver in the ARCHIVERS property. Sets the maximum number of forwarded addresses to add the remote IP in the archive, counted from the end. The addresses is listed in the order they appear in the header. The default value is 1 (only include the last address). This property is only used when USE_FORWARDED_ADDRESS is set to "true".

ARCHIVERx.INCLUDE_DIRECT_ADDRESS = Where "x" is the index of the archiver in the ARCHIVERS property. If this property is set to "true", and USE_FORWARDED_ADDRESS is also set to "true", the host IP address (direct address) is added to the end of the list of forwarded addresses. This address is not taken into account for the number of forwarded addresses by MAX_FORWARDED_ADDRESSES above. The default is "false" (not included). This property is only used when USE_FORWARDED_ADDRESS is set to "true".

*** ArchiveData table ***

The exact database table structure is described in the SQL scripts available under doc/sql-scripts/.

uniqueId Primary key of the archive row.
archiveData The actual data encoded in an Base64PutHashMap.
archiveId Some identifier for the produced item.
For the TimeStampSigner this would be the Time stamp token serial number (in hex encoding). Other signers might use a hash of the request document and the transaction ID.
requestCertSerialnumber Serial number (in hex encoding) of the client certificate (if any) used by the client.
Notice: This only indicates that the client certificate where used when establishing the connection to the web server and not wither the worker required a client certificate or not or if it did any additional checks if the authenticated client was authorized.
requestIP By default IP address of the host connecting. When USE_FORWARDED_ADDRESS is set to "true" this contains a list of forwarded IP addresses from X-Forwarded-For optionally ending with the host address (when setting INCLUDE_DIRECT_ADDRESS to "true").
requestIssuerDN Issuer DN (in string representation) of the issuer of the client certificate (if any) used by the client.
See also note about requestCertSerialnumber.
signerId ID of the worker handling the request.
time Timestamp (number of milliseconds since January 1 1970 00:00:00) on the SignServer host when the item where archived.
type The type of archivable item. Currently this could be:
  • 0 - TYPE_RESPONSE
  • 1 - TYPE_REQUEST
dataEncoding Type of encoding used for the archiveData. Currently this could be:
  • NULL - DATA_ENCODING_XML
  • 0 - DATA_ENCODING_XML
  • 1 - DATA_ENCODING_BASE64
Where DATA_ENCODING_XML uses the Base64PutHashMap and DATA_ENCODING_BASE64 uses a plain Base64 encoding of the binary data.

Base64DatabaseArchiver

This Archiver archives to the database table "ArchiveData" using the same datasource as SignServer uses for accessing the database for its configuration etc. It is similar to the OldDatabaseArchiver but does not use an XML structure for storing the data. Instead the data is simply base64 encoded.

In the "dataEncoding" column this format is indicated as DATA_ENCODING_BASE64.

The fully qualified class name is: org.signserver.server.archive.base64dbarchiver.Base64DatabaseArchiver

*** Worker Properties ***

ARCHIVERx.ARCHIVE_OF_TYPE = Same as for OldDatabaseArchiver above.

Accounters

See also the section about the ACCOUNTER worker property that can be set to one of the available Accounter implementations described below.

NoAccounter

The fully qualified class name is: org.signserver.server.NoAccounter

Accounter not doing anything. Sets purchased to true.

GlobalConfigSampleAccounter

The fully qualified class name is: org.signserver.server.GlobalConfigSampleAccounter

Accounter holding the clients balances internally in the global configuration.
Note: This Accounter is only for demonstration purposes and will not work under load. A production Accounter should use an implementation using a proper database.

*** Global Configuration Properties ***

GLOBALCONFIGSAMPLEACCOUNTER_USERS = Mapping from credential to account name
GLOBALCONFIGSAMPLEACCOUNTER_ACCOUNTS = Mapping from account name to a balance

Example:

GLOBALCONFIGSAMPLEACCOUNTER_USERS = user1,password:account1; user2,password2:account2
GLOBALCONFIGSAMPLEACCOUNTER_ACCOUNTS = account1:14375; account2:12
                        

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.

See also doc/DEVELOP.txt.

Custom modules

Custom code can be included in the SignServer build process by placing the projects under the modules directory and adhere to the modules contract.

First, the property modules.build.includes in res/modules-project.properties defines which projects that should be included in the build process. All projects with a folder name starting with SignServer-Module-*, SignServer-ejb* or SignServer-war are included. Other patterns can be included by setting a property extra.modules.build.includes.

Second, in the project folder there should be an Ant script called build.xml.

Third, if the project should be called it should define the properties:

  • modulename: The name of the module. Will be used as prefix to the enable-property. Example: module.pdfsigner (the enable property will then be module.pdfsigner.enabled)
  • clean.available: True if the "clean" target should be called when the rest of SignServer is getting cleaned.
  • dist-module.available: True if the "dist-module" target should be called when SignServer is getting built
Example:

<property name="modulename" value="module.pdfsigner"/>
<property name="clean.available" value="true"/>
<property name="dist-module.available" value="true"/>    
                

Forth, the dist-module target should take care of moving all distributables to the ../../lib directory and if the module should be deployed as part of the signserver.ear file a module descriptor should be placed in ../../mods-available. The name of the descriptor file should be priority_modulename.properties where priority is the order in which the module should be built and modulename is the name as defined by the property with the same name.

The priorities are basically like this:

  • 10: Essential core modules (like signserverejb and signservercommon)
  • 20: Other core modules (like web services)
  • 30: Other core modules (like web components etc)
  • 40: Other modules (like signers/validators etc)

The module descriptor can contain:

  • module.name: Same as the modulename property
  • module.type: The type of the module. "lib" if the module should be put in signserver.ear/lib, "ejb" if it is an EJB module or "war" if it is and WAR module.
  • to.root: Comma separated list of files to move to the root of signserver.ear. Basedir is SIGNSERVER_HOME and all files should be taken from lib/ (not modules/ as it is not available in the binary distribution).
  • to.lib: Same as to.root but for jar files to be moved to signserver.ear/lib/.
  • module.ejb: Only if module.type is "ear" or "war". The name of the enterprise module file (example: signserver.war).
  • module.web.web-uri: Only if module.type is "war". The name to put in the web-uri part of the application.xml for this enterprise module.
  • module.web.context-root: Only if module.type is "war". The name to put in the context-root part of the application.xml for this enterprise module.
  • postprocess.files: Optionally. Comma separated list of property name prefixes for each file to postprocess (example: postprocess.file1)
  • postprocess.file1.src: Only if postprocess.files specified. Path of file to postprocess (relative to SIGNSERVER_HOME/lib/, example: SignServer-ejb-SignServerWS.jar)
  • postprocess.file1.includes: Only if postprocess.files. Ant includes pattern with files in the jar to postprocess (example: META-INF/ejb-jar.xml)
  • postprocess.file1.dest: Only if postprocess.files specified. Location to put the resulting JAR in the final EAR. Default "" (the root) but should be set to "lib/" for library JARs.
Example (mods-available/40_module.pdfsigner.properties):

module.name=module.pdfsigner
module.type=lib
to.root=
to.lib=lib/ext/1.6/bcprov-jdk.jar,lib/ext/1.6/bctsp-jdk.jar,lib/ext/cert-cvc.jar,lib/ext/commons-collections-3.2.jar,lib/ext/commons-io-1.4.jar,lib/ext/commons-lang-2.5.jar,lib/ext/commons-logging-1.1.1.jar,lib/ext/ejbca-util.jar,lib/ext/log4j-1.2.14.jar,lib/ext/module/pdfsigner/itext/itext.jar,lib/SignServer-Common.jar,lib/SignServer-ejb-interfaces.jar,lib/SignServer-Module-PDFSigner.jar
                

Example (mods-available/20_signserverws.properties):

module.name=signserverws
module.type=ejb
module.ejb=SignServer-ejb-SignServerWS.jar
to.root=lib/SignServer-ejb-SignServerWS.jar
to.lib=lib/ext/1.6/bcprov-jdk.jar,lib/ext/1.6/bctsp-jdk.jar,lib/ext/cert-cvc.jar,lib/ext/commons-collections-3.2.jar,lib/ext/commons-io-1.4.jar,lib/ext/commons-lang-2.5.jar,lib/ext/commons-logging-1.1.1.jar,lib/ext/ejbca-util.jar,lib/ext/log4j-1.2.14.jar,lib/SignServer-Common.jar,lib/SignServer-ejb-interfaces.jar
postprocess.files=postprocess.file1
postprocess.file1.src=SignServer-ejb-SignServerWS.jar
postprocess.file1.includes=META-INF/ejb-jar.xml
                

Custom sub modules

In the same way as described in the previous chapter about custom modules, it is also possible to have custom sub modules. This is done by creating a folder under 'modules' with a name starting with 'mod-' and include a build.xml as in the example below. It would then be possible to include any number of additional modules in this folder.

Sample modules/mod-mysigners/build.xml:

<project name="MySigner Modules" default="dist-module" basedir=".">
    <description>Builds sub modules in mysigner</description>
    <property name="platform.project.dir" location="../../"/>
    <property name="signserver.home" location="../../"/>
    <property file="build.properties"/>
    <property file="${platform.project.dir}/conf/signserver_build.properties"/>
    <property file="${platform.project.dir}/signserver_build.properties"/>
    
    <!-- Clean selected modules in this sub module -->
    <target name="-do-clean-module">
        <echo>Cleaning ${ant.project.name}</echo>
        <subant target="-do-clean-module" failonerror="true">
            <fileset dir="." includes="${modules.clean.includes}"/>
         </subant>
    </target>
    <target name="clean" depends="-do-clean-module"/>
    
    <!-- Build selected modules in this sub module -->
    <target name="-do-module">
        <echo>Building ${ant.project.name}</echo>
        <subant target="-do-module" verbose="false">
            <fileset dir="." includes="${modules.build.includes}"/>
        </subant>
    </target>
    <target name="dist-module" depends="-do-module"/>
    
    <!-- Build selected systemtests in this sub module -->
    <target name="-do-test-module">    
        <echo>Building systemtests for ${ant.project.name}</echo>
        <subant target="-do-test-module" verbose="false">
            <fileset dir="." includes="${build.systemtest.includes}" excludes="${build.systemtest.excludes}"/>
        </subant>
    </target>
    <target name="build-systemtests" depends="-do-test-module"/>
    
    <!-- Run tests in this sub module -->
    <target name="test">
        <echo>Running tests for ${ant.project.name}</echo>
        <subant target="test">
            <fileset dir="." includes="${tests.modules.includes}"/>
        </subant>
    </target>
</project>

Custom CLI

The SignServer AdminCLI or ClientCLI can be extended by putting additional JAR files with custom implementations of the ClientCommandFactory or AdminCommandFactory interfaces on the classpath. The implementation classes should be listed in the JAR files under META-INF/services in a file with the full class name of the interface. See SignServer-Client-ValidationCLI as an example.

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;
                        

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".

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
  • healthcheck.maintenancefile=/path/to/signserver/maintenance.properties (where /path/to/signserver is the path where SignServer is located)

For the Database CLI tests to run successfully you will need to put the JDBC driver for your database as lib/ext/jdbc/jdbc.jar.

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.

If SignServer is configured to run without database some tests needs to be excluded by running like this:

bin/ant test:run -Dexcludes="**/ArchivingCLITest*,**/Base64DatabaseArchiverTest*,**/OldDatabaseArchiverTest*,**/ArchiveTest*,**/AuditLogCLITest*,**/DatabaseCLITest*,**/VerifyLogCommandTest*"
                    
*** System tests with HSM ***

To run system tests with an HSM create an properties file in SIGNSERVER_HOME called test-config.properties containing the PKCS#11 configuration including the key alias for an existing RSA key-pair:

test.p11.sharedlibrary=/opt/ETcpsdk/lib/linux-x86_64/libcryptoki.so
test.p11.slot=1
test.p11.pin=foo123
test.p11.existingkey1=mykey001
                        

The tests can be run with:

ant test:p11:run test:report
                        

Random testing

SignServer-Test-Random is a tool for random testing of SignServer. Each test suite has different requirements configured workers in the different worker groups and how many threads that can be used etc. See the source code for further details.

*** Building and running ***

Build from modules/SignServer-Test-Random/ using:

ant jar

It can then be run from SIGNSERVER_HOME using:

bin/randomtest
*** Usage ***
usage: randomtest <options>
Random testing tool
 -randomseed <arg>     Optional. Seed to initialize the pseudo random
                       generator with.
 -testsuite <arg>      Test suite to run. Any of [signWhileUpdatingConfig,
                       signAndCountSignings, signWhileRenewing].
 -threadgroup1 <arg>   Number of threads in group 1.
 -threadgroup2 <arg>   Number of threads in group 2.
 -timelimit <arg>      Optional. Only run for the specified time (in
                       milliseconds).
 -workergroup1 <arg>   First group of workers. Comma separated list of
                       workerId/workerType.
 -workergroup2 <arg>   Second group of workers. Comma separated list of
                       workerId/workerType
 -workergroup3 <arg>   Third group of workers. Comma separated list of
                       workerId/workerType

Sample usages:
a) randomtest -testsuite signWhileUpdatingConfig -workergroup1
5678/xml,5679/tsa,5680/xml -threadgroup1 4 -workergroup2
5677/xml,5678/xml,5679/tsa -threadgroup2 3 -timelimit 30000

b) randomtest -testsuite signAndCountSignings -workergroup1
5678/xml,5679/tsa,5680/xml -threadgroup1 10 -timelimit 30000

c) randomtest -testsuite signWhileRenewing -workergroup1 300/xml
-workergroup2 301/xml,302/xml -threadgroup1 5 -workergroup3 309/renew
-timelimit 20000

Available worker types:
- workerType can be any of [xml, tsa, renew]

Test suite: signAndCountSignings
- Signs documents with the workers from group 1 with the number of threads
defined for group 1
- Pauses signings and counts performed signings a compares to the key
usage counter value
- Notice that it is assumed that all workers use the same key-pair

Test suite: signWhileUpdatingConfig
- Signs documents with the workers from group 1 with the number of threads
defined for group 1
- Increases a counter in the configuration of group 2
- Notice that the size of thread group 2 must be equal to the number of
workers in group 2

Test suite: signWhileRenewing
- Signs documents with the workers from group 1 with the number of threads
defined for group 1
- Renews signers from group 2 using the one renewal worker in group 3
- Notice that group 3 should only include one renewal worker
                        

Stress testing

SignServer-Test-Performance is a tool for performance testing of SignServer. Currently it contains only one test suite for testing time stamping. See the source code for further details.

*** Building and running ***

Build from modules/SignServer-Test-Performance/ using:

ant jar

It can then be run from SIGNSERVER_HOME using:

bin/stresstest
*** Usage ***
usage: stresstest <options>
Performance testing tool
 -maxwaittime <arg>     Maximum number of milliseconds for a thread to
                        wait until issuing the next time stamp.
                        Default=100
 -processurl <arg>      URL to process servlet (for the DocumentSigner1
                        testsuite).
 -statoutputdir <arg>   Optional. Directory to output statistics to. If
                        set, each threads creates a file in this directory
                        to output its response times to. The directory
                        must exist.
 -testsuite<arg>       Test suite to run. Any of [TimeStamp1, DocumentSigner1].
 -threads <arg>         Number of threads requesting time stamps.
 -timelimit <arg>       Optional. Only run for the specified time (in
                        milliseconds).
 -tsaurl <arg>          URL to timestamp worker to use.
 -warmuptime <arg>      Don't count number of signings and response times
                        until after this time (in milliseconds). Default=0
                        (no warmup time).
 -worker <arg>    Worker name or ID to use (with the DocumentSigner1 test suite).
 -workerurl <arg> URL to worker servlet (for the DocumentSigner1
                        test suite).

Sample usages:
a) stresstest -testsuite TimeStamp1 -threads 4 -tsaurl
http://localhost:8080/signserver/tsa?workerId=1
b) stresstest -testsuite TimeStamp1 -threads 4 -maxwaittime 100
-statoutputdir ./statistics/ -tsaurl
http://localhost:8080/signserver/tsa?workerId=1
c) stresstest -testsuite DocumentSigner1 -threads 4 -processurl
http://localhost:8080/signserver/process -worker PDFSigner -infile
test.pdf
d) stresstest -testsuite DocumentSigner1 -threads 4 -processurl
http://localhost:8080/signserver/process -worker XMLSigner -data "<root/>"
e) stresstest -testsuite DocumentSigner1 -threads 4 -workerurl
http://localhost:8080/signserver/worker -worker 1 -data "<root/>"
              			

When finished (after time limit expires, or process is stopped using control+c) a statistic overview is printed containing number of signings, and statistics (average, minimum, and maximum) for response times.

Miscellaneous

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 non-persistent local (per JVM) status information (properties) with optional expiration times. After the expiration time the property is not returned. The value is also not preserved among server restarts.

This could be used by having workers read the status from the repository while an external (or internal) service periodically updates it. The (optional) expiration time on the values makes it possible to detect if an periodic service has failed to update the value within the specified time.

From the Admin CLI the status repository can be controlled using the getstatusproperties, getstatusproperty and setstatusproperty commands.

Logging

SignServer uses Log4j for debug logging and the security events logger from CESeCore for system/audit logging. In addition the worker logger (transaction log) can be configured to use Log4j and/or the security events logger.

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.

*** AllFieldsWorkerLogger ***

The default worker logger for most workers. Can be used during testing to find which fields a worker logs and then changed to the PatternWorkerLogger with only does fields that are of interest chosen.
LOGLEVEL_DEFAULT sets the level at which the logger will do log output. These are specified as standard Log4J levels (FATAL, ERROR, WARNING, INFO, DEBUG, and TRACE), if not set, it defaults to INFO.

WORKERLOGGER=org.signserver.server.log.AllFieldsWorkerLogger
LOGLEVEL_DEFAULT=INFO
                        
*** SecurityEventsWorkerLogger ***

Worker logger using the CESeCore security events logger. This logger included all fields in the additionalDetails fields in the audit log, except the worker ID, which is mapped to searchDetail2.

The properties LOGINCLUDEFIELDS and LOGEXCLUDEFIELDS can be used to restrict the fields included in additionalDetails by explicitly setting a comma-separated list of field names. Only one of these options can be set at a time.

WORKERLOGGER=org.signserver.server.log.SecurityEventsWorkerLogger
                        
*** PatternWorkerLogger ***

The LOGLEVEL_DEFAULT property has the same behavior as for the AllFieldsWorkerLogger.

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};
LOGLEVEL_DEFAULT=INFO
                        
*** DefaultTimeStampLogger ***

Pattern logger with a default log order suitable for logging time-stamp requests. This logger is the default logger used by the TimeStampSigner.

WORKERLOGGER=org.signserver.module.tsa.DefaultTimeStampLogger
                        
*** NullWorkerLogger ***

Worker logger that does not log anything.

WORKERLOGGER=org.signserver.server.log.NullWorkerLogger                            
                        
*** CustomTimeStampLogger1 ***
WORKERLOGGER=org.signserver.module.tsa.CustomTimeStampLogger1
                        
*** FileWorkerLogger ***

Worker logger that writes the log values to a worker-specific log file (the logger logs all fields, similar to AllFieldsWorkerLogger.
This logger is mainly intended for use by unit tests, and is not thread safe.

WORKERLOGGER=org.signserver.server.log.FileWorkerLogger
LOG_FILE_PATH=/path/to/logfile
						

System Log

The purpose of the system log is to log events concerning the SignServer application but not necessarily related to any signing transaction (that is covered by the Worker Log). The audit log covers key and certificate management events, status properties updates (for instance for the status of the time source) and to some extent also configuration changes. For details see the table of events below.
From version 3.4.0 SignServer uses the CESeCore library to perform audit logging.

*** Available log events ***
Services
SIGNSERVER_STARTUP

Logged at startup of the SignServer application.

VERSION: The version of SignServer.

Example:

EVENT: SIGNSERVER_STARTUP; MODULE: SERVICE; ADMINISTRATOR: null; ISSUER: null; SERIAL_NUMBER: null; WORKER_ID: null; VERSION: SignServer 3.3.0alpha12; REPLY_TIME:1350562045545

SIGNSERVER_SHUTDOWN

Logged at shutdown of the SignServer application.

VERSION: The version of SignServer.

Example:

EVENT: SIGNSERVER_SHUTDOWN; MODULE: SERVICE; ADMINISTRATOR: null; ISSUER: null; SERIAL_NUMBER: null; WORKER_ID: null; VERSION: SignServer 3.3.0alpha12; REPLY_TIME:1350562045545

Global configuration
SET_GLOBAL_PROPERTY

Logged when a global configuration property was updated.

GLOBALCONFIG_PROPERTY: The property that was updated.
GLOBALCONFIG_VALUE: The new value of the property.

Example:

EVENT: SET_GLOBAL_PROPERTY; MODULE: GLOBAL_CONFIG; ADMINISTRATOR: null; ISSUER: null; SERIAL_NUMBER: null; WORKER_ID: null; GLOBALCONFIG_VALUE: TESTVALUE47; GLOBALCONFIG_PROPERTY: GLOB.TESTPROPERTY47; REPLY_TIME:1350657202153

REMOVE_GLOBAL_PROPERTY

Logged when a global configuration property was removed.

GLOBALCONFIG_PROPERTY: The property that was removed.

Example:

EVENT: REMOVE_GLOBAL_PROPERTY; MODULE: GLOBAL_CONFIG; ADMINISTRATOR: null; ISSUER: null; SERIAL_NUMBER: null; WORKER_ID: null; GLOBALCONFIG_PROPERTY: GLOB.TESTPROPERTY47; REPLY_TIME:1350657202444

GLOBAL_CONFIG_RELOAD

Logged when the global configuration was reloaded from the database.

Example:

EVENT: GLOBAL_CONFIG_RELOAD; MODULE: GLOBAL_CONFIG; ADMINISTRATOR: null; ISSUER: null; SERIAL_NUMBER: null; WORKER_ID: null; REPLY_TIME:1350657202593

GLOBAL_CONFIG_RESYNC

Logged when the resync command was executed.

Example:

EVENT: GLOBAL_CONFIG_RESYNC; MODULE: GLOBAL_CONFIG; ADMINISTRATOR: null; ISSUER: null; SERIAL_NUMBER: null; WORKER_ID: null; REPLY_TIME:1350894343902

Worker configuration
SET_WORKER_CONFIG

Logged when a worker's configuration was updated by adding and/or removing and/or changing any values.

WORKER_ID: The ID of the worker.

Changes in worker properties are logged with prefixes added/changed/removed followed by a colon and the property name a colon and the property value.
Several property changes can occur in one log line (see examples below).
Authorized clients are shown as a property with the name authorized_client.

Example:

EVENT: SET_WORKER_CONFIG; MODULE: WORKER_CONFIG; ADMINISTRATOR: null; ISSUER: null; SERIAL_NUMBER: null; WORKER_ID: 100; added:FOO: bar; REPLY_TIME:1350657202773

EVENT: SET_WORKER_CONFIG; MODULE: WORKER_CONFIG; ADMINISTRATOR: null; ISSUER: null; SERIAL_NUMBER: null; WORKER_ID: 100; changed:FOO: newvalue; REPLY_TIME:1350657202873

EVENT: SET_WORKER_CONFIG; MODULE: WORKER_CONFIG; ADMINISTRATOR: null; ISSUER: null; SERIAL_NUMBER: null; WORKER_ID: 100; removed:FOO: newvalue; REPLY_TIME:1350657202873

EVENT: SET_WORKER_CONFIG; MODULE: WORKER_CONFIG; ADMINISTRATOR: null; ISSUER: null; SERIAL_NUMBER: null; WORKER_ID: 100; added:FOO: bar; changed:BAR: newvalue; REPLY_TIME:1350657202873

EVENT: SET_WORKER_CONFIG; MODULE: WORKER_CONFIG; ADMINISTRATOR: null; ISSUER: null; SERIAL_NUMBER: null; WORKER_ID: 100; added:authorized_client: SN: 1234567890, issuer DN: CN=Test; REPLY_TIME:1350657202873

CERTINSTALLED

Logged when a certificate was uploaded to the worker configuration.

WORKER_ID: The ID of the worker.
CERTIFICATE: The certificate in PEM format.
SCOPE: If the setting was at GLOBAL or NODE scope.
NODE: The ID of the node if the setting was at NODE scope, otherwise not available.

Example:

EVENT: CERTINSTALLED; MODULE: WORKER_CONFIG; ADMINISTRATOR: null; ISSUER: null; SERIAL_NUMBER: null; WORKER_ID: 100; CERTIFICATE: Subject: CN=Anyone
Issuer: CN=Anyone
-----BEGIN CERTIFICATE-----
MIIBnTCCAQagAwIBAgIIWWNYSOeuN+swDQYJKoZIhvcNAQEFBQAwETEPMA0GA1UE
AwwGQW55b25lMB4XDTEyMTAxOTE0MzMyM1oXDTEzMTAxOTE0MzMyM1owETEPMA0G
A1UEAwwGQW55b25lMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCDE9GElbJd
e74WmIpPSsIF9r5vv0oH6WWo7n31goR1zMIHJPC9V1mpwQZ6C0uCHCV2ZvqQIIAE
ZQM7mgbPfxjCF74RqKzScZlOSaHnvdf7zCWpYraVrIDt9Wg3HMxye0/L3cCImmkY
FkFtabtoa5UuPZObdIt154Yg+GpGB8aPBwIDAQABMA0GCSqGSIb3DQEBBQUAA4GB
AHm3oAUHwM0KwMcEUwWouE0f4+UK6ZvYvxLAgiCVZQnPImcqX1oBl+iFV59FlsXj
rqoQYJROxIeV0ByGeyBYXqvgTw1YtdqoR+wKmiymjn/lynmTh1fQMcFoUouGfubX
EK4rfPBXEl33gKbsO5aeMHd5iF2jtx7RfYMsOuHKoDSe
-----END CERTIFICATE-----
; SCOPE: GLOBAL; REPLY_TIME:1350657204367

CERTCHAININSTALLED

Logged when a certificate chain was uploaded to the worker configuration.

WORKER_ID: The ID of the worker.
CERTIFICATECHAIN: The certificates in PEM format.
SCOPE: If the setting was at GLOBAL or NODE scope.
NODE: The ID of the node if the setting was at NODE scope, otherwise not available.

Example:

EVENT: CERTCHAININSTALLED; MODULE: WORKER_CONFIG; ADMINISTRATOR: null; ISSUER: null; SERIAL_NUMBER: null; WORKER_ID: 100; CERTIFICATECHAIN: Subject: CN=Signer,C=SE
Issuer: CN=Issuer,C=SE
-----BEGIN CERTIFICATE-----
MIIBdjCCASCgAwIBAgIIE+fXOs/SAwMwDQYJKoZIhvcNAQEFBQAwHjEPMA0GA1UE
AwwGSXNzdWVyMQswCQYDVQQGEwJTRTAeFw0xMjEwMjIwNzQ1MDZaFw0xMzEwMjIw
NzQ1MDZaMB4xDzANBgNVBAMMBlNpZ25lcjELMAkGA1UEBhMCU0UwgZ8wDQYJKoZI
hvcNAQEBBQADgY0AMIGJAoGBAKpX5psdaL5CHAKSxoOvB12Ie8iUb/mX6ikF8jfu
zrbwVgf6bX0RCUnD+v+t9vY7byz+nN32KnmGluNGdBFdM1Ug9Oc+64ZNBbgZi9mi
cHnKMDLLSECBY2Nux62PZejp5SwtzpjFymt3TMCtRr4UHGu3zkuqLLCHFlGRdvdo
MPQ9AgMBAAEwDQYJKoZIhvcNAQEFBQADQQADlInGm9AujZfL+1kM7ehaKyKKencF
fp6YGElOpGEplxxIwgmVc0iYKv4rCkfUAysYL6l3AC+VLK1asxkpEJc1
-----END CERTIFICATE-----
Subject: CN=Issuer,C=SE
Issuer: CN=Issuer,C=SE
-----BEGIN CERTIFICATE-----
MIIBMTCB3KADAgECAggbfKZHs8ttKDANBgkqhkiG9w0BAQUFADAeMQ8wDQYDVQQD
DAZJc3N1ZXIxCzAJBgNVBAYTAlNFMB4XDTEyMTAyMjA3NDUwNloXDTEzMTAyMjA3
NDUwNlowHjEPMA0GA1UEAwwGSXNzdWVyMQswCQYDVQQGEwJTRTBcMA0GCSqGSIb3
DQEBAQUAA0sAMEgCQQCpgzxJ6r6D1cP8v1AB88pJsCwi0SJdeRSGYydYYBOafJk0
fpqxJCwaiFS3tt9OkWUAXzcixv5+sItkEuEOpmp7AgMBAAEwDQYJKoZIhvcNAQEF
BQADQQCC5NG3eWx/mXXKZmePOvZEIwyqWHOwzsBB174gkzlyhOdiOr3YwVihyebI
VAfkEktRrO04Hi5eLR+AxW7EVz6l
-----END CERTIFICATE-----
; SCOPE: GLOBAL; REPLY_TIME:1350891906417

KEYSELECTED

Logged when the key-pair to use was selected by changing the value of the DEFAULTKEY worker property.

WORKER_ID: The ID of the worker.
KEYALIAS: The new key alias.
SCOPE: If the setting was at GLOBAL or NODE scope.
NODE: The ID of the node if the setting was at NODE scope, otherwise not available.

Example:

EVENT: KEYSELECTED; MODULE: WORKER_CONFIG; ADMINISTRATOR: null; ISSUER: null; SERIAL_NUMBER: null; WORKER_ID: 100; KEYALIAS: ts_key00002; SCOPE: GLOBAL; REPLY_TIME:1350891907048

Key management
KEYGEN

Logged when a new key-pair was generated using the built-in key generation command.

WORKER_ID: The ID of the worker.
KEYALIAS: The new key alias.
KEYSPEC: The key specification (ie. RSA/DSA bit length or EC curve).
KEYALG: The key algorithm.

Example:

EVENT: KEYGEN; MODULE: KEY_MANAGEMENT; ADMINISTRATOR: null; ISSUER: null; SERIAL_NUMBER: null; WORKER_ID: 5676; KEYALIAS: ts_key00004; KEYSPEC: 2048; KEYALG: RSA; REPLY_TIME:135089190791

KEYTEST

Logged when the key test command was executed and a test signing with either the specified key or all keys in the slot if that was specified.

WORKER_ID: The ID of the worker.
KEYALIAS: Alias of the the key to test or "all" to test all available keys in the slot.
TESTRESULTS: The test report with an entry for each tested key.

Example:

EVENT: KEYTEST; MODULE: KEY_MANAGEMENT; ADMINISTRATOR: null; ISSUER: null; SERIAL_NUMBER: null; WORKER_ID: 47; KEYALIAS: all; TESTRESULTS: KeyTestResult{alias=tsu47_key00005, success=true, status=, publicKeyHash=979359e5261112b11fac341962bec1e7e6052d9e}
KeyTestResult{alias=key5, success=true, status=, publicKeyHash=46b264e4892ef2e4fd9616e4927534ca3597fd9c}
KeyTestResult{alias=key3, success=true, status=, publicKeyHash=ae64792f1f50e23eb54bf79d46d819bc07db2d79}
KeyTestResult{alias=key2, success=true, status=, publicKeyHash=b1317f363e6124a8e15bba8c1adb9f20b2f4ef59}
KeyTestResult{alias=TS Signer 1, success=true, status=, publicKeyHash=8f6dfccdcea931d4deee9466f43c0eb0e7f4d8b1}
; REPLY_TIME:1350564289165

GENCSR

Logged when a certificate signing request (CSR) was generated.

WORKER_ID: The ID of the worker.
CSR: Base64 encoded CSR (typically in PKCS#10 format).

Example:

EVENT: GENCSR; MODULE: KEY_MANAGEMENT; ADMINISTRATOR: null; ISSUER: null; SERIAL_NUMBER: null; WORKER_ID: 5676; CSR: MIIBYDCBygIBADAjMRQwEgYDVQQDDAtUUyBTaWduZXIgMTELMAkGA1UEBhMCU0Uw
gZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAJt8F51wD+QcX+WLyIxjWu3at3q+
IiJrL5jIenmggUhjOLHGHOStoNOiYEQAaiiTZ623m9y7O3zhqFdAdWZg+JrfsHQJ
pjKV9RgvJznl6yk/K54BWOBgqjvbloAUGtn8y8Hf+5DYJUJNFqrzvRLcmCQ9JU0H
mgSmEIqgOIwBL3oBAgMBAAEwDQYJKoZIhvcNAQEFBQADgYEAer5hr/cUYx4jy0XO
N4U8sP/2gSFppytx9dn5BamVBLjDkcML8B3c9u9omDPebd+LEsCU+HCmYN9xHkSS
Ei8lcAqyVv+SDLEmvE8gnrPFR/J7uADCRayLVQumW6/YpVO/sFEGuM6rgnn8ZJmW
X2lhvJ4V1UhlkEAeyIQ861U3IgE=; REPLY_TIME:1350891907981

KEYREMOVE

Logged when a key was removed or an removal attempt was performed.

WORKER_ID: The ID of the worker.
KEYALIAS: The key alias of the key removed.
SUCCESS: True if the key was removed or false if the removal failed or if removal was not supported by the token.

Example:

EVENT: KEYREMOVE; MODULE: KEY_MANAGEMENT; ADMINISTRATOR: CLI user; ISSUER: null; SERIAL_
NUMBER: null; WORKER_ID: 20003; KEYALIAS: signKey000002 SUCCESS: true; REPLY_TIME:1391008847962

Status Repository
SET_STATUS_PROPERTY

Logged when a status property was updated.

STATUSREPO_PROPERTY: The updated property.
STATUSREPO_VALUE: The new property value.
STATUSREPO_EXPIRATION: Expiration time for the status property (timestamp), if any.

Example:

EVENT: SET_STATUS_PROPERTY; MODULE: STATUS_REPOSITORY; ADMINISTRATOR: null; ISSUER: null; SERIAL_NUMBER: null; WORKER_ID: null; STATUSREPO_EXPIRATION: 1350891909366; STATUSREPO_PROPERTY: TEST_PROPERTY1; STATUSREPO_VALUE: TESTVALUE47; REPLY_TIME:1350891908372

Worker processing
PROCESS

Logged for events regarding worker processing but when a worker logger can not be used because the requested worker does not exist etc.

WORKER_ID: The ID of the worker or empty in case of non existing worker.
Worker logger fields: All fields available to the worker logger.

Example:

EVENT: PROCESS; MODULE: WORKER; ADMINISTRATOR: null; ISSUER: null; SERIAL_NUMBER: null; WORKER_ID: null; LOG_ID: db517726-ff0d-40dd-8f2b-2297925cb4d3; CLIENT_IP: 127.0.0.1; PROCESS_SUCCESS: false; REQUEST_LENGTH: 0; XFORWARDEDFOR: null; FILENAME: noname.dat; 
REQUEST_FULLURL: http://localhost:8080/signserver/process?null; LOG_TIME: 1350628977410; WORKER_ID: 0; EXCEPTION: No such worker: 0; REPLY_TIME:1350628977411

CESeCore Security Events Logger

The default logging implementation, org.signserver.server.log.SignServerLog4jDevice uses Log4J and a similar logging format as the old SystemLogger.

*** Signed log ***
Note
This is a SignServer Enterprise Edition (EE) feature.

An example configuration for CESeCore is provided in conf/cesecore.properties.sample.

To enable signed audit logs configure conf/databaseprotection.properties (see conf/databaseprotection.properties.sample). And set the following which enables signing of the AuditRecordData table as well as verification of the log entries queried using for instance the CLI or GUI:

databaseprotection.enablesign.AuditRecordData = true
databaseprotection.enableverify.AuditRecordData = true
                        

Configure a key-pair to use for signing and verification of the log with something similar to this:

databaseprotection.keyid = 400
databaseprotection.keyid.0 = 400
databaseprotection.keylabel.0 = dbProtKey
databaseprotection.classname.0 = org.cesecore.keys.token.PKCS11CryptoToken
databaseprotection.properties.0 = sharedLibrary=/opt/utimaco/Software/PKCS11/lib/Linux-x86-64/libcs2_pkcs11.so, slotLabelType=SLOT_NUMBER, slotLabelValue=1
databaseprotection.data.0 =
databaseprotection.tokenpin.0 = userpin1
databaseprotection.version.0 = 2
                        

Note: each SignServer node writing to the audit log needs to use different node IDs. By default the hostname is used. If multiple instances are running from the same host set the node id manually in conf/cesecore.properties as cluster.nodeid.

If enableverify is set to true, all individual log entries that are displayed using CLI, GUI or over web services are verified at the server side and in case of inconsistent signatures an error message is displayed. This verification will not discover missing log entries. To verify the complete log for all nodes as well as detect gaps in the sequence numbering, run the Database CLI.

*** AuditRecordData table ***

The exact database table structure is described in the SQL scripts available under doc/sql-scripts/.

Friendly Name Table Name Description
Time timeStamp

Time stamp (number of milliseconds since January 1, 1970, 00:00:00 GMT). Example:

1359550503607
Outcome eventStatus

Status/result of the operation performed. Can be:

  • SUCCESS
  • FAILURE
  • VOID
Event eventType

The event. Some examples:

  • SIGNSERVER_STARTUP
  • SET_GLOBAL_PROPERTY
  • SET_WORKER_CONFIG
  • KEYGEN
  • PROCESS
Module module

The source module of the event. Some examples:

  • SERVICE
  • GLOBAL_CONFIG
  • WORKER_CONFIG
  • KEY_MANAGEMENT
  • WORKER
  • STATUS_REPOSITORY
Service service

The service performing the operation. Some examples:

  • CORE
  • SIGNSERVER
  • EJBCA
Admin Subject authToken

Information about which administrator performed the operation.

Subject DN from the administrator's certificate if the operation was performed over web services, "CLI User" if the EJB remote interface was used, the name of the service if it was an internal operation or "Client User" if the request came from a client.

Some examples:

C=SE, O=My Organization, CN=Admin 1
CLI User
StartServicesServlet.init
Client User
Admin Serial Number searchDetail1

Information about which administrator performed the operation.

Certificate serial number for the administrator performing the operation (if available). Example:

4a3442e98e3ce428
Admin Issuer customId

Information about which administrator performed the operation.

Issuer DN from the administrator's certificate (if available). Example:

C=SE, O=My Organization, CN=AdminCA1
Worker ID searchDetail2

ID of worker involved in the operation (if any). Example:

71
Node nodeId

ID of the node (typically the hostname if not explicitly specified). Example:

dsstsa1.example.com
Details additionalDetails

Additional key-value pairs with information about the operation encoded with Java XML serialization. Example:

<?xml version="1.0" encoding="UTF-8"?>
<java version="1.6.0_24" class="java.beans.XMLDecoder">
 <object class="org.cesecore.util.Base64PutHashMap">
  <void method="put">
   <string>GLOBALCONFIG_PROPERTY</string>
   <string>GLOB.WORKER1.CLASSPATH</string>
  </void>
  <void method="put">
   <string>GLOBALCONFIG_VALUE</string>
   <string>org.signserver.module.xmlsigner.XMLSigner</string>
  </void>
 </object>
</java>
                                    
Sequence Number sequenceNumber

Sequence number of the log entry. Should be unique and sequential per node.

Row Protection rowProtection

Contains information about wich key-pair and signature algorithm that has been used and the actual signature value (if the row is signed). Example:

1:2:400:079b6c2d89671702077b1802ff221cd7c6d71804ea3771b7d5f7cd1...

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{ISO8601} %-5p [%c{1}] %m%n" />
    </layout>
</appender>

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

For GlassFish a similar setup is already configured in SIGNSERVER_HOME/modules/SignServer-Module-Log4j/src/log4j.properties.

For JBoss 7/EAP6 the following can be edited in JBOSS_HOME/standalone/configuration/standalone.xml:

<subsystem xmlns="urn:jboss:domain:logging:1.2">
    ...
    <periodic-rotating-file-handler name="SignServer" autoflush="true">
        <formatter>
            <pattern-formatter pattern="%d{HH:mm:ss,SSS} %-5p [%c] (%t) %s%E%n"/>
        </formatter>
        <file relative-to="jboss.server.log.dir" path="signserver.log"/>
        <suffix value=".yyyy-MM-dd"/>
        <append value="true"/>
    </periodic-rotating-file-handler>
    <periodic-rotating-file-handler name="SignServer_audit" autoflush="true">
        <formatter>
            <pattern-formatter pattern="%d{HH:mm:ss,SSS} %-5p [%c] (%t) %s%E%n"/>
        </formatter>
        <file relative-to="jboss.server.log.dir" path="signserver_audit.log"/>
        <suffix value=".yyyy-MM-dd"/>
        <append value="true"/>
    </periodic-rotating-file-handler>

    <logger category="org.signserver">
        <level name="DEBUG"/>
        <handlers>
            <handler name="SignServer"/>
        </handlers>
    </logger>
    <logger category="org.ejbca">
        <level name="DEBUG"/>
        <handlers>
            <handler name="SignServer"/>
        </handlers>
    </logger>
    <logger category="org.cesecore">
        <level name="DEBUG"/>
        <handlers>
            <handler name="SignServer"/>
        </handlers>
    </logger>
    <logger category="org.signserver.server.log.SignServerLog4jDevice">
        <handlers>
            <handler name="SignServer_audit"/>
        </handlers>
    </logger>
    <logger category="org.signserver.server.log.ISystemLogger">
        <handlers>
            <handler name="SignServer_audit"/>
        </handlers>
    </logger>
    ...
</subsystem>             
                    

Status Repository Logging

By default the Status Repository produces a log entry for every update. This can be disabled or changed in the configuration so that only changes are logged. See the property statusrepository.log in signserver_build.properties.sample.

Database Command Line Interface

The SignServer DB CLI can be run against a database. Currently it only supports verifying the audit log.

Building

The DB CLI is built if the property databasecli.enabled=true is specified in signserver_build.properties. It can also be built using:

$ bin/ant -f modules/SignServer-DatabaseCLI/build.xml dist-module
                    

Configuring

Configure the dbcli.* properties in conf/signserver_cli.properties.

Running

There is start-up script available under bin. You might have specify a classpath containing the JDBC connectors for the specific database type. Example:

$ OPTIONAL_CLASSPATH=/usr/share/java/mysql-connector-java.jar bin/signserver-db audit verifylog
                    

SignServer without Database

Since SignServer 3.2.3 it is sometimes possible to operate SignServer without a database management system and instead rely on SignServer to manage persistence using local files.

Notice that all features of SignServer is not supported without having a database and that the performance and scalability characteristics might be different. Currently archiving to database is not supported.

To increase throughput it is recommended to disable the key usage counter as every request would otherwise have to lock and update that file. See the property DISABLEKEYUSAGECOUNTER in the section Limiting the number of signatures.

Configuration

In signserver_build.properties, set database.type to "nodb".

database.type=nodb
					

Set the location for the local file-based database.

database.nodb.location=/path/to/filedb
					

Where the path is some location where SignServer can write files. The default value is empty. If an relative path is used it is most likely relative to the application server's working directory.

This directory should either point to an existing SignServer file database or be completely empty. If the directory is empty, SignServer will create the initial database structure at startup.

Structure of data

The file based database uses a number of files in the specified directory. Read/write synchronization is handled internally in the application and it is thus not support to do manual changes to the files while the application server is running. It is normally also not supported to have multiple application servers running with SignServer using the same database directory.

Migrating to/from database

The recommended way of migrating either to or from an other database management system without setting up all worker configuration from scratch is do use admin command "dumpproperties" to dump the current configuration to a file and then on the new system use the "setproperties" followed by the reload command for every worker id.

Notice: The dumpproperties command will not include the list of authorized clients so those will have to be setup again in the new system. Check with the admin command "listauthorizedclients" if you have any of those.

SignServer TimeMonitor

Note
The SignServer TimeMonitor is an Enterprise Edition feature.

This is an external application that can be used together with the StatusReadingLocalComputerTimeSource for monitoring of the local time and informing SignServer about its state.

In SignServer, either a StatusPropertiesWorker or a TimeMonitorManager is configured for accepting the status updates. The later also supports dynamic configuration of the TimeMonitor.

For details see the TimeMonitor manual (only available in Enterprise Edition).

Installation Packages

See res/install/debian/README.building for instructions for creating Debian packages for SignServer.

Contributed Howtos

Contributed howtos and installation guides can be found under doc/howtos.

  • Installation guide for SignServer 3.1 and RHEL5.3 / CentOS 5.3 by Christophe Sahut called signserver31-rhel5.txt.
  • Installation package for SignServer 3.2.4 and Debian 6.0 contributed by Antoine Louiset called signserver32-debian6-by-antoine-louiset.zip.

References