TRC Signing Ceremony Preparation Steps
Each party involved in a TRC signing ceremony must go through a few steps in preparation for the ceremony. This document outlines these steps.
Important
It is required that the machine used to execute the commands has openssl version 3.0.14 or higher installed.
Note
Placeholders
This document contains placeholders for certificate configurations.
Placeholders look like this {{.Property}}
. These placeholders need to be
filled before executing the commands.
Ceremony administrator role
The ceremony administrator should send out the high-level TRC Signing Ceremony description, the appropriate TRC Signing Ceremony Phases document, and this document all in digital form to the participants.
The existing TRC Signing Ceremony Phases documents are listed here:
Furthermore, the ceremony administrator should remind all voters that they need to agree on a common TRC policy before scheduling the TRC ceremony. Importantly, the TRC validity period should be agreed upon, such that every voter can generate certificates that cover the full validity.
The ceremony administrator should bring all digitally distributed documents as a print out for all parties that take part.
Voting AS representative roles
Important
All voters need to agree on a preliminary TRC policy. Especially, the validity period of the TRC, since all the generated certificates must cover the full TRC validity period. The other policy values can be amended during the ceremony itself.
When the preliminary policy is in place. The voters can start generating the necessary certificates.
Create a safe workspace folder
To protect the key material, we recommend using an air-gapped workstation. Next,
a folder for key material and for certificates is created. First navigate to
the desired parent directory (.e.g. cd /home/user
).
To create the folders:
export PUBDIR="$(pwd)/public"
mkdir -p $PUBDIR
export KEYDIR="$(pwd)/keys"
mkdir -p $KEYDIR
Note
For traceability, we recommend that each action in the public directory is committed to git.
Create basic configuration
Navigate to the public directory:
cd $PUBDIR
This directory stores the necessary configurations and created certificates. Private keys are kept in a separate directory to avoid accidental disclosure.
To avoid duplicated information, create a subject.tmpl
that can
be reused for the sensitive voting, regular voting and root certificate:
cat << EOF > subject.tmpl
{
"country": "{{.Country}}",
"state": "{{.State}}",
"locality": "{{.Location}}",
"organization": "{{.Organization}}",
"organizational_unit": "{{.OrganizationalUnit}}",
"isd_as": "{{.ISDAS}}"
}
EOF
export ORG="{{.ShortOrg}}"
Fill in the required fields.
Note
The {{.Country}}
must be replaced with an ISO 3166-1 alpha-2 code.
Switzerland, for example, has the code CH
.
The {{.ShortOrg}}
must be replaced with a short name for the
organization that will be used in the certificate common name.
To avoid duplicated information, create a basic.cnf
that can
be imported from the sensitive voting, regular voting and root certificate
configuration files:
cat << EOF > basic.cnf
[openssl_init]
oid_section = oids
[req]
distinguished_name = req_distinguished_name
prompt = no
[oids]
ISD-AS = SCION ISD-AS number, 1.3.6.1.4.1.55324.1.2.1
sensitive-key = SCION sensitive voting key, 1.3.6.1.4.1.55324.1.3.1
regular-key = SCION regular voting key, 1.3.6.1.4.1.55324.1.3.2
root-key = SCION CP root key, 1.3.6.1.4.1.55324.1.3.3
[req_distinguished_name]
C = {{.Country}}
ST = {{.State}}
L = {{.Location}}
O = {{.Organization}}
OU = {{.OrganizationalUnit}}
CN = \${common_name::name}
ISD-AS = {{.ISDAS}}
[ca]
default_ca = basic_ca
[basic_ca]
default_days = \${ca_defaults::default_days}
default_md = sha256
database = database/index.txt
new_certs_dir = certificates
unique_subject = no
rand_serial = yes
policy = policy_any
[policy_any]
countryName = supplied
stateOrProvinceName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
EOF
Fill in the required fields.
Note
The {{.Country}}
must be replaced with an ISO 3166-1 alpha-2 code.
Switzerland, for example, has the code CH
.
To set the start and end time of a X509 certificate using openssl, the ca
command is necessary. The directory needs to be prepared:
mkdir -p database
touch database/index.txt
mkdir -p certificates
Sensitive voting
This step creates a sensitive voting key and certificate.
Note
The ISD-AS configuration field is optional, but should be provided if the party has an AS identifier, the ISD number must match with the TRC this certificate will be used in.
First, export the sensitive voting certificate common name.
export CN_SENSITIVE="$ORG High Security Voting Certificate"
First, create the sensitive voting certificate configuration. In the file,
replace {{.ShortOrg}}
with the name of your organization:
cat << EOF > sensitive-voting.cnf
openssl_conf = openssl_init
x509_extensions = x509_ext
[common_name]
name = {{.ShortOrg}} High Security Voting Certificate
[x509_ext]
subjectKeyIdentifier = hash
extendedKeyUsage = 1.3.6.1.4.1.55324.1.3.1, 1.3.6.1.5.5.7.3.8
[ca_defaults]
default_days = 1825
.include basic.cnf
EOF
Note
Make sure the common name is different for each certificate type. The proposed name makes it easier for human operators to reason about what the the purpose of the certificate is.
Important
If this step is executed in preparation for a TRC update signing ceremony, make sure that the previous private key and certificate are not overwritten.
For example, you can version the predecessor private key and certificate by running the following command:
# Uncomment and set appropriate value:
#
# PREDID="ISD1-B1-S1"
mkdir -p $KEYDIR/$PREDID $PREDID
mv $KEYDIR/sensitive-voting.key $KEYDIR/$PREDID/sensitive-voting.key
mv sensitive-voting.crt $PREDID/sensitive-voting.crt
Using the subject template, create the sensitive voting key and certificate. The
start and end date need to be replaced with the time when the certificate
becomes valid, and the time when it expires. The format is RFC3339 compliant.
For example, June 24th, 2020 UTC at noon, is formatted as 2020-06-24T12:00:00Z
.
# Uncomment and set the appropriate values:
#
# STARTDATE="2020-06-24T14:00:00+02:00"
# ENDDATE="2021-06-24T14:00:00+02:00"
scion-pki certificate create \
--profile sensitive-voting \
--not-before $STARTDATE \
--not-after $ENDDATE \
--common-name "$CN_SENSITIVE" \
subject.tmpl \
sensitive-voting.crt \
$KEYDIR/sensitive-voting.key
Using this configuration, create the sensitive voting key and certificate. The
start and end date need to be replaced with the time when the certificate
becomes valid, and the time when it expires. The format is YYYYMMDDHHMMSSZ
.
For example, June 24th, 2020 UTC at noon, is formatted as 20200624120000Z
.
The required commands are:
# Uncomment and set the appropriate values:
#
# STARTDATE="20200624120000Z"
# ENDDATE="20250624120000Z"
openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:P-256 \
-pkeyopt ec_param_enc:named_curve -out $KEYDIR/sensitive-voting.key
openssl req -new -key $KEYDIR/sensitive-voting.key -config sensitive-voting.cnf \
-utf8 -out sensitive-voting.csr
openssl ca -in sensitive-voting.csr -config sensitive-voting.cnf \
-keyfile $KEYDIR/sensitive-voting.key -selfsign \
-startdate $STARTDATE -enddate $ENDDATE -preserveDN \
-notext -batch -utf8 -out sensitive-voting.crt
After generating the certificate, check that the output is reasonable:
openssl x509 -in sensitive-voting.crt -noout -dates
openssl x509 -in sensitive-voting.crt -noout -text | grep -o "Signature Algorithm.*"
The validity time must cover the agreed upon TRC validity period.
The certificate can be validated with with the scion-pki
binary:
scion-pki certs validate --type sensitive-voting sensitive-voting.crt
Regular voting
This step creates a regular voting key and certificate.
Note
The ISD-AS configuration field is optional, but should be provided if the party has an AS identifier, the ISD number must match with the TRC this certificate will be used in.
First, export the regular voting certificate common name.
export CN_REGULAR="$ORG Regular Voting Certificate"
Create the regular voting certificate configuration:
cat << EOF > regular-voting.cnf
openssl_conf = openssl_init
x509_extensions = x509_ext
[common_name]
name = {{.ShortOrg}} Regular Voting Certificate
[x509_ext]
subjectKeyIdentifier = hash
extendedKeyUsage = 1.3.6.1.4.1.55324.1.3.2, 1.3.6.1.5.5.7.3.8
[ca_defaults]
default_days = 365
.include basic.cnf
EOF
Note
Make sure the common name is different for each certificate type. The proposed name makes it easier for human operators to reason about what the the purpose of the certificate is.
Important
If this step is executed in preparation for a TRC update signing ceremony, make sure that the previous private key and certificate are not overwritten.
For example, you can version the predecessor private key and certificate by running the following command:
# Uncomment and set appropriate value:
#
# PREDID="ISD1-B1-S1"
mkdir -p $KEYDIR/$PREDID $PREDID
mv $KEYDIR/regular-voting.key $KEYDIR/$PREDID/regular-voting.key
mv regular-voting.crt $PREDID/regular-voting.crt
Using the subject template, create the regular voting key and certificate. The
start and end date need to be replaced with the time when the certificate
becomes valid, and the time when it expires. The format is RFC3339 compliant.
For example, June 24th, 2020 UTC at noon, is formatted as 2020-06-24T12:00:00Z
.
# Uncomment and set the appropriate values:
#
# STARTDATE="2020-06-24T14:00:00+02:00"
# ENDDATE="2021-06-24T14:00:00+02:00"
scion-pki certificate create \
--profile regular-voting \
--not-before $STARTDATE \
--not-after $ENDDATE \
--common-name "$CN_REGULAR" \
subject.tmpl \
regular-voting.crt \
$KEYDIR/regular-voting.key
Using this configuration, create the regular voting key and certificate. The
start and end date need to be replaced with the time when the certificate
becomes valid, and the time when it expires. The format is YYYYMMDDHHMMSSZ
.
For example, June 24th, 2020 UTC at noon, is formatted as 20200624120000Z
.
The required commands are:
# Uncomment and set the appropriate values:
#
# STARTDATE="20200624120000Z"
# ENDDATE="20210624120000Z"
openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:P-256 \
-pkeyopt ec_param_enc:named_curve -out $KEYDIR/regular-voting.key
openssl req -new -key $KEYDIR/regular-voting.key -config regular-voting.cnf \
-utf8 -out regular-voting.csr
openssl ca -in regular-voting.csr -config regular-voting.cnf \
-keyfile $KEYDIR/regular-voting.key -selfsign \
-startdate $STARTDATE -enddate $ENDDATE -preserveDN \
-notext -batch -utf8 -out regular-voting.crt
After generating the certificate, check that the output is reasonable:
openssl x509 -in regular-voting.crt -noout -dates
openssl x509 -in regular-voting.crt -noout -text | grep -o "Signature Algorithm.*"
The validity time must cover the agreed upon TRC validity period.
The certificate can be validated with with the scion-pki
binary:
scion-pki certs validate --type regular-voting regular-voting.crt
CP Root
This step creates a CP root key and certificate.
Note
This step only has to be executed by issuing ASes.
First, export the root certificate common name.
export CN_ROOT="$ORG High Security Root Certificate"
Create the CP root certificate configuration:
cat << EOF > cp-root.cnf
openssl_conf = openssl_init
x509_extensions = x509_ext
[common_name]
name = {{.ShortOrg}} High Security Root Certificate
[x509_ext]
basicConstraints = critical, CA:TRUE, pathlen:1
keyUsage = critical, keyCertSign
subjectKeyIdentifier = hash
extendedKeyUsage = 1.3.6.1.4.1.55324.1.3.3, 1.3.6.1.5.5.7.3.8
[ca_defaults]
default_days = 365
.include basic.cnf
EOF
Note
Make sure the common name is different for each certificate type. The proposed name makes it easier for human operators to reason about what the the purpose of the certificate is.
Important
If this step is executed in preparation for a TRC update signing ceremony, make sure that the previous private key and certificate are not overwritten.
For example, you can version the predecessor private key and certificate by running the following command:
# Uncomment and set appropriate value:
#
# PREDID="ISD1-B1-S1"
mkdir -p $KEYDIR/$PREDID $PREDID
mv $KEYDIR/regular-voting.key $KEYDIR/$PREDID/regular-voting.key
mv regular-voting.crt $PREDID/regular-voting.crt
Using the subject template, create the root key and certificate. The
start and end date need to be replaced with the time when the certificate
becomes valid, and the time when it expires. The format is RFC3339 compliant.
For example, June 24th, 2020 UTC at noon, is formatted as 2020-06-24T12:00:00Z
.
# Uncomment and set the appropriate values:
#
# STARTDATE="2020-06-24T14:00:00+02:00"
# ENDDATE="2021-06-24T14:00:00+02:00"
scion-pki certificate create \
--profile cp-root \
--not-before $STARTDATE \
--not-after $ENDDATE \
--common-name "$CN_ROOT" \
subject.tmpl \
cp-root.crt \
$KEYDIR/cp-root.key
Using this configuration, create the CP root key and certificate. The start and
end date need to be replaced with the time when the certificate becomes valid,
and the time when it expires. The format is YYYYMMDDHHMMSSZ
. For example,
June 24th, 2020 UTC at noon, is formatted as 20200624120000Z
. The required
commands are:
# Uncomment and set the appropriate values:
#
# STARTDATE="20200624120000Z"
# ENDDATE="20210624120000Z"
openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:P-256 \
-pkeyopt ec_param_enc:named_curve -out $KEYDIR/cp-root.key
openssl req -new -key $KEYDIR/cp-root.key -config cp-root.cnf \
-utf8 -out cp-root.csr
openssl ca -in cp-root.csr -config cp-root.cnf \
-keyfile $KEYDIR/cp-root.key -selfsign \
-startdate $STARTDATE -enddate $ENDDATE -preserveDN \
-notext -batch -utf8 -out cp-root.crt
After generating the certificate, check that the output is reasonable:
openssl x509 -in cp-root.crt -noout -dates
openssl x509 -in cp-root.crt -noout -text | grep -o "Signature Algorithm.*"
The validity time must cover the agreed upon TRC validity period.
The certificate can be validated with with the scion-pki
binary:
scion-pki certs validate --type cp-root cp-root.crt