
com.pdftools.crypto.providers.builtin.Provider Maven / Gradle / Ivy
/****************************************************************************
*
* File: Provider.java
*
* Description: PDFTOOLS Provider 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.builtin;
import com.pdftools.sys.*;
import com.pdftools.internal.*;
import java.util.EnumSet;
import java.time.OffsetDateTime;
/**
* The built-in cryptographic provider
*
* The built-in cryptographic provider requires no cryptographic hardware or external service (except for the optional
* {@link Provider#getTimestampUrl }).
*
* Signing certificates with private keys can be loaded using {@link Provider#createSignatureFromCertificate }.
*
* Certificates Directory:
* Additional certificates, e.g. issuer certificates, can be stored in the certificates directory.
* These certificates are required when adding validation information to signatures that do not have the full trust chain embedded.
* The certificates directory may contain certificates in either PEM (.pem, ASCII text) or DER (.cer, binary) form.
*
* -
* Windows:
*
* -
* {@code %LOCALAPPDATA%\PDF Tools AG\Certificates}
* -
* {@code %ProgramData%\PDF Tools AG\Certificates}
*
* -
* Linux:
*
* -
* {@code ~/.pdf-tools/Certificates} or {@code $TMP/pdf-tools/Certificates}
* -
* {@code /usr/share/pdf-tools/Certificates}
*
* -
* macOS:
*
* -
* {@code ~/.pdf-tools/Certificates} or {@code $TMP/pdf-tools/Certificates}
*
*
*/
public class Provider extends com.pdftools.crypto.providers.Provider
{
protected Provider(long handle)
{
super(handle);
}
/**
* @hidden
*/
public static Provider createDynamicObject(long handle)
{
return new Provider(handle);
}
/**
*
*/
public Provider()
{
this(newHelper());
}
private static long newHelper()
{
long handle = newNative();
if (handle == 0)
{
switch (getLastErrorCode())
{
case 0: throw new RuntimeException("An unexpected error occurred");
default: throwLastRuntimeException();
}
}
return handle;
}
/**
* Create a configuration to sign with a PFX (PKCS#12) soft certificate
* The file must contain the certificate itself, all certificates of the trust chain, and the private key.
* @param stream
* The signing certificate in PKCS#12 format (.p12, .pfx).
* @param password
* The password required to decrypt the private key of the archive.
* @return
*
* @throws com.pdftools.CorruptException The PFX (PKCS#12) archive is corrupt and cannot be read.
* @throws com.pdftools.PasswordException The password is invalid.
* @throws IllegalArgumentException The certificate is not a valid signing certificate
* @throws IllegalArgumentException if {@code stream} is {@code null}
*/
public com.pdftools.crypto.providers.builtin.SignatureConfiguration createSignatureFromCertificate(com.pdftools.sys.Stream stream, String password)
throws
com.pdftools.CorruptException,
com.pdftools.PasswordException
{
if (stream == null)
throw new IllegalArgumentException("Argument 'stream' must not be null.", new NullPointerException("'stream'"));
long retHandle = createSignatureFromCertificateNative(getHandle(), stream, password);
if (retHandle == 0)
{
switch (getLastErrorCode())
{
case 0: throw new RuntimeException("An unexpected error occurred");
case 3: throw new IllegalArgumentException(getLastErrorMessage());
case 16: throw new com.pdftools.CorruptException(getLastErrorMessage());
case 17: throw new com.pdftools.PasswordException(getLastErrorMessage());
default: throwLastRuntimeException();
}
}
return com.pdftools.crypto.providers.builtin.SignatureConfiguration.createDynamicObject(retHandle);
}
/**
* Create a time-stamp configuration
* Note that to create time-stamps, the {@link Provider#getTimestampUrl } must be set.
* @return
*/
public com.pdftools.crypto.providers.builtin.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.builtin.TimestampConfiguration.createDynamicObject(retHandle);
}
/**
* Create a configuration to prepare a signature for an external signature handler
* This method is part of a very specialized use case requiring an external signature handler.
* The process using an external signature handler is:
*
* -
* {@link Provider#createPreparedSignature }: Create the signature configuration.
* -
* {@link com.pdftools.sign.Signer#addPreparedSignature pdftools.sign.Signer.addPreparedSignature}: Create the document with the prepared signature.
* -
* {@link com.pdftools.sign.PreparedDocument#getHash pdftools.sign.PreparedDocument.getHash}: Calculate the hash from the document and create the signature using an
* external signature handler.
* -
* {@link Provider#readExternalSignature }: Create signature configuration for the external signature.
* -
* {@link com.pdftools.sign.Signer#signPreparedSignature pdftools.sign.Signer.signPreparedSignature}: Insert the external signature into the document with the prepared signature.
*
*
* @param size
* The expected size of the cryptographic signature that will be added later.
* This is the number of bytes that will be reserved in the prepared signature.
* @param format
* The format (SubFilter) of the cryptographic signature that is added later.
* For example, {@code "adbe.pkcs7.detached"} or {@code "ETSI.CAdES.detached"}.
* @param name
* The name of the signer of the cryptographic signature that will be added later.
* @return
* @throws IllegalArgumentException if {@code format} is {@code null}
* @throws IllegalArgumentException if {@code name} is {@code null}
*/
public com.pdftools.sign.SignatureConfiguration createPreparedSignature(int size, String format, String name)
{
if (format == null)
throw new IllegalArgumentException("Argument 'format' must not be null.", new NullPointerException("'format'"));
if (name == null)
throw new IllegalArgumentException("Argument 'name' must not be null.", new NullPointerException("'name'"));
long retHandle = createPreparedSignatureNative(getHandle(), size, format, name);
if (retHandle == 0)
{
switch (getLastErrorCode())
{
case 0: throw new RuntimeException("An unexpected error occurred");
default: throwLastRuntimeException();
}
}
return com.pdftools.sign.SignatureConfiguration.createDynamicObject(retHandle);
}
/**
* Read signature created by an external signature handler
* See {@link Provider#createPreparedSignature } for more information on the signing process using an external signature handler.
* @param signature
* This signature must not be larger than the number of bytes reserved in the prepared signature.
* @return
* @throws IllegalArgumentException if {@code signature} is {@code null}
*/
public com.pdftools.sign.SignatureConfiguration readExternalSignature(byte...signature)
{
if (signature == null)
throw new IllegalArgumentException("Argument 'signature' must not be null.", new NullPointerException("'signature'"));
long retHandle = readExternalSignatureNative(getHandle(), signature);
if (retHandle == 0)
{
switch (getLastErrorCode())
{
case 0: throw new RuntimeException("An unexpected error occurred");
default: throwLastRuntimeException();
}
}
return com.pdftools.sign.SignatureConfiguration.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();
}
}
}
private static native long newNative();
private native long createSignatureFromCertificateNative(long handle, com.pdftools.sys.Stream stream, String password);
private native long createTimestampNative(long handle);
private native long createPreparedSignatureNative(long handle, int size, String format, String name);
private native long readExternalSignatureNative(long handle, byte[] signature);
private native String getTimestampUrlNative(long handle);
private native boolean setTimestampUrlNative(long handle, String value);
}