Compare commits

...

18 Commits

Author SHA1 Message Date
083bf20be7 update deps, switching pyhanko to version 0.29
All checks were successful
Build image and push it to registry / build (push) Successful in 1m28s
2025-06-05 13:33:38 +02:00
6626b33c6a upgrade idea settings 2025-06-05 13:33:38 +02:00
8a3c44c517 test signature with return line 2025-06-05 13:33:38 +02:00
c7a6283e00 Add timezone configuration to Dockerfile
All checks were successful
Build image and push it to registry / build (push) Successful in 1m11s
Included tzdata package and set the timezone to Europe/Paris by creating a symbolic link in /etc/localtime. This ensures the container runs with the correct timezone settings.
2024-11-06 14:46:45 +01:00
0e7d01f0fd Fix environment password encoding in SignOrchestrator init
All checks were successful
Build image and push it to registry / build (push) Successful in 6m47s
Previously, the `PKCS12_PASSWORD` environment variable was used directly, which could lead to issues when it was not set. This change ensures the password is properly encoded when provided and defaults to `None` if not set.
2024-10-22 16:37:49 +02:00
39b9f7455c Update README section title for clarity
Changed the title "Préparation pour Vendée" to "Préparation à partir d'un certificat d'horodatage au format pkcs12" for better clarity and specificity. This update helps users understand the section's purpose more easily.
2024-10-22 16:37:31 +02:00
97a2385167 Remove redundant 'TIMESTAMP_URL' environment variable check
All checks were successful
Build image and push it to registry / build (push) Successful in 1m27s
The 'TIMESTAMP_URL' environment variable check was removed from the worker script as it is no longer required. This simplifies the code by eliminating unnecessary validation.
2024-10-22 12:07:08 +02:00
77aaf97d7b Add new TSA configuration environment variables
All checks were successful
Build image and push it to registry / build (push) Successful in 1m1s
Included 'TSA_CONFIG_PATH', 'TSA_CERT_CHAIN', and 'TSA_KEY_PASSWORD' to the environment variable check in worker.py. This ensures the script validates these new required configurations before proceeding. Added an exception raise in the error handling block for better error management.
2024-10-21 18:53:52 +02:00
dd8c30787a fix imports
All checks were successful
Build image and push it to registry / build (push) Successful in 1m48s
2024-10-21 18:28:20 +02:00
8c5950b37f Merge pull request 'Allow the signature_index to be None' (#3) from test-ts-sign into main
All checks were successful
Build image and push it to registry / build (push) Successful in 1m40s
Reviewed-on: #3
2024-10-16 07:13:38 +00:00
34857ae4b0 Allow the signature_index to be None
When the signature_index is not set, the name's sinature zone is generated from a random int.
2024-10-15 07:47:58 +02:00
df2a8d554f Merge pull request 'Create a dedicated timestamper which use the openssl cli and custom certificates' (#2) from test-ts-sign into main
All checks were successful
Build image and push it to registry / build (push) Successful in 1m42s
Reviewed-on: #2
2024-10-11 14:19:51 +00:00
89cb05fce1 Add openssl to Dockerfile
This change adds the openssl CLI to the Dockerfile to ensure necessary cryptographic functionalities are available. It helps in maintaining secure communications and other operations that depend on openssl.
2024-10-11 16:19:32 +02:00
3716c3ce78 create a new script dedicated for signing for vendee certificates 2024-10-11 16:13:34 +02:00
c8042a6f84 Integrate local OpenSSL TSA for timestamping
Replaced HTTPTimeStamper with LocalOpensslTimestamp for TSA operations using a local OpenSSL CLI. Updated related configurations and dependencies to support this change, enhancing the timestamping process's reliability and security.
2024-10-11 16:13:34 +02:00
9f085484f7 write readme to generate timestamps 2024-10-11 12:43:25 +02:00
958c96193e Add .gitignore and example local.env.dist
Introduce a .gitignore to exclude local environment files. Provide a sample local.env.dist for configuration templates. This helps in maintaining environment-specific settings securely and consistently.
2024-10-11 09:05:46 +02:00
7c84464d13 remove the unused drone file 2024-10-11 09:04:38 +02:00
16 changed files with 551 additions and 71 deletions

View File

@@ -1,35 +0,0 @@
---
kind: pipeline
type: docker
name: build-images
image_pull_secrets:
- dockerconfig
trigger:
event:
- cron
- push
cron:
- build-image
steps:
- name: build-base-image
image: plugins/docker
settings:
username:
from_secret: docker_username
password:
from_secret: docker_password
registry: h3m6q87t.gra7.container-registry.ovh.net
repo: h3m6q87t.gra7.container-registry.ovh.net/sign-pdf-worker/worker
tag:
- latest
pull_image: true
context: ./pythonProject
dockerfile: ./pythonProject/Dockerfile
---
kind: signature
hmac: 538ac6bab02bd9fcc1d0124c64135c87c850e07391a5271e7e7864913f3cad61
...

1
.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
local.env

2
.idea/misc.xml generated
View File

@@ -3,5 +3,5 @@
<component name="Black">
<option name="sdkName" value="Python 3.10 (pythonProject)" />
</component>
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.10 (pythonProject)" project-jdk-type="Python SDK" />
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.10 virtualenv at ~/dev/chill/sign-pdf-worker/pythonProject/.venv" project-jdk-type="Python SDK" />
</project>

View File

@@ -4,7 +4,7 @@
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/pythonProject/.venv" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="jdk" jdkName="Python 3.10 virtualenv at ~/dev/chill/sign-pdf-worker/pythonProject/.venv" jdkType="Python SDK" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

10
local.env.dist Normal file
View File

@@ -0,0 +1,10 @@
AMQP_URL=amqp://guest:guest@localhost:32772/%2f/to_python_sign
LOG_LEVEL=DEBUG
PKCS12_PATH=./assets/dummy.p12
TIMESTAMP_URL=http://freetsa.org/tsr
QUEUE_IN=to_python_sign
EXCHANGE_OUT=signed_docs
OUT_ROUTING_KEY=signed_doc
TSA_CONFIG_PATH=/home/julien/dev/chill/sign-pdf-worker/ts-authority/rootca.conf
TSA_CERT_CHAIN=/home/julien/dev/chill/sign-pdf-worker/ts-authority/ca/tsa-chain.pem
TSA_KEY_PASSWORD=5678

View File

@@ -4,6 +4,12 @@ FROM python:3.10-alpine
# Set working directory
WORKDIR /app
# add required clis
RUN apk add --no-cache openssl tzdata
# set timezone
RUN ln -s /usr/share/zoneinfo/Europe/Paris /etc/localtime
# Copy requirements.txt to the Docker container
COPY requirements.txt .

View File

@@ -1,20 +1,22 @@
asn1crypto==1.5.1
certifi==2024.6.2
cffi==1.16.0
charset-normalizer==3.3.2
click==8.1.7
cryptography==42.0.8
idna==3.7
certifi==2025.4.26
cffi==1.17.1
charset-normalizer==3.4.2
click==8.2.1
cryptography==45.0.3
idna==3.10
lxml==5.4.0
oscrypto==1.3.0
pika==1.3.2
pika-stubs==0.1.3
pycparser==2.22
pyHanko==0.25.0
pyhanko-certvalidator==0.26.3
pyHanko==0.29.0
pyhanko-certvalidator==0.27.0
pypng==0.20220715.0
PyYAML==6.0.1
qrcode==7.4.2
PyYAML==6.0.2
qrcode==8.2
requests==2.32.3
typing_extensions==4.12.2
tzlocal==5.2
uritools==4.0.3
urllib3==2.2.2
typing_extensions==4.14.0
tzlocal==5.3.1
uritools==5.0.0
urllib3==2.4.0

View File

@@ -1,17 +1,21 @@
import io
from random import randint
from typing import Optional
from pyhanko import stamp
from pyhanko.pdf_utils.incremental_writer import IncrementalPdfFileWriter
from pyhanko.sign import signers, timestamps, fields
from pyhanko_certvalidator import ValidationContext
from pyhanko.sign import signers, fields
from typing_extensions import Buffer
from timestamp import LocalOpensslTimestamp
class SignOrchestrator:
"""Orchestrate the signature on document"""
def __init__(self, pkcs12_path: str, timestamp_url: str, pkcs12_password: Optional[bytes] = None):
def __init__(self, pkcs12_path: str,
tsa_config_path: str, tsa_password: str, tsa_cert_chain: str,
pkcs12_password: Optional[bytes] = None):
# Load signer key material from PKCS#12 file
# This assumes that any relevant intermediate certs are also included
# in the PKCS#12 file.
@@ -20,9 +24,7 @@ class SignOrchestrator:
)
# Set up a timestamping client to fetch timestamps tokens
self.timestamper = timestamps.HTTPTimeStamper(
url=timestamp_url,
)
self.timestamper = LocalOpensslTimestamp(tsa_config_path, tsa_password, tsa_cert_chain)
self.stamp_style = stamp.TextStampStyle(
stamp_text="Signé par:\n%(signer_text)s\nLe %(ts)s",
@@ -47,8 +49,8 @@ class SignOrchestrator:
reason=reason,
)
def sign(self, reason: str, signature_index: int, input_content: Buffer, on_page: int, box_place: (int, int, int, int), signer_text: str) -> io.BytesIO:
field_name = 'Signature' + str(signature_index)
def sign(self, reason: str, signature_index: int|None, input_content: Buffer, on_page: int, box_place: (int, int, int, int), signer_text: str) -> io.BytesIO:
field_name = 'Signature' + str(signature_index) if signature_index is not None else 'Signature'+ str(randint(1000, 99999999999))
signature_meta = self._make_signature_metadata(reason, field_name)
pdf_signer = signers.PdfSigner(

View File

@@ -1,19 +1,33 @@
from sign import SignOrchestrator
orchestrator = SignOrchestrator('./assets/dummy.p12','http://freetsa.org/tsr', pkcs12_password=None)
"""
This is a script to sign a file with the dummy assets
It is created mainly for testing purpose
"""
orchestrator = SignOrchestrator('./assets/dummy.p12',
'/home/julien/dev/chill/sign-pdf-worker/ts-authority/rootca.conf',
'5678',
'/home/julien/dev/chill/sign-pdf-worker/ts-authority/ca/tsa-chain.pem',
pkcs12_password=None)
with open('./assets/test.pdf', 'rb') as input:
signed_content = orchestrator.sign(reason="first signer", signature_index=0,
signed_content = orchestrator.sign(reason="first\nsigner\nreturn\ntext", signature_index=None,
input_content=input.read(), box_place=(300, 600, 500, 660), on_page=0,
signer_text="Mme Caroline Diallo")
signer_text="""Mme Caroline Diallo
with
return
text
""")
with open('./assets/test_signed_0.pdf', 'wb') as output:
output.write(signed_content.read())
with open('./assets/test_signed_0.pdf', 'rb') as input:
signed_content = orchestrator.sign(reason="second signer", signature_index=1,
input_content=input.read(), box_place=(100, 600, 300, 660), on_page=0,
signer_text="M. Bah Mamadou")
signed_content = orchestrator.sign(reason="second signer", signature_index=None,
input_content=input.read(), box_place=(100, 600, 300, 660), on_page=0,
signer_text="M. Bah Mamadou")
with open('./assets/test_signed_1.pdf', 'wb') as output:
output.write(signed_content.read())
with open('./assets/test_signed_1.pdf', 'wb') as output:
output.write(signed_content.read())

View File

@@ -0,0 +1,29 @@
from sign import SignOrchestrator
"""
This is a script to sign a file with the dummy assets
It is created mainly for testing purpose
"""
orchestrator = SignOrchestrator('/run/user/1000/ca/cachet.p12',
'/home/julien/dev/chill/sign-pdf-worker/ts-authority/vendee-tsa.conf',
'xxxxxxxxxxxxxxxxxxx',
'/run/user/1000/ca/tsa-chain.pem',
pkcs12_password=b"xxxxxxxxxxxxxxxx")
with open('./assets/test.pdf', 'rb') as input:
signed_content = orchestrator.sign(reason="first signer", signature_index=0,
input_content=input.read(), box_place=(300, 600, 500, 660), on_page=0,
signer_text="Mme Caroline Diallo")
with open('./assets/test_signed_0.pdf', 'wb') as output:
output.write(signed_content.read())
with open('./assets/test_signed_0.pdf', 'rb') as input:
signed_content = orchestrator.sign(reason="second signer", signature_index=1,
input_content=input.read(), box_place=(100, 600, 300, 660), on_page=0,
signer_text="M. Bah Mamadou")
with open('./assets/test_signed_1.pdf', 'wb') as output:
output.write(signed_content.read())

View File

@@ -0,0 +1,64 @@
import logging
import os
from asn1crypto import tsp
from asn1crypto.tsp import TimeStampResp
from pyhanko.sign.timestamps import TimeStamper
import subprocess
LOGGER = logging.getLogger(__name__)
LOGGER.setLevel(os.environ.get('LOG_LEVEL', logging.DEBUG))
class LocalOpensslTimestamp(TimeStamper):
"""
Apply a timestamp using a local openssl cli.
The class provides methods to request a timestamp response from a local OpenSSL TSA cli.
"""
def __init__(self, path_config: str, password: str, path_chain: str):
super().__init__()
self.path_conf = path_config
self.password = password
self.path_chain = path_chain
def request_tsa_response(self, req: tsp.TimeStampReq) -> tsp.TimeStampResp:
with open('/tmp/request.tsq', 'wb') as request:
request.write(req.dump())
cmd = [
'openssl', 'ts', '-reply',
'-config', self.path_conf,
'-queryfile', '/tmp/request.tsq',
'-chain', self.path_chain,
'-out', '/tmp/response.tsr',
'-passin', f'pass:{self.password}'
]
try:
subprocess.run(cmd, capture_output=True, check=True, timeout=10)
except subprocess.CalledProcessError as e:
LOGGER.error("Could not generate a timestamp")
LOGGER.error(f"response code: {e.returncode}")
LOGGER.error(f"stderr: {e.stderr}")
LOGGER.error(f"stdout: {e.stdout}")
LOGGER.error(f"error: {e.output}")
raise Exception("could not generate a timestamp")
except subprocess.TimeoutExpired as e:
LOGGER.error("timeout expired")
LOGGER.error(f"stderr: {e.stderr}")
LOGGER.error(f"stdout: {e.stdout}")
LOGGER.error(f"error: {e.output}")
raise e
with open('/tmp/response.tsr', mode='rb') as f:
tsp = TimeStampResp.load(f.read())
os.unlink('/tmp/response.tsr')
return tsp
async def async_request_tsa_response(self, req: tsp.TimeStampReq) -> tsp.TimeStampResp:
return self.request_tsa_response(req)

View File

@@ -12,20 +12,21 @@ logging.basicConfig(level=logging.INFO, format=LOG_FORMAT)
LOGGER = logging.getLogger(__name__)
LOGGER.setLevel(os.environ.get('LOG_LEVEL', logging.INFO))
for v in ['AMQP_URL', 'PKCS12_PATH', 'TIMESTAMP_URL', 'QUEUE_IN', 'EXCHANGE_OUT', 'OUT_ROUTING_KEY']:
for v in ['AMQP_URL', 'PKCS12_PATH', 'QUEUE_IN', 'EXCHANGE_OUT', 'OUT_ROUTING_KEY', 'TSA_CONFIG_PATH', 'TSA_CERT_CHAIN', 'TSA_KEY_PASSWORD']:
if v not in os.environ:
LOGGER.error('Missing environment variable: %s', v)
raise ValueError('Missing environment variable: ' + v)
DSN = os.environ.get('AMQP_URL')
PKCS12_PATH = os.environ.get('PKCS12_PATH')
TIMESTAMP_URL = os.environ.get('TIMESTAMP_URL')
QUEUE_IN = os.environ.get('QUEUE_IN')
EXCHANGE_OUT = os.environ.get('EXCHANGE_OUT')
OUT_ROUTING_KEY = os.environ.get('OUT_ROUTING_KEY')
TSA_CONFIG_PATH = os.environ.get('TSA_CONFIG_PATH')
TSA_CERT_CHAIN = os.environ.get('TSA_CERT_CHAIN')
TSA_KEY_PASSWORD = os.environ.get('TSA_KEY_PASSWORD')
orchestrator = sign.SignOrchestrator(PKCS12_PATH, TIMESTAMP_URL, pkcs12_password=os.environ.get('PKCS12_PASSWORD', None))
orchestrator = sign.SignOrchestrator(PKCS12_PATH, TSA_CONFIG_PATH, TSA_KEY_PASSWORD, TSA_CERT_CHAIN, pkcs12_password=None if os.environ.get('PKCS12_PASSWORD', None) is None else os.environ.get('PKCS12_PASSWORD').encode())
parameters = pika.URLParameters(DSN)
connection = pika.BlockingConnection(parameters)
@@ -75,6 +76,7 @@ def on_message(channel, method_frame, header_frame, body):
else:
LOGGER.warning(f"first try failed, signatureId: {body_content['signatureId']}")
channel.basic_ack(delivery_tag=method_frame.delivery_tag)
raise e
if __name__ == '__main__':

4
ts-authority/.gitignore vendored Normal file
View File

@@ -0,0 +1,4 @@
ca/*
!ca/certs/.gitkeep
!ca/db/.gitkeep
!ca/private/.gitkeep

167
ts-authority/README.md Normal file
View File

@@ -0,0 +1,167 @@
# Set up CA
## Sources:
- https://www.jimby.name/techbits/recent/openssl_tsa/
## Create directory
```bash
# mkdir certs db private ## should already be created
# chmod 700 private ## should already be set
touch db/index
openssl rand -hex 16 > db/serial
echo 1001 > db/crlnumber
echo 01 > tsa_serial
```
## Create files for certificate authority
Create a new private key and root CA certificate request in one step:
```bash
openssl req -new -newkey rsa:2048 -config ./rootca.conf -out ca/root-ca.csr -keyout ca/private/root-ca.key
```
Dont forget the password youll need it again and again below.
Now self-sign the certificate request.
```bash
openssl ca -selfsign -config ./rootca.conf -in ca/root-ca.csr -out ca/root-ca.crt -extensions ca_ext
```
Check the certificate:
```bash
openssl x509 -text -in ca/root-ca.crt -noout
```
## Create certificate for timestamp
To proceed, we first make a key and a certificate request for a non-CA certificate. We use the -subj option so we dont
have to use a configuration file for this step. The Country (C=US) and Organization (O=Example Inc.) elements must
match the root certificate.
```bash
openssl req -new \
-newkey rsa:2048 \
-subj "/C=US/O=Example Inc./OU=Engineering/CN=Example Inc. TSA Responder" \
-keyout ca/private/tsa.key \
-out ca/tsa.csr
```
You should use a different password for the tsa.key private key.
Then we generate a non-CA certificate using the -extension tsa_ext command line option which points to the required
extendedKeyUsage in the configuration file.
```bash
openssl ca -config ./rootca.conf -in ca/tsa.csr -out ca/tsa.crt -extensions tsa_ext -days 365
```
Sign with the root-ca.key private key password, and commit to the database.
Examine the new TSA certificate as follows:
```bash
openssl x509 -in ca/tsa.crt -text -noout
```
Ensure that it has CA: false , keyUsage nonRepudiation, and extendedKeyUsage timeStamping.
Requests to the time stamp service usually require that the reply include the certificate chain of the service. We now create the certificate chain as follows:
First, extract just the PEM form of the x509 certificates for root-ca.crt and tsa.crt :
```bash
openssl x509 -in ca/root-ca.crt -outform PEM -out ca/root-ca.pem
openssl x509 -in ca/tsa.crt -outform PEM -out ca/tsa.pem
```
Next, concatenate the two bare certificates ensuring that the root certificate is last in the file:
```bash
cat ca/tsa.pem ca/root-ca.pem > ca/tsa-chain.pem
```
You can verify this chain by just viewing the file:
```bash
cat ca/tsa-chain.pem
```
## Generate a timestamp request
Ok! We are now ready to create a time stamp request. First, we prepare a query:
```bash
openssl ts -query -config ./rootca.conf -cert -data /etc/hosts -out /tmp/request.tsq
```
View the request with
```bash
openssl ts -query -in /tmp/request.tsq -text
```
Note that since we did not request certificate checking (using the -cert option in the request command above), the text
output of this command shows “Certificate required: no”. Also, note that we did not specify our own configuration
file in the above example.
If you want to use a stronger digest algorithm, specify it on the command line (sha512 requested here):
```bash
openssl ts -query -config ./rootca.conf -data /etc/hosts -out /tmp/request.tsr -sha512
```
## Generating a reply
We can now process a reply to the the request. Note that the openssl ts -reply sub-command does require a configuration
file, including the all the tsa sections. In particular, it uses the tsa_policy1(2,3) options we added at the top of the file.
Here (and everywhere you utilize the services of the tsa.crt certificate), you must enter the password for the tsa
certificate private key.
```bash
openssl ts -reply -config ./rootca.conf -queryfile /tmp/request.tsq -chain ca/tsa-chain.pem -out /tmp/response.tsr
```
```bash
openssl ts -reply -config ./rootca.conf -in /tmp/response.tsr -text
```
## Verification
Openssl can also verify the received timestamp ensuring that the data file or data digest the query was based on still
applies to the current version of the file.
```bash
openssl ts -verify -queryfile /tmp/request.tsq -in /tmp/response.tsr -CAfile ca/root-ca.pem -untrusted ca/tsa.pem
```
The OK response ensures that the original signed timestamp is correctly authorized by the root and tsa certificates
(in PEM format).
```bash
openssl ts -verify -data /etc/hosts -in /tmp/response.tsr -CAfile ca/root-ca.pem -untrusted ca/tsa.pem
```
# Préparation à partir d'un certificat d'horodatage au format pkcs12
## Extraire les infos
```bash
openssl pkcs12 -info -in horodatage.p12 -legacy
```
Ca demandera un mot de passe pour déchiffrer, et un autre mot de passe pour chiffrer la clé qui apparaitra.
- on recopie la clé et on fait un copier-coller dans /run/user/1000/ca/private/tsa.key
- on recopie tous les certificats, on supprime les interligne, et on colle ça dans /run/user/1000/ca/tsa-chain.pem
- on recopie le premier certificat, pour céer /run/user/1000/ca/tsa.crt

168
ts-authority/rootca.conf Normal file
View File

@@ -0,0 +1,168 @@
#
# rootca.conf
#
# See Ristic OpenSSL Cookbook URL above.
oid_section = new_oids
[ new_oids ]
tsa_policy1 = 1.2.3.4.1
tsa_policy2 = 1.2.3.4.5.6
tsa_policy3 = 1.2.3.4.5.7
###### First Part ########
[default]
name = root-ca
domain_suffix = example.com
aia_url = http://$name.$domain_suffix/$name.crt
crl_url = http://$name.$domain_suffix/$name.crl
ocsp_url = http://ocsp.$name.$domain_suffix:9080
default_ca = ca_default
name_opt = utf8,esc_ctrl,multiline,lname,align
[ca_dn]
countryName = "US"
organizationName = "Example Inc."
commonName = "Root CA"
###### Second Part #######
[ca_default]
home = .
database = $home/ca/db/index
serial = $home/ca/db/serial
crlnumber = $home/ca/db/crlnumber
certificate = $home/ca/$name.crt
private_key = $home/ca/private/$name.key
RANDFILE = $home/ca/private/random
new_certs_dir = $home/ca/certs
unique_subject = no
copy_extensions = none
default_days = 3650
default_crl_days = 30
default_md = sha256
policy = policy_c_o_match
name = foo@example.com
[policy_c_o_match]
countryName = match
stateOrProvinceName = optional
organizationName = match
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
##### Third Part #######
[req]
default_bits = 4096
encrypt_key = yes
default_md = sha256
utf8 = yes
string_mask = utf8only
prompt = no
distinguished_name = ca_dn
req_extensions = ca_ext
[ca_ext]
basicConstraints = critical,CA:true
keyUsage = critical,keyCertSign,cRLSign
subjectKeyIdentifier = hash
####### Fourth Part - Extensions ########
#
# Value Meaning - see x509v3.cnf(5)
# -------- ------------------------------
# serverAuth SSL/TLS web server authentication
# clientAuth SSL/TLS web client authentication
# codeSigning code signing
# emailProtection email protection (S/MIME)
# timeStamping trusted doc hash timestamping
# OCSPSigning OCSP Signing
# ipsecIKE IPsec internet key exchange
# msCodeInd Microsoft individual code signing (authenticode)
# msCodeCom Microsoft commercial code signing (authenticode)
# msCTLSign Microsoft trust list signing
# msEFS Microsoft encrypted file system (EFS)
[sub_ca_ext]
authorityInfoAccess = @issuer_info
authorityKeyIdentifier = keyid:always
basicConstraints = critical,CA:true,pathlen:0
crlDistributionPoints = @crl_info
keyUsage = critical,keyCertSign,cRLSign
extendedKeyUsage = clientAuth,serverAuth
nameConstraints = @name_constraints
subjectKeyIdentifier = hash
[crl_info]
URI.0 = $crl_url
[issuer_info]
caIssuers;URI.0 = $aia_url
OCSP;URI.0 = $ocsp_url
[name_constraints]
permitted;DNS.0=example.com
permitted;DNS.1=example.org
excluded;IP.0=0.0.0.0/0.0.0.0
excluded;IP.1=0:0:0:0:0:0:0:0/0:0:0:0:0:0:0:0
####### Fifth Part ==========
[ocsp_ext]
authorityKeyIdentifier = keyid:always
basicConstraints = critical,CA:false
extendedKeyUsage = OCSPSigning
keyUsage = critical,digitalSignature
subjectKeyIdentifier = hash
########### TSA extension ##############
#
# Copied from the OpenSSL CAtsa.cnf test configuration and modified for use as a TSA extension.
#
#
[ tsa ]
default_tsa = tsa_config1
[ tsa_config1 ]
dir = /home/julien/dev/chill/sign-pdf-worker/ts-authority # TSA root directory, same as root-ca
serial = $dir/ca/tsa_serial # current serial number (mandatory)
signer_cert = $dir/ca/tsa.crt # signing certificate (optional)
certs = $dir/ca/tsa-chain.pem # certification chain (optional)
signer_key = $dir/ca/private/tsa.key # tsa private key (optional)
default_policy = tsa_policy1
signer_digest = sha256 # digest to use for signing (optional)
other_policies = tsa_policy2,tsa_policy3 # other policies (optional)
digests = sha256,sha384,sha512 # acceptable digests (mandatory)
accuracy = secs:1,millisecs:500,microsecs:100 # accuracy optional
ordering = yes # is ordering defined? (optional, default: no)
tsa_name = yes # must tsa name be included in reply? (opt., default: no)
ess_cert_id_chain = yes # must ess cert id change be incl? (opt., default: no)
ess_cert_id_alg = sha256 # alg to compute cert. id (optional, default: sha1)
# added, was missing in the blog post
crypto_device = builtin
# The tsa_ext extension is
# used to create the tsa cert tsa.crt
[ tsa_ext ]
authorityKeyIdentifier = keyid:always
basicConstraints = critical,CA:false
extendedKeyUsage = critical,timeStamping
keyUsage = critical,nonRepudiation
subjectKeyIdentifier = hash

View File

@@ -0,0 +1,46 @@
#
# rootca.conf
#
# See Ristic OpenSSL Cookbook URL above.
oid_section = new_oids
[ new_oids ]
tsa_policy1 = 1.2.3.4.1
tsa_policy2 = 1.2.3.4.5.6
tsa_policy3 = 1.2.3.4.5.7
[ tsa ]
default_tsa = tsa_config1
[ tsa_config1 ]
dir = /run/user/1000/ca # TSA root directory, same as root-ca
serial = $dir/tsa_serial # current serial number (mandatory)
signer_cert = $dir/tsa.crt # signing certificate (optional)
certs = $dir/tsa-chain.pem # certification chain (optional)
signer_key = $dir/private/tsa.key # tsa private key (optional)
default_policy = tsa_policy1
signer_digest = sha256 # digest to use for signing (optional)
other_policies = tsa_policy2,tsa_policy3 # other policies (optional)
digests = sha256,sha384,sha512 # acceptable digests (mandatory)
accuracy = secs:1,millisecs:500,microsecs:100 # accuracy optional
ordering = yes # is ordering defined? (optional, default: no)
tsa_name = yes # must tsa name be included in reply? (opt., default: no)
ess_cert_id_chain = yes # must ess cert id change be incl? (opt., default: no)
ess_cert_id_alg = sha256 # alg to compute cert. id (optional, default: sha1)
# added, was missing in the blog post
crypto_device = builtin
# The tsa_ext extension is
# used to create the tsa cert tsa.crt
[ tsa_ext ]
authorityKeyIdentifier = keyid:always
basicConstraints = critical,CA:false
extendedKeyUsage = critical,timeStamping
keyUsage = critical,nonRepudiation
subjectKeyIdentifier = hash