com.pdftools.crypto.providers.pkcs11.Session Maven / Gradle / Ivy
Show all versions of pdftools-sdk Show documentation
/****************************************************************************
*
* File: Session.java
*
* Description: PDFTOOLS Session Class
*
* Author: PDF Tools AG
*
* Copyright: Copyright (C) 2023 - 2024 PDF Tools AG, Switzerland
* All rights reserved.
*
* Notice: By downloading and using this artifact, you accept PDF Tools AG's
* [license agreement](https://www.pdf-tools.com/license-agreement/),
* [privacy policy](https://www.pdf-tools.com/privacy-policy/),
* and allow PDF Tools AG to track your usage data.
*
***************************************************************************/
package com.pdftools.crypto.providers.pkcs11;
import com.pdftools.sys.*;
import com.pdftools.internal.*;
import java.util.EnumSet;
import java.time.OffsetDateTime;
/**
* A session to a cryptographic device (HSM, USB token, etc.) to perform cryptographic operations
*
* The session can be used to create signature configuration to sign documents.
*
* To acquire a session, the following steps must be performed:
*
* -
* Load the PKCS#11 driver module using {@link Module#load }.
*
* -
* Get the appropriate cryptographic device from the module's {@link Module#getDevices }.
* If it can be assumed that there is only a single device available, the {@link DeviceList#getSingle } can be used.
*
* -
* Create a session to the device using {@link Device#createSession }.
*
*
*/
public class Session extends com.pdftools.crypto.providers.Provider
{
protected Session(long handle)
{
super(handle);
}
/**
* @hidden
*/
public static Session createDynamicObject(long handle)
{
return new Session(handle);
}
/**
* Log in user into the cryptographic device
*
* Login is typically required to enable cryptographic operations.
* Furthermore, some of the device's objects such as certificates or private keys might only be visible when logged in.
*
* Note that many devices are locked after a number of failed login attempts.
* Therefore, it is crucial to not retry this method using the same {@link com.pdftools.crypto.providers.pkcs11.Session#login password} after a failed attempt.
*
* @param password
* The user's password
*
* @throws com.pdftools.PasswordException If the {@link com.pdftools.crypto.providers.pkcs11.Session#login password} is not correct
* @throws com.pdftools.PermissionException If the {@link com.pdftools.crypto.providers.pkcs11.Session#login password} has been locked or is expired
* @throws UnsupportedOperationException If the user has already logged in
*/
public void login(String password)
throws
com.pdftools.PasswordException,
com.pdftools.PermissionException
{
boolean retVal = loginNative(getHandle(), password);
if (!retVal)
{
switch (getLastErrorCode())
{
case 0: throw new RuntimeException("An unexpected error occurred");
case 1: throw new UnsupportedOperationException(getLastErrorMessage());
case 17: throw new com.pdftools.PasswordException(getLastErrorMessage());
case 23: throw new com.pdftools.PermissionException(getLastErrorMessage());
default: throwLastRuntimeException();
}
}
}
/**
* Create a signature configuration based on signing certificate
* @param certificate
* The signing certificate from {@link Session#getCertificates }
* @return
*
* @throws IllegalArgumentException If the {@link com.pdftools.crypto.providers.pkcs11.Session#createSignature certificate} is not a valid signing certificate.
* @throws IllegalArgumentException If the {@link com.pdftools.crypto.providers.pkcs11.Session#createSignature certificate} has expired.
* @throws IllegalArgumentException if {@code certificate} is {@code null}
*/
public com.pdftools.crypto.providers.pkcs11.SignatureConfiguration createSignature(com.pdftools.crypto.providers.Certificate certificate)
{
if (certificate == null)
throw new IllegalArgumentException("Argument 'certificate' must not be null.", new NullPointerException("'certificate'"));
long retHandle = createSignatureNative(getHandle(), getHandle(certificate), certificate);
if (retHandle == 0)
{
switch (getLastErrorCode())
{
case 0: throw new RuntimeException("An unexpected error occurred");
case 3: throw new IllegalArgumentException(getLastErrorMessage());
default: throwLastRuntimeException();
}
}
return com.pdftools.crypto.providers.pkcs11.SignatureConfiguration.createDynamicObject(retHandle);
}
/**
* Create a signature configuration based on certificate name
* @param name
* The name of the signing certificate ({@link com.pdftools.crypto.providers.Certificate#getName pdftools.crypto.providers.Certificate.getName})
* @return
*
* @throws com.pdftools.NotFoundException If the certificate cannot be found in {@link Session#getCertificates }
* @throws IllegalArgumentException If the certificate is not a valid signing certificate
* @throws IllegalArgumentException if {@code name} is {@code null}
*/
public com.pdftools.crypto.providers.pkcs11.SignatureConfiguration createSignatureFromName(String name)
throws
com.pdftools.NotFoundException
{
if (name == null)
throw new IllegalArgumentException("Argument 'name' must not be null.", new NullPointerException("'name'"));
long retHandle = createSignatureFromNameNative(getHandle(), name);
if (retHandle == 0)
{
switch (getLastErrorCode())
{
case 0: throw new RuntimeException("An unexpected error occurred");
case 3: throw new IllegalArgumentException(getLastErrorMessage());
case 5: throw new com.pdftools.NotFoundException(getLastErrorMessage());
default: throwLastRuntimeException();
}
}
return com.pdftools.crypto.providers.pkcs11.SignatureConfiguration.createDynamicObject(retHandle);
}
/**
* Create a signature configuration based on the private key's ID and an external certificate
*
* Create a signature configuration where only the private key is contained in the PKCS#11 device and
* the signing certificate is provided externally.
* This is intended for PKCS#11 devices that can only store private keys, e.g. the Google Cloud Key Management (KMS).
*
* The private key object is identified using its ID,
* i.e. the {@code CKA_ID} object attribute in the PKCS#11 store.
*
* The certificates of the trust chain should be added using {@link SignatureConfiguration#addCertificate }.
*
* @param id
* The ID of the private key object in the PKCS#11 store
* @param certificate
* The signing certificate in either PEM (.pem, ASCII text) or DER (.cer, binary) form
* @return
*
* @throws com.pdftools.NotFoundException If the private key cannot be found in the PKCS#11 store
* @throws IllegalArgumentException If the certificate is not a valid signing certificate
* @throws IllegalArgumentException If the key specification matches more than one key
* @throws IllegalArgumentException if {@code id} is {@code null}
* @throws IllegalArgumentException if {@code certificate} is {@code null}
*/
public com.pdftools.crypto.providers.pkcs11.SignatureConfiguration createSignatureFromKeyId(byte[] id, com.pdftools.sys.Stream certificate)
throws
com.pdftools.NotFoundException
{
if (id == null)
throw new IllegalArgumentException("Argument 'id' must not be null.", new NullPointerException("'id'"));
if (certificate == null)
throw new IllegalArgumentException("Argument 'certificate' must not be null.", new NullPointerException("'certificate'"));
long retHandle = createSignatureFromKeyIdNative(getHandle(), id, certificate);
if (retHandle == 0)
{
switch (getLastErrorCode())
{
case 0: throw new RuntimeException("An unexpected error occurred");
case 3: throw new IllegalArgumentException(getLastErrorMessage());
case 5: throw new com.pdftools.NotFoundException(getLastErrorMessage());
default: throwLastRuntimeException();
}
}
return com.pdftools.crypto.providers.pkcs11.SignatureConfiguration.createDynamicObject(retHandle);
}
/**
* Create a signature configuration based on the private key's label (name) and an external certificate
*
* Create a signature configuration where only the private key is contained in the PKCS#11 device and
* the signing certificate is provided externally.
* This is intended for PKCS#11 devices that can only store private keys, e.g. the Google Cloud Key Management (KMS).
*
* The private key object is identified using its label,
* i.e. the {@code CKA_LABEL} object attribute in the PKCS#11 store.
*
* The certificates of the trust chain should be added using {@link SignatureConfiguration#addCertificate }.
*
* @param label
* The label of the private key object in the PKCS#11 store
* @param certificate
* The signing certificate in either PEM (.pem, ASCII text) or DER (.cer, binary) form
* @return
*
* @throws com.pdftools.NotFoundException If the private key cannot be found in the PKCS#11 store
* @throws IllegalArgumentException If the certificate is not a valid signing certificate
* @throws IllegalArgumentException If the key specification matches more than one key
* @throws IllegalArgumentException if {@code label} is {@code null}
* @throws IllegalArgumentException if {@code certificate} is {@code null}
*/
public com.pdftools.crypto.providers.pkcs11.SignatureConfiguration createSignatureFromKeyLabel(String label, com.pdftools.sys.Stream certificate)
throws
com.pdftools.NotFoundException
{
if (label == null)
throw new IllegalArgumentException("Argument 'label' must not be null.", new NullPointerException("'label'"));
if (certificate == null)
throw new IllegalArgumentException("Argument 'certificate' must not be null.", new NullPointerException("'certificate'"));
long retHandle = createSignatureFromKeyLabelNative(getHandle(), label, certificate);
if (retHandle == 0)
{
switch (getLastErrorCode())
{
case 0: throw new RuntimeException("An unexpected error occurred");
case 3: throw new IllegalArgumentException(getLastErrorMessage());
case 5: throw new com.pdftools.NotFoundException(getLastErrorMessage());
default: throwLastRuntimeException();
}
}
return com.pdftools.crypto.providers.pkcs11.SignatureConfiguration.createDynamicObject(retHandle);
}
/**
* Create a time-stamp configuration
* Note that to create time-stamps, the {@link Session#getTimestampUrl } must be set.
* @return
*/
public com.pdftools.crypto.providers.pkcs11.TimestampConfiguration createTimestamp()
{
long retHandle = createTimestampNative(getHandle());
if (retHandle == 0)
{
switch (getLastErrorCode())
{
case 0: throw new RuntimeException("An unexpected error occurred");
default: throwLastRuntimeException();
}
}
return com.pdftools.crypto.providers.pkcs11.TimestampConfiguration.createDynamicObject(retHandle);
}
/**
* The URL of the trusted time-stamp authority (TSA) from which time-stamps shall be acquired (Getter)
*
* The TSA must support the time-stamp protocol as defined in RFC 3161.
*
* The property’s value must be a URL with the following elements:
*
* {@code http[s]://[‹user›[:‹password›]@]‹host›[:‹port›][/‹resource›]}
*
* Where:
*
* -
* {@code http/https}: Protocol for connection to TSA.
* -
* {@code ‹user›:‹password›} (optional): Credentials for connection to TSA (basic authorization).
* -
* {@code ‹host›}: Hostname of TSA.
* -
* {@code ‹port›}: Port for connection to TSA.
* -
* {@code ‹resource›}: The resource.
*
*
* Applying a time-stamp requires an online connection to a time server; the firewall must be configured accordingly.
* If a web proxy is used (see {@link com.pdftools.Sdk#getProxy pdftools.Sdk.getProxy}), make sure the following MIME types are supported:
*
* -
* {@code application/timestamp-query}
* -
* {@code application/timestamp-reply}
*
*/
public java.net.URI getTimestampUrl()
{
String retVal = getTimestampUrlNative(getHandle());
if (retVal == null)
{
switch (getLastErrorCode())
{
case 0: break;
default: throwLastRuntimeException();
}
return null;
}
return java.net.URI.create(retVal);
}
/**
* The URL of the trusted time-stamp authority (TSA) from which time-stamps shall be acquired (Setter)
*
* The TSA must support the time-stamp protocol as defined in RFC 3161.
*
* The property’s value must be a URL with the following elements:
*
* {@code http[s]://[‹user›[:‹password›]@]‹host›[:‹port›][/‹resource›]}
*
* Where:
*
* -
* {@code http/https}: Protocol for connection to TSA.
* -
* {@code ‹user›:‹password›} (optional): Credentials for connection to TSA (basic authorization).
* -
* {@code ‹host›}: Hostname of TSA.
* -
* {@code ‹port›}: Port for connection to TSA.
* -
* {@code ‹resource›}: The resource.
*
*
* Applying a time-stamp requires an online connection to a time server; the firewall must be configured accordingly.
* If a web proxy is used (see {@link com.pdftools.Sdk#getProxy pdftools.Sdk.getProxy}), make sure the following MIME types are supported:
*
* -
* {@code application/timestamp-query}
* -
* {@code application/timestamp-reply}
*
*/
public void setTimestampUrl(java.net.URI value)
{
boolean retVal = setTimestampUrlNative(getHandle(), value != null ? value.toString() : null);
if (!retVal)
{
switch (getLastErrorCode())
{
case 0: throw new RuntimeException("An unexpected error occurred");
default: throwLastRuntimeException();
}
}
}
/**
* The cerfificates of the device (Getter)
* The certificates available in this device.
* Note that some certificates or their private keys (see {@link com.pdftools.crypto.providers.Certificate#getHasPrivateKey pdftools.crypto.providers.Certificate.getHasPrivateKey}) might only be visible
* after {@link Session#login }.
*/
public com.pdftools.crypto.providers.CertificateList getCertificates()
{
long retHandle = getCertificatesNative(getHandle());
if (retHandle == 0)
{
switch (getLastErrorCode())
{
case 0: throw new RuntimeException("An unexpected error occurred");
default: throwLastRuntimeException();
}
}
return com.pdftools.crypto.providers.CertificateList.createDynamicObject(retHandle);
}
private native boolean loginNative(long handle, String password);
private native long createSignatureNative(long handle, long certificate, com.pdftools.crypto.providers.Certificate certificateObj);
private native long createSignatureFromNameNative(long handle, String name);
private native long createSignatureFromKeyIdNative(long handle, byte[] id, com.pdftools.sys.Stream certificate);
private native long createSignatureFromKeyLabelNative(long handle, String label, com.pdftools.sys.Stream certificate);
private native long createTimestampNative(long handle);
private native String getTimestampUrlNative(long handle);
private native boolean setTimestampUrlNative(long handle, String value);
private native long getCertificatesNative(long handle);
}