diff --git a/ts-authority/.gitignore b/ts-authority/.gitignore new file mode 100644 index 0000000..6b87dd0 --- /dev/null +++ b/ts-authority/.gitignore @@ -0,0 +1,4 @@ +ca/* +!ca/certs/.gitkeep +!ca/db/.gitkeep +!ca/private/.gitkeep \ No newline at end of file diff --git a/ts-authority/README.md b/ts-authority/README.md new file mode 100644 index 0000000..8da5311 --- /dev/null +++ b/ts-authority/README.md @@ -0,0 +1,153 @@ +# 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 +``` + +Don’t forget the password – you’ll 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 don’t +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 +``` + diff --git a/ts-authority/rootca.conf b/ts-authority/rootca.conf new file mode 100644 index 0000000..f5e0a5c --- /dev/null +++ b/ts-authority/rootca.conf @@ -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 = . # 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