commit a8269203f0e695aca728d847f53694faffbbade6 Author: jose.canelas Date: Fri Aug 5 15:48:02 2022 +0100 Initial commit. This repo contains ansible CM that describes ECG infrastructure. A test server (acacia root server) is already included in the inventory, with an ecg admin account. diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..baf3952 --- /dev/null +++ b/.gitignore @@ -0,0 +1,42 @@ +## DebOps project environment +# See https://docs.debops.org/en/master/user-guide/project-directories.html + +# Autogenerated by the debops script +/ansible.cfg + +# Symlink your debops package here for path consistency +/debops + +# Workshop directories for unfinished roles +/roles +/playbooks + +# Local environment configuration +.env + +#-- python +*.py[co] + +#-- vim +[._]*.s[a-w][a-z] +[._]s[a-w][a-z] +*.un~ +Session.vim +.netrwhist +*~ + +#-- Emacs +\#*\# +/.emacs.desktop +/.emacs.desktop.lock +*.elc +auto-save-list +tramp +.\#* + +#-- SublimeText +*.sublime-workspace +#*.sublime-project + +#-- sftp configuration file +sftp-config.json diff --git a/inventory/group_vars/all/bootstrap.yml b/inventory/group_vars/all/bootstrap.yml new file mode 100644 index 0000000..73e327b --- /dev/null +++ b/inventory/group_vars/all/bootstrap.yml @@ -0,0 +1,9 @@ +--- +netbase__domain: 'ecogood.org' +bootstrap__admin_system: no +bootstrap__admin_default_users: [] +bootstrap__admin_sshkeys: [] +bootstrap__admin_users: + - name: ecg + sshkeys: ["{{ lookup('file', '~/.ssh/id_ed25519-ecg.pub') }}"] + diff --git a/inventory/group_vars/all/common.yml b/inventory/group_vars/all/common.yml new file mode 100644 index 0000000..2eea079 --- /dev/null +++ b/inventory/group_vars/all/common.yml @@ -0,0 +1,6 @@ +--- +netbase__domain: 'ecogood.org' +ntp__timezone: 'Etc/UTC' +bootstrap__admin_sshkeys: '{{ lookup("pipe","ssh-add -L | grep ^ssh || cat ~/.ssh/id_ed25519-ecg.pub || true") }}' +python__v3: 'True' +python__v2: 'False' diff --git a/inventory/group_vars/all/system_users.yml b/inventory/group_vars/all/system_users.yml new file mode 100644 index 0000000..2854289 --- /dev/null +++ b/inventory/group_vars/all/system_users.yml @@ -0,0 +1,17 @@ +--- +system_users__accounts: + - name: 'ecg' + admin: True + shell: '/bin/zsh' + groups: ['users','ssh','sshusers'] + sshkeys: + - 'ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEO5nhjvVvdZawbxBjFnpZ1b0tKP3/6mLihRpbslnzO3 jose.canelas' + - 'ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMmUWXrblLoCkhxTbaZhCPXRxAxVPnTfKXOKleVdYWTG christian.suessenguth' + - 'ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEokDHNJYhqw5LtIhIEPS7q3spM2DZuaLgCPzLLOW9oQ thomas.dedek.portable' + - 'ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICN1LccpNTtO7c3uDr9WeCNl13IKTNdq5ObFEFYSKBGF thomas.dedek.home' + - name: 'z' + admin: True + shell: '/bin/zsh' + groups: ['users','ssh','sshusers'] + sshkeys: + - 'ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEO5nhjvVvdZawbxBjFnpZ1b0tKP3/6mLihRpbslnzO3 jose.canelas' diff --git a/inventory/hosts b/inventory/hosts new file mode 100644 index 0000000..3e3db17 --- /dev/null +++ b/inventory/hosts @@ -0,0 +1,22 @@ +# This is an Ansible inventory file in INI format. You can define a list of +# hosts and groups to be managed by this particular inventory. + +# Hosts listed under [debops_all_hosts] will have common DebOps plays +# ran against them. It will include services such as iptables, DNS, Postfix, +# sshd configuration and more. +# +# View the list here: +# https://github.com/debops/debops/blob/master/ansible/playbooks/common.yml +# +# You should check Getting Started guide for useful suggestions: +# https://docs.debops.org/en/master/introduction/getting-started.html + +# Your host is eligible to be managed by DebOps' common playbook. If you want +# that functionality and more, then uncomment your hostname below. + +[debops_all_hosts] +#blacknode ansible_host=ip6-localhost ansible_connection=local +acacia ansible_host=v220211255864172122.hotsrv.de + +[staging] +acacia diff --git a/secret/credentials/acacia/root_account/password b/secret/credentials/acacia/root_account/password new file mode 100644 index 0000000..486478e --- /dev/null +++ b/secret/credentials/acacia/root_account/password @@ -0,0 +1 @@ +s2FFky-0H,xrR58BaDX3ETBpYBBM.4lB salt=Y9TrHnLvLdyzvVh1 diff --git a/secret/dhparam/params/dh2048.pem b/secret/dhparam/params/dh2048.pem new file mode 100644 index 0000000..faa92a6 --- /dev/null +++ b/secret/dhparam/params/dh2048.pem @@ -0,0 +1,8 @@ +-----BEGIN DH PARAMETERS----- +MIIBCAKCAQEAnZvm6DaiWQXCdfCn9Xsr738NUdbmRZoWj9j5F455/pb2En0ymNak +8g8CmzBRTNM9vL/5Y8ILxl6H14h3hftJm/+UsP0VgG4RMY7hWusPH2Tr2oqNPsNy +ktaoBuPtCevZ3ULQj/roiZLF2EvqwvPaFTMwoAjC46cXgJ79/DZhQIN1rCJaaf6o +9SB9ivVIeRKixkxVQzGIVuGrHmUIhKCC1kT6E7Bij4yCCZp5vWYmovzdDqHNTOTF +LT40ZorqoNjQzout+FImlxI5axHUN9w9uC7nYJ0JYTfxUIOuBVuIOG015LyeSyA/ +w7jv9pMS9rmUPi/1Dewx8UTq8xvWFrzhzwIBAg== +-----END DH PARAMETERS----- diff --git a/secret/dhparam/params/dh3072.pem b/secret/dhparam/params/dh3072.pem new file mode 100644 index 0000000..b3ce6c8 --- /dev/null +++ b/secret/dhparam/params/dh3072.pem @@ -0,0 +1,11 @@ +-----BEGIN DH PARAMETERS----- +MIIBiAKCAYEAmo1yIQ7JrlFjTMSSO6VFHioQr2UfnaCogJdNyccxY0i69d8WaThr +pT1XTHDsAn+Xf4RWjoXFjKWdn8lYiOO0PeZL0RKHLzzayA/PqShEbzAnFHKk87zJ +3GdfcAvG7ZNJtYvAbaA+H4A1/fGnNrbvhBCXdZFrw7mg6d3fjaJV1oNM6piiTQoz +8LU1i1SBrEWx7xJt49fEuYf24tlBxtm7uglNQq02SGdviBGQ5r69TGQEnTIxIL1e +TX2GZd3od5qRWHPVkMUI8QN0e6ngK7FaMl94z+si8NNP7FLQNZE5+E5LXyE1Tk3V +LL0EKYZK77ZaQXLoTST2Go79Wb8aQ8HxeB4jKSsNd1PjC/8Jn6QmgThRnY+wxt8B +9lSnXDcXbY4iK7BvxIxuozq2Yuk5dr9pXgBg5XNyPRJZwi5AnGxeLe69cWJISt4m +9v+1Mih1SIESSQ88UYBUTptdar0TzbG66D3smAt+nv7dDsCDNZclcFkv9m4m96zQ +3TM4jCpnYRfvAgEC +-----END DH PARAMETERS----- diff --git a/secret/journald/fss/acacia/verify_key b/secret/journald/fss/acacia/verify_key new file mode 100644 index 0000000..465f866 --- /dev/null +++ b/secret/journald/fss/acacia/verify_key @@ -0,0 +1 @@ +db4660-569b2f-2aaa26-84a9a9/1c22ac-35a4e900 \ No newline at end of file diff --git a/secret/pki/authorities/domain/certs/9E11BE2C034490ED269C0FAE728EDAF1.pem b/secret/pki/authorities/domain/certs/9E11BE2C034490ED269C0FAE728EDAF1.pem new file mode 100644 index 0000000..8808732 --- /dev/null +++ b/secret/pki/authorities/domain/certs/9E11BE2C034490ED269C0FAE728EDAF1.pem @@ -0,0 +1,32 @@ +-----BEGIN CERTIFICATE----- +MIIFhTCCA22gAwIBAgIRAJ4RviwDRJDtJpwPrnKO2vEwDQYJKoZIhvcNAQELBQAw +JjEQMA4GA1UECgwHRWNvZ29vZDESMBAGA1UECwwJRG9tYWluIENBMB4XDTIyMDgw +MzAzMDkxNloXDTI1MDgwMjAzMDkxNlowHTEbMBkGA1UEAxMSYWNhY2lhLmVjb2dv +b2Qub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA17AI5NtAlFc5 +wY+NayYVDn68LNzgbYOZeTHzOxYoh7iIQxdcDMJWnGEVhQDpKy2ymZ6pAfbIO/Si +UfSR0qqN3vcE/3pPlff3mwshqT/PYXZfYME5YpwkgW3nWtIKSN2zGA3A/nKHFKFD +d6SWbweaUSGeynxhKBHssEVv62FxSoEQRgLjM9t2Vq2Q48Zyv5FNN9dzwKdUihpw +HkmAhyMn8dqycPfnuQ755v3kgMnsLwQ0GivBXw/BoGYx6Xc28e7mhyidjZQIuu2I ++TC3HKSZL9Cl2owwamqDFh19j8HnKwUo5PWrgLfVmZLorX/XuAqC998lznAjTokG +NcDqaqxktwIDAQABo4IBtTCCAbEwbQYIKwYBBQUHAQEEYTBfMC0GCCsGAQUFBzAC +hiFodHRwOi8vZG9tYWluLWNhLmVjb2dvb2Qub3JnL2NydC8wLgYIKwYBBQUHMAGG +Imh0dHA6Ly9kb21haW4tY2EuZWNvZ29vZC5vcmcvb2NzcC8wXwYDVR0jBFgwVoAU +NjKTdoP4roaBWMjJ8qs497PJ8NihLKQqMCgxJjAkBgNVBAoMHUVjb2dvb2QgQ2Vy +dGlmaWNhdGUgQXV0aG9yaXR5ghAc/alS+Prue8lEkmpvlO5zMAwGA1UdEwEB/wQC +MAAwMgYDVR0fBCswKTAnoCWgI4YhaHR0cDovL2RvbWFpbi1jYS5lY29nb29kLm9y +Zy9jcmwvMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcDATAOBgNVHQ8BAf8E +BAMCBaAwHQYDVR0OBBYEFHtIuZuwcsCWQyB/X3LejynZe3SgME8GA1UdEQRIMEaC +C2Vjb2dvb2Qub3JnghJhY2FjaWEuZWNvZ29vZC5vcmeCFCouYWNhY2lhLmVjb2dv +b2Qub3Jngg0qLmVjb2dvb2Qub3JnMA0GCSqGSIb3DQEBCwUAA4ICAQB2oKIVEYd2 +5b1t9qZSaJbZ28KZJFoHiJO/ZXHa9ejD+wnxV1ie0nzSV+GY5sEqwXPEOpTU0MSi +fgaEwR5J54FhD4iNOH3zM/22nbtVvkkDAZshH37VHLvDZ9u81gCVLLGtD+JV2u8F +Gr/xHPRS8H5QpLIeeLW4wXPGbS7Wrb8xttvzdL5yveF45gXAxgCr7ww4uexcMN0M +mR+EFcDICOnfcA0pUFFWDnGfEZef4/5s7Z/7CgIN/PhUGwPE9FsR6e4YqHFyzr19 +RJi+kvjMxT/8HL05WLoxAF8g/XGy6dxsUUjxQP06gAXkjmFBHv9RJZg958xqZtY2 +grYg+8ULLm5aSIxkgJJM8+D6nYa2Um6/vdPsQFGjhSN0KKvfDyWQKxmZezTEklq8 +gP1ZwbWlsoW/yg8FGaBOHUQpmGsYzlAs0fTETLuvNrthb7yOtp7h8DBG4DVGPZ6+ +rECdPlpNdOg/yT05Mq9qWIDsw7onTnm1lvMwYLstT4OSi7atAia6fi0b/VdFkiyk +fqsjqwvkmdR/albcQ2Lyh/kQ49KGGpZEiLxFjZImsN9+XA/ych4FpH6EuPrNxA2h +WLThz/XhpsqhFq1bejGVc4VgJ7uUy5OwlX9F6JvNohQTY00TAUy+qhFcroewNrCA +eziVOPxbRSp+ozGLwTcIjxTUmJErS2vOYw== +-----END CERTIFICATE----- diff --git a/secret/pki/authorities/domain/config/authority.conf b/secret/pki/authorities/domain/config/authority.conf new file mode 100644 index 0000000..79c2c80 --- /dev/null +++ b/secret/pki/authorities/domain/config/authority.conf @@ -0,0 +1,30 @@ +# Configuration file generated by pki-authority + +config['pki_default_root_sign_multiplier']='12' +config['pki_library']='openssl' +config['name_constraints_critical']='True' +config['crl']='True' +config['pki_default_ca_sign_multiplier']='10' +config['subject']='o=Ecogood/ou=Domain CA' +config['pki_default_domain_dn']='' +config['pki_default_domain']='' +config['issuer_name']='root' +config['key_size']='4096' +config['name_constraints']='True' +config['private_file_mode']='600' +config['private_dir_mode']='700' +config['public_file_mode']='644' +config['domain']='ecogood.org' +config['root_sign_days']='' +config['ocsp']='True' +config['ca_sign_days']='' +config['pki_default_cert_sign_multiplier']='3' +config['pki_default_sign_base']='365' +config['pki_default_fqdn']='blacknode' +config['system_ca']='true' +config['public_dir_mode']='755' +config['ca_type']='' +config['alt_authority']='' +config['subdomain']='domain-ca' +config['cert_sign_days']='' +config['name']='domain' diff --git a/secret/pki/authorities/domain/config/openssl-request.conf b/secret/pki/authorities/domain/config/openssl-request.conf new file mode 100644 index 0000000..d07dbdc --- /dev/null +++ b/secret/pki/authorities/domain/config/openssl-request.conf @@ -0,0 +1,15 @@ +# Configuration file generated by pki-authority + +[ req ] +default_md = sha256 +default_bits = 4096 +default_keyfile = private/key.pem +prompt = no +encrypt_key = no +distinguished_name = ca_dn +utf8 = yes +string_mask = utf8only + +[ ca_dn ] +organizationName=Ecogood +organizationalUnitName=Domain CA diff --git a/secret/pki/authorities/domain/config/openssl-sign.conf b/secret/pki/authorities/domain/config/openssl-sign.conf new file mode 100644 index 0000000..eedcf4d --- /dev/null +++ b/secret/pki/authorities/domain/config/openssl-sign.conf @@ -0,0 +1,59 @@ +# Configuration file generated by pki-authority + +[ default ] +name = domain-ca +domain_suffix = ecogood.org +aia_url = http://$name.$domain_suffix/crt/ +crl_url = http://$name.$domain_suffix/crl/ +ocsp_url = http://$name.$domain_suffix/ocsp/ +default_ca = ca_default +name_opt = utf8,esc_ctrl,multiline,lname,align + +[ ca_default ] +home = . +database = $home/database/index +serial = $home/database/serial +crlnumber = $home/database/crlnumber +certificate = $home/subject/cert.pem +private_key = $home/private/key.pem +RANDFILE = $home/private/random +new_certs_dir = $home/certs +unique_subject = no +policy = policy_default +x509_extensions = extension_default +copy_extensions = copy +default_days = 1095 +default_crl_days = 30 +default_md = sha256 + +[ crl_info ] +URI.0 = $crl_url + +[ issuer_info ] +caIssuers;URI.0 = $aia_url +OCSP;URI.0 = $ocsp_url + +[ extension_ocsp ] +authorityKeyIdentifier = keyid:always +basicConstraints = critical, CA:false +extendedKeyUsage = OCSPSigning +keyUsage = critical, digitalSignature +subjectKeyIdentifier = hash + +[ policy_default ] +countryName = optional +stateOrProvinceName = optional +organizationName = optional +organizationalUnitName = optional +commonName = optional +emailAddress = optional + +[ extension_default ] +authorityInfoAccess = @issuer_info +authorityKeyIdentifier = keyid:always, issuer:always +basicConstraints = critical, CA:FALSE +crlDistributionPoints = @crl_info +extendedKeyUsage = clientAuth, serverAuth +keyUsage = critical, digitalSignature, keyEncipherment +subjectKeyIdentifier = hash + diff --git a/secret/pki/authorities/domain/database/index b/secret/pki/authorities/domain/database/index new file mode 100644 index 0000000..92d68dd --- /dev/null +++ b/secret/pki/authorities/domain/database/index @@ -0,0 +1 @@ +V 250802030916Z 9E11BE2C034490ED269C0FAE728EDAF1 unknown /CN=acacia.ecogood.org diff --git a/secret/pki/authorities/domain/database/index.attr b/secret/pki/authorities/domain/database/index.attr new file mode 100644 index 0000000..3a7e39e --- /dev/null +++ b/secret/pki/authorities/domain/database/index.attr @@ -0,0 +1 @@ +unique_subject = no diff --git a/secret/pki/authorities/domain/database/index.old b/secret/pki/authorities/domain/database/index.old new file mode 100644 index 0000000..e69de29 diff --git a/secret/pki/authorities/domain/database/serial b/secret/pki/authorities/domain/database/serial new file mode 100644 index 0000000..3c606e2 --- /dev/null +++ b/secret/pki/authorities/domain/database/serial @@ -0,0 +1 @@ +9E11BE2C034490ED269C0FAE728EDAF2 diff --git a/secret/pki/authorities/domain/database/serial.old b/secret/pki/authorities/domain/database/serial.old new file mode 100644 index 0000000..ae07051 --- /dev/null +++ b/secret/pki/authorities/domain/database/serial.old @@ -0,0 +1 @@ +9e11be2c034490ed269c0fae728edaf1 diff --git a/secret/pki/authorities/domain/issuer b/secret/pki/authorities/domain/issuer new file mode 120000 index 0000000..3afde58 --- /dev/null +++ b/secret/pki/authorities/domain/issuer @@ -0,0 +1 @@ +../root \ No newline at end of file diff --git a/secret/pki/authorities/domain/private/key.pem b/secret/pki/authorities/domain/private/key.pem new file mode 100644 index 0000000..ec8e3a0 --- /dev/null +++ b/secret/pki/authorities/domain/private/key.pem @@ -0,0 +1,52 @@ +-----BEGIN PRIVATE KEY----- +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 +4H7eGg47R3RDPu+kthpLnuUZfj4Tkg== +-----END PRIVATE KEY----- diff --git a/secret/pki/authorities/domain/subject/cert.pem b/secret/pki/authorities/domain/subject/cert.pem new file mode 100644 index 0000000..e5ed858 --- /dev/null +++ b/secret/pki/authorities/domain/subject/cert.pem @@ -0,0 +1,35 @@ +-----BEGIN CERTIFICATE----- +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 +xFbmxNO3xP17AYJgwQgdxzep +-----END CERTIFICATE----- diff --git a/secret/pki/authorities/domain/subject/request.pem b/secret/pki/authorities/domain/subject/request.pem new file mode 100644 index 0000000..f1a4e14 --- /dev/null +++ b/secret/pki/authorities/domain/subject/request.pem @@ -0,0 +1,26 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIIEazCCAlMCAQAwJjEQMA4GA1UECgwHRWNvZ29vZDESMBAGA1UECwwJRG9tYWlu +IENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAtYbm1RUaqATfXtRx +hIYT2n4GkI3zjRtFT7VlOGTI7oAmO/VN73UgUbGLzmETHx2M3aMrz2DBPDjud4Z4 +EfDMlUYh+7KZv9HEQGr08DGF/lBtb1OHWVXlaJNw9JCAli8rv0ZD/1SEygWY3HUr +15j02W04TY+r44bYprqi5pcUFoSqUqCxm2XSxBuDt9fUEysy6MUI7EJWYfbogLZO +cR7zEVfUQIqdpPcSIdEnzd/NVmSw7rUGlnf7DyuGOKLCRBDkVItRRC9/XTk90Viv +S5i0NHwUr3nPMrZVGrsx8CJ0PVGN6sHkMQWeNC9QHMzZSXHyhydonl2QeD9WEeDD +kgWv5Xrf4zQ9nkrtu9saFqyIEunuUthGH4g2rMd3SiJeVngEbqw1wEUNQegRRE+h +5buNZh1gunRfxnd7n34QXnHPajaf2wHUEt8ygViScl+8tRqJu7eFApPBc7EORany +s7dkWKC2IweiOD3nEjz7GioxWXV+2AU4SAgF0kEOMrfNl8sHQ6IZXd/y3KmjV5Y9 +NvUnBt1qWT6YWfE2Bn8ck8NZ+alEPvsbkhxO4mcLrVWhfGNR5a6lc1Jm4RxKH+VN +PS5ShmjXmtZ8QlvhQajGZrG7DXIpDX/9TTR9oXFnSqIDUdHZEXbgbAvgqP6qN0G5 +wLDV7TsNedrFjhdyNr3iDTyje9kCAwEAAaAAMA0GCSqGSIb3DQEBCwUAA4ICAQCg +uFyxpr6yKQ6ALTvsJTS+w4/vV15Ymco5rZeOhpJgFNkHBTvqkI/yZm60mbLrVmDk +Jq3tLBEsZ9CsFGwaIeFWezK/knXjNV4rGjYH+KiZWAv63LzdKveSqYk2gFqMnRxg +xwsPuwzLMaCh+w2FKb9875DKWhw6hYZq/suECPDmdt5EjQxbtXZiDVM0+BIjdZA9 +7OYREkAmc0Ss56/3nvXvWPSDk/tBLLOx9bd3PHo7N0GEre0P9RaWKAbdQ+sN8i3x +WzfrSfGrunFcfqb/N4du/5jC6PtL8QsqeDOdrMv+ipOY+QTAnLrTLNn7zOWk6x8x +pUjsQ4n57Ie4tiSMNh52WdXAv3So8ZnJJX1X4EG02BM1LGeHef4D5V9wHhDgUAvf +pWGpiNS9SiTo8bm0Ni93thd6P9dJYA27QvzlUxjFxecJWvLQZLigH32QHod9uQ1z +T1DKTR3cbcHCUWxrhanxN8pNutWAnOaebus67u7gFgtT2znvzLXyTLrfLc4FGmYa +9ZLjyQUPSl9hJFvch9qhF7lNTpRovk+G3CO6jhTe/P30rDsTnraN7V3fsPd8u2tD +09Av6IwGv8ktLO0RU+rAmSq1jbRUCTtKREWP4z04/cTXjhGkEdRsUs/NlBj3Yn4R +aUpXHL8Ppe1Pd0i1+FadAXnBgfraS0R9lRdp7i/JOQ== +-----END CERTIFICATE REQUEST----- diff --git a/secret/pki/authorities/root/certs/1CFDA952F8FAEE7BC944926A6F94EE72.pem b/secret/pki/authorities/root/certs/1CFDA952F8FAEE7BC944926A6F94EE72.pem new file mode 100644 index 0000000..5d67b72 --- /dev/null +++ b/secret/pki/authorities/root/certs/1CFDA952F8FAEE7BC944926A6F94EE72.pem @@ -0,0 +1,31 @@ +-----BEGIN CERTIFICATE----- +MIIFSzCCAzOgAwIBAgIQHP2pUvj67nvJRJJqb5TucjANBgkqhkiG9w0BAQsFADAo +MSYwJAYDVQQKDB1FY29nb29kIENlcnRpZmljYXRlIEF1dGhvcml0eTAeFw0yMjA4 +MDMwMzA5MTRaFw0zNDA3MzEwMzA5MTRaMCgxJjAkBgNVBAoMHUVjb2dvb2QgQ2Vy +dGlmaWNhdGUgQXV0aG9yaXR5MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKC +AgEAt8EJQWlwfKldOOLjHB2HktYMy1Wq5qzL91l5sgjD7iJP30RJtYRHnpt75hSL +x+eWmmgWj8fgWjnvep+VU/EK9udp7X4R5xFQUwShZwZ+koumZEoPTQDVFR7dk+5/ +JOcOeP6KeoYs8szOADioIuKHn9sHSTeAh6nwQ1QeuroWij/BQG0Bt+euJSWScotB +tILlW9AXtSNs96LAo1XbMpRDbUGdlpJltH5XZAYicRO72Cx/9OUSEX48lSe88ER5 +6qWZ+/oLJZvE5a2XuUjli8lfJJvAHvULfVRuhA4wQyYBV/RACLZgLAhjRuV7OqQl +GxP0Rt8dChHXqPhsjzsfms+2/1qnodAPNBqNXL9f49LwB6yDqlnu9qD/GHefECcE +NGBBpGU53RBwHLfjImyUgLtnvteVbyaqtZb18aXwSB7iUPpnAezgvARE/EpebTX7 +bhWcEmvvd8MxhwhR8mg5cSC1MOF8Zo8Xth4wD/3cheQlbEUEtxTm0eIJ3FWHfwJC +HEretQwSS9jWtwz0rFd/G7yoZHlw+9dIRzdrzimAsTs5xXJ3hu3QoRkrgd4ecyfU +sd9kuYl8WVPoquduAwhD094L47fWO9Q13HNim+amnfEHVLpxZn1VN6pRmloljiy1 +mAVgNUeaUonwQR2kP9RRMEoq5Xi6T1qSr3eXkta6L8KreTMCAwEAAaNxMG8wDwYD +VR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFCvynbzX8gr+ +U86oDP/t8mx3NeJNMC0GA1UdHgEB/wQjMCGgHzANggtlY29nb29kLm9yZzAOggwu +ZWNvZ29vZC5vcmcwDQYJKoZIhvcNAQELBQADggIBAK1B7qR3995EGk0OIG09k6G4 +usY+gs+ZbfVfcF4nQKvtUHf53VqtbZjqN6CybTnYzIT9frWQIVbwzClpvksyhg00 +XYDAfsI8uF1NFnJJ1OVeax6sDgOLRsyZ73J+1WEqCtr1kvsbJ5lR5ydQ2RpkUR9e +jEpEZQnAkXrlq4967TxZhMg7YWd4QG/8vffEkSxFpmAA96CTv4vbHkFZMun98ynx +P+3AFCISPMGHQViwa18iKKYFoqqlp2OFSNdMzFwM1fAtRrzIv928+a+4dPwRVLAF +0ozF8RuaUdHhr92CSWqmbB5LYelhV5ltK1n14JoxcmdL0xnoICgkPzYFHLenZ3I4 +93oej/UJuxDd06BorzcDtD57E6yBUXbKu0eUDUNfAbb+26zpWXjR18w5i2GCyE+9 +swUf4T6Ef6KXZzb653FjtjYwrCZ9E0A8xRKDQbNsXLdXCkL9WSdLk86k/PSr1jlO +sF1ywGPw5Cap25aOPVILnHUWitN3jpJaWdTW1oK7vrWhPDhhGKV0P+ya9U6jOgOt +qqgw8ycaVibyCXTPTDvmIkbuTwXdissVFzbld1RMO7jJk8mOumrZCfd3Qr5sPEBz +UH0oho4Dt4v6RU9H6lPC4sfghY4wDYMvPragSU0Opu6Rpl51OAgqc2NSszhJ9PHU +vnoVLlLRclNT+2lh5/XZ +-----END CERTIFICATE----- diff --git a/secret/pki/authorities/root/certs/1CFDA952F8FAEE7BC944926A6F94EE73.pem b/secret/pki/authorities/root/certs/1CFDA952F8FAEE7BC944926A6F94EE73.pem new file mode 100644 index 0000000..e5ed858 --- /dev/null +++ b/secret/pki/authorities/root/certs/1CFDA952F8FAEE7BC944926A6F94EE73.pem @@ -0,0 +1,35 @@ +-----BEGIN CERTIFICATE----- +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 +xFbmxNO3xP17AYJgwQgdxzep +-----END CERTIFICATE----- diff --git a/secret/pki/authorities/root/config/authority.conf b/secret/pki/authorities/root/config/authority.conf new file mode 100644 index 0000000..19c4c2b --- /dev/null +++ b/secret/pki/authorities/root/config/authority.conf @@ -0,0 +1,30 @@ +# Configuration file generated by pki-authority + +config['pki_default_root_sign_multiplier']='12' +config['pki_library']='openssl' +config['name_constraints_critical']='True' +config['crl']='True' +config['pki_default_ca_sign_multiplier']='10' +config['subject']='o=Ecogood Certificate Authority' +config['pki_default_domain_dn']='' +config['pki_default_domain']='' +config['issuer_name']='' +config['key_size']='4096' +config['name_constraints']='True' +config['private_file_mode']='600' +config['private_dir_mode']='700' +config['public_file_mode']='644' +config['domain']='ecogood.org' +config['root_sign_days']='' +config['ocsp']='True' +config['ca_sign_days']='' +config['pki_default_cert_sign_multiplier']='3' +config['pki_default_sign_base']='365' +config['pki_default_fqdn']='blacknode' +config['system_ca']='true' +config['public_dir_mode']='755' +config['ca_type']='' +config['alt_authority']='' +config['subdomain']='root-ca' +config['cert_sign_days']='' +config['name']='root' diff --git a/secret/pki/authorities/root/config/openssl-request.conf b/secret/pki/authorities/root/config/openssl-request.conf new file mode 100644 index 0000000..b747981 --- /dev/null +++ b/secret/pki/authorities/root/config/openssl-request.conf @@ -0,0 +1,14 @@ +# Configuration file generated by pki-authority + +[ req ] +default_md = sha256 +default_bits = 4096 +default_keyfile = private/key.pem +prompt = no +encrypt_key = no +distinguished_name = ca_dn +utf8 = yes +string_mask = utf8only + +[ ca_dn ] +organizationName=Ecogood Certificate Authority diff --git a/secret/pki/authorities/root/config/openssl-selfsign.conf b/secret/pki/authorities/root/config/openssl-selfsign.conf new file mode 100644 index 0000000..205002a --- /dev/null +++ b/secret/pki/authorities/root/config/openssl-selfsign.conf @@ -0,0 +1,56 @@ +# Configuration file generated by pki-authority + +[ default ] +name = root-ca +domain_suffix = ecogood.org +aia_url = http://$name.$domain_suffix/crt/ +crl_url = http://$name.$domain_suffix/crl/ +ocsp_url = http://$name.$domain_suffix/ocsp/ +default_ca = ca_default +name_opt = utf8,esc_ctrl,multiline,lname,align + +[ ca_default ] +home = . +database = $home/database/index +serial = $home/database/serial +crlnumber = $home/database/crlnumber +certificate = $home/subject/cert.pem +private_key = $home/private/key.pem +RANDFILE = $home/private/random +new_certs_dir = $home/certs +unique_subject = no +copy_extensions = none +default_days = 4380 +default_crl_days = 365 +default_md = sha256 +policy = policy_default +x509_extensions = extension_default + +[ crl_info ] +URI.0 = $crl_url + +[ issuer_info ] +caIssuers;URI.0 = $aia_url +OCSP;URI.0 = $ocsp_url + +[ extension_ocsp ] +authorityKeyIdentifier = keyid:always +basicConstraints = critical, CA:false +extendedKeyUsage = OCSPSigning +keyUsage = critical, digitalSignature +subjectKeyIdentifier = hash + +[ policy_default ] +countryName = optional +stateOrProvinceName = optional +organizationName = optional +organizationalUnitName = optional +commonName = optional +emailAddress = optional + +[ extension_default ] +basicConstraints = critical, CA:TRUE +keyUsage = critical, keyCertSign, cRLSign +subjectKeyIdentifier = hash +nameConstraints = critical, permitted;DNS:ecogood.org,permitted;DNS:.ecogood.org + diff --git a/secret/pki/authorities/root/config/openssl-sign.conf b/secret/pki/authorities/root/config/openssl-sign.conf new file mode 100644 index 0000000..b392618 --- /dev/null +++ b/secret/pki/authorities/root/config/openssl-sign.conf @@ -0,0 +1,59 @@ +# Configuration file generated by pki-authority + +[ default ] +name = root-ca +domain_suffix = ecogood.org +aia_url = http://$name.$domain_suffix/crt/ +crl_url = http://$name.$domain_suffix/crl/ +ocsp_url = http://$name.$domain_suffix/ocsp/ +default_ca = ca_default +name_opt = utf8,esc_ctrl,multiline,lname,align + +[ ca_default ] +home = . +database = $home/database/index +serial = $home/database/serial +crlnumber = $home/database/crlnumber +certificate = $home/subject/cert.pem +private_key = $home/private/key.pem +RANDFILE = $home/private/random +new_certs_dir = $home/certs +unique_subject = no +policy = policy_default +x509_extensions = extension_default +copy_extensions = none +default_days = 3650 +default_crl_days = 365 +default_md = sha256 + +[ crl_info ] +URI.0 = $crl_url + +[ issuer_info ] +caIssuers;URI.0 = $aia_url +OCSP;URI.0 = $ocsp_url + +[ extension_ocsp ] +authorityKeyIdentifier = keyid:always +basicConstraints = critical, CA:false +extendedKeyUsage = OCSPSigning +keyUsage = critical, digitalSignature +subjectKeyIdentifier = hash + +[ policy_default ] +countryName = optional +stateOrProvinceName = optional +organizationName = optional +organizationalUnitName = optional +commonName = optional +emailAddress = optional + +[ extension_default ] +authorityInfoAccess = @issuer_info +authorityKeyIdentifier = keyid:always +basicConstraints = critical, CA:TRUE, pathlen:0 +crlDistributionPoints = @crl_info +keyUsage = critical, keyCertSign, cRLSign +subjectKeyIdentifier = hash +nameConstraints = critical, permitted;DNS:ecogood.org,permitted;DNS:.ecogood.org + diff --git a/secret/pki/authorities/root/database/index b/secret/pki/authorities/root/database/index new file mode 100644 index 0000000..48d1d9a --- /dev/null +++ b/secret/pki/authorities/root/database/index @@ -0,0 +1,2 @@ +V 340731030914Z 1CFDA952F8FAEE7BC944926A6F94EE72 unknown /O=Ecogood Certificate Authority +V 320731030916Z 1CFDA952F8FAEE7BC944926A6F94EE73 unknown /O=Ecogood/OU=Domain CA diff --git a/secret/pki/authorities/root/database/index.attr b/secret/pki/authorities/root/database/index.attr new file mode 100644 index 0000000..3a7e39e --- /dev/null +++ b/secret/pki/authorities/root/database/index.attr @@ -0,0 +1 @@ +unique_subject = no diff --git a/secret/pki/authorities/root/database/index.attr.old b/secret/pki/authorities/root/database/index.attr.old new file mode 100644 index 0000000..3a7e39e --- /dev/null +++ b/secret/pki/authorities/root/database/index.attr.old @@ -0,0 +1 @@ +unique_subject = no diff --git a/secret/pki/authorities/root/database/index.old b/secret/pki/authorities/root/database/index.old new file mode 100644 index 0000000..88eeef7 --- /dev/null +++ b/secret/pki/authorities/root/database/index.old @@ -0,0 +1 @@ +V 340731030914Z 1CFDA952F8FAEE7BC944926A6F94EE72 unknown /O=Ecogood Certificate Authority diff --git a/secret/pki/authorities/root/database/serial b/secret/pki/authorities/root/database/serial new file mode 100644 index 0000000..31b852d --- /dev/null +++ b/secret/pki/authorities/root/database/serial @@ -0,0 +1 @@ +1CFDA952F8FAEE7BC944926A6F94EE74 diff --git a/secret/pki/authorities/root/database/serial.old b/secret/pki/authorities/root/database/serial.old new file mode 100644 index 0000000..3b16fe5 --- /dev/null +++ b/secret/pki/authorities/root/database/serial.old @@ -0,0 +1 @@ +1CFDA952F8FAEE7BC944926A6F94EE73 diff --git a/secret/pki/authorities/root/private/key.pem b/secret/pki/authorities/root/private/key.pem new file mode 100644 index 0000000..606f110 --- /dev/null +++ b/secret/pki/authorities/root/private/key.pem @@ -0,0 +1,52 @@ +-----BEGIN PRIVATE KEY----- +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 +AoZ7VnsZwKdGLZlpsxH43DYDCxV32w== +-----END PRIVATE KEY----- diff --git a/secret/pki/authorities/root/subject/cert.pem b/secret/pki/authorities/root/subject/cert.pem new file mode 100644 index 0000000..5d67b72 --- /dev/null +++ b/secret/pki/authorities/root/subject/cert.pem @@ -0,0 +1,31 @@ +-----BEGIN CERTIFICATE----- +MIIFSzCCAzOgAwIBAgIQHP2pUvj67nvJRJJqb5TucjANBgkqhkiG9w0BAQsFADAo +MSYwJAYDVQQKDB1FY29nb29kIENlcnRpZmljYXRlIEF1dGhvcml0eTAeFw0yMjA4 +MDMwMzA5MTRaFw0zNDA3MzEwMzA5MTRaMCgxJjAkBgNVBAoMHUVjb2dvb2QgQ2Vy +dGlmaWNhdGUgQXV0aG9yaXR5MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKC +AgEAt8EJQWlwfKldOOLjHB2HktYMy1Wq5qzL91l5sgjD7iJP30RJtYRHnpt75hSL +x+eWmmgWj8fgWjnvep+VU/EK9udp7X4R5xFQUwShZwZ+koumZEoPTQDVFR7dk+5/ +JOcOeP6KeoYs8szOADioIuKHn9sHSTeAh6nwQ1QeuroWij/BQG0Bt+euJSWScotB +tILlW9AXtSNs96LAo1XbMpRDbUGdlpJltH5XZAYicRO72Cx/9OUSEX48lSe88ER5 +6qWZ+/oLJZvE5a2XuUjli8lfJJvAHvULfVRuhA4wQyYBV/RACLZgLAhjRuV7OqQl +GxP0Rt8dChHXqPhsjzsfms+2/1qnodAPNBqNXL9f49LwB6yDqlnu9qD/GHefECcE +NGBBpGU53RBwHLfjImyUgLtnvteVbyaqtZb18aXwSB7iUPpnAezgvARE/EpebTX7 +bhWcEmvvd8MxhwhR8mg5cSC1MOF8Zo8Xth4wD/3cheQlbEUEtxTm0eIJ3FWHfwJC +HEretQwSS9jWtwz0rFd/G7yoZHlw+9dIRzdrzimAsTs5xXJ3hu3QoRkrgd4ecyfU +sd9kuYl8WVPoquduAwhD094L47fWO9Q13HNim+amnfEHVLpxZn1VN6pRmloljiy1 +mAVgNUeaUonwQR2kP9RRMEoq5Xi6T1qSr3eXkta6L8KreTMCAwEAAaNxMG8wDwYD +VR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFCvynbzX8gr+ +U86oDP/t8mx3NeJNMC0GA1UdHgEB/wQjMCGgHzANggtlY29nb29kLm9yZzAOggwu +ZWNvZ29vZC5vcmcwDQYJKoZIhvcNAQELBQADggIBAK1B7qR3995EGk0OIG09k6G4 +usY+gs+ZbfVfcF4nQKvtUHf53VqtbZjqN6CybTnYzIT9frWQIVbwzClpvksyhg00 +XYDAfsI8uF1NFnJJ1OVeax6sDgOLRsyZ73J+1WEqCtr1kvsbJ5lR5ydQ2RpkUR9e +jEpEZQnAkXrlq4967TxZhMg7YWd4QG/8vffEkSxFpmAA96CTv4vbHkFZMun98ynx +P+3AFCISPMGHQViwa18iKKYFoqqlp2OFSNdMzFwM1fAtRrzIv928+a+4dPwRVLAF +0ozF8RuaUdHhr92CSWqmbB5LYelhV5ltK1n14JoxcmdL0xnoICgkPzYFHLenZ3I4 +93oej/UJuxDd06BorzcDtD57E6yBUXbKu0eUDUNfAbb+26zpWXjR18w5i2GCyE+9 +swUf4T6Ef6KXZzb653FjtjYwrCZ9E0A8xRKDQbNsXLdXCkL9WSdLk86k/PSr1jlO +sF1ywGPw5Cap25aOPVILnHUWitN3jpJaWdTW1oK7vrWhPDhhGKV0P+ya9U6jOgOt +qqgw8ycaVibyCXTPTDvmIkbuTwXdissVFzbld1RMO7jJk8mOumrZCfd3Qr5sPEBz +UH0oho4Dt4v6RU9H6lPC4sfghY4wDYMvPragSU0Opu6Rpl51OAgqc2NSszhJ9PHU +vnoVLlLRclNT+2lh5/XZ +-----END CERTIFICATE----- diff --git a/secret/pki/authorities/root/subject/request.pem b/secret/pki/authorities/root/subject/request.pem new file mode 100644 index 0000000..ea616e6 --- /dev/null +++ b/secret/pki/authorities/root/subject/request.pem @@ -0,0 +1,26 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIIEbTCCAlUCAQAwKDEmMCQGA1UECgwdRWNvZ29vZCBDZXJ0aWZpY2F0ZSBBdXRo +b3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC3wQlBaXB8qV04 +4uMcHYeS1gzLVarmrMv3WXmyCMPuIk/fREm1hEeem3vmFIvH55aaaBaPx+BaOe96 +n5VT8Qr252ntfhHnEVBTBKFnBn6Si6ZkSg9NANUVHt2T7n8k5w54/op6hizyzM4A +OKgi4oef2wdJN4CHqfBDVB66uhaKP8FAbQG3564lJZJyi0G0guVb0Be1I2z3osCj +VdsylENtQZ2WkmW0fldkBiJxE7vYLH/05RIRfjyVJ7zwRHnqpZn7+gslm8TlrZe5 +SOWLyV8km8Ae9Qt9VG6EDjBDJgFX9EAItmAsCGNG5Xs6pCUbE/RG3x0KEdeo+GyP +Ox+az7b/Wqeh0A80Go1cv1/j0vAHrIOqWe72oP8Yd58QJwQ0YEGkZTndEHAct+Mi +bJSAu2e+15VvJqq1lvXxpfBIHuJQ+mcB7OC8BET8Sl5tNftuFZwSa+93wzGHCFHy +aDlxILUw4Xxmjxe2HjAP/dyF5CVsRQS3FObR4gncVYd/AkIcSt61DBJL2Na3DPSs +V38bvKhkeXD710hHN2vOKYCxOznFcneG7dChGSuB3h5zJ9Sx32S5iXxZU+iq524D +CEPT3gvjt9Y71DXcc2Kb5qad8QdUunFmfVU3qlGaWiWOLLWYBWA1R5pSifBBHaQ/ +1FEwSirleLpPWpKvd5eS1rovwqt5MwIDAQABoAAwDQYJKoZIhvcNAQELBQADggIB +AAPc3VAFM+uCl+zQ6VY9kpbO0phA6sDgF5DDEeVUxJLxYtyGZte5jS9UdmlcaPzD +saWlNGXY+TXkzZziTEoGdSfxJ2pQ2/ROa4xR6+Nh4TxzSG2XUC1QhX2XKu70Bbmg +swkVKY2s4vcUdNthpAfFFMdLvX+UBK8bf8pqf7kNBtlv2zXhg5Cb2TYL5xwECutR +yYAdWOYNsSgOwfM57VSFnNxVLVdA08L0TYNrzm+DtbxJfXhR6kiwnjSzrXysixTi +Q23WwU+cXccbZA2Sz4OL0j3Ia8vgMPxaRAMaPeuMmSG5vuo1T6UQVHIZ91jFCrJT +0hXr8IsiOh7+f2oodBQQtkHtCqt3ZE+9j0yPj7FHiGyDYpLsRkUpS2cZw2DGQFto +e8FAytNUbyMb2Q95OqnFOC9QaW4urG2hKw7T95OqhmhOU4gCtwoRTP4EgQbHr9Cw +574otYxE6ZC+KiZX04gXz0q93eE0yyMDaxOOW+3831IWSTqCvwHCa/viSZhngdCu +lGE0FPI/RewuEhDckiwooLDBeh/3MXF4IhO6gRP4GrnWqa0vqIc/OzdQl2CYR73F +1PG1QhXlpsTcOHYLg0yTm1uR/hunFwgMnb068PXX+LIIphOpJ32isDOm4PpWN6Xe ++p50MNT7ACWCx0AP5IXOGrPxuWoQPrz38OJUDiALh5EH +-----END CERTIFICATE REQUEST----- diff --git a/secret/pki/ca-certificates/by-group/all/root-ca.ecogood.org.crt b/secret/pki/ca-certificates/by-group/all/root-ca.ecogood.org.crt new file mode 120000 index 0000000..c64c345 --- /dev/null +++ b/secret/pki/ca-certificates/by-group/all/root-ca.ecogood.org.crt @@ -0,0 +1 @@ +../../../authorities/root/subject/cert.pem \ No newline at end of file diff --git a/secret/pki/lib/pki-authority b/secret/pki/lib/pki-authority new file mode 100755 index 0000000..76cbcd1 --- /dev/null +++ b/secret/pki/lib/pki-authority @@ -0,0 +1,1698 @@ +#!/usr/bin/env bash +# vim: foldmarker={{{,}}}:foldmethod=marker + +# pki-authority: CA-side PKI management +# Copyright (C) 2016 Maciej Delmanowski +# Copyright (C) 2016-2017 Robin Schneider +# Copyright (C) 2016-2020 DebOps +# SPDX-License-Identifier: GPL-3.0-only + +set -o nounset -o pipefail -o errexit + +umask 022 + +script="$(basename "${0}")" + +_openssl () { + # OpenSSL writes to stderr/stdout even when there are no errors. So just + # display the output if the exit code was != 0 to simplify debugging. + set +e + _openssl_out="$(openssl "${@}" 2>&1)" + local rc=$? + set -e + if [ ${rc} -ne 0 ]; then + echo "${script}: Error: failed to run $* (Exitcode: ${rc})" >&2 + echo >&2 + echo "Details:" >&2 + echo "${_openssl_out}" >&2 + exit ${rc} + fi + unset _openssl_out + return ${rc} +} + +array_exists () { + # Check if an element is in an array + local array="$1[@]" + local seeking=${2} + local in=1 + for element in "${!array}"; do + if [[ $element == "$seeking" ]]; then + in=0 + break + fi + done + return $in +} + +# Inlined in the following scripts: pki-authority, pki-realm {{{ +version () { + # Normalize version numbers for comparison. + echo "$@" | awk -F. '{ printf("%d%03d%03d%03d\n", $1,$2,$3,$4); }' +} + +key_exists () { + # Check if an associative array has a specified key present + # shellcheck disable=SC2086 + eval '[ ${'$1'[$2]+test_of_existence} ]' +} + +get_absolute_path () { + # Get an absolute path to a file + if type python3 > /dev/null ; then + python3 -c 'import sys, os.path; print(os.path.abspath(sys.argv[1]))' "${1}" + else + python -c 'import sys, os.path; print(os.path.abspath(sys.argv[1]))' "${1}" + fi +} + +get_relative_path () { + # Get a relative path to a file + if type python3 > /dev/null ; then + python3 -c 'import sys, os.path; print(os.path.relpath(sys.argv[1], sys.argv[2]))' "${1}" "${2:-$PWD}" + else + python -c 'import sys, os.path; print(os.path.relpath(sys.argv[1], sys.argv[2]))' "${1}" "${2:-$PWD}" + fi +} + +get_dnsdomainname () { + # Wrap dnsdomainname if it's not present (on MacOS X) + + if type dnsdomainname > /dev/null 2>&1 ; then + dnsdomainname + else + local fqdn + fqdn="$(get_fqdn)" + if [[ ${fqdn} == *.* ]] ; then + echo "${fqdn#*.}" + else + echo "" + fi + fi +} + +get_fqdn () { + shopt -s nocasematch + case $OSTYPE in + *bsd* | dragonfly* ) hostname;; + * ) hostname -f;; + esac +} + +chmod_idempotent () { + # chmod does a `fchmodat` (after a `stat`) even if it does not need to + # change anything as of 8.23-4. + # This behavior is not ideal for this script as it would update the ctime. + + local new_mode_in_octal="${1##0}" + local file_path="${2}" + + if [ "$(stat -c %a "${file_path}")" != "${new_mode_in_octal}" ] ; then + chmod "${new_mode_in_octal}" "${file_path}" + fi +} + +chgrp_idempotent () { + # chgrp does a `fchownat` (after a `newfstatat`) even if it does not need + # to change anything as of 8.23-4. + # This behavior is not ideal for this script as it would update the ctime. + + local new_group_name="${1}" + local file_path="${2}" + + if [ "$(stat -c %G "${file_path}")" != "${new_group_name}" ] ; then + chgrp "${new_group_name}" "${file_path}" + fi +} +# }}} + +get_openssl_ocsp_uri_directive () { + local ocsp_uri + case "${config['ocsp']}" in + true|True) + ocsp_uri="OCSP;URI.0 = \$ocsp_url" + ;; + false|False) + ocsp_uri="" + ;; + *) + ocsp_uri="OCSP;URI.0 = ${config['ocsp']}" + ;; + esac + echo "$ocsp_uri" +} + +get_openssl_name_constraints_directive () { + local config_domain="${1}" + local name_constraints + case "${config['name_constraints']}" in + true|True) + case "${config['name_constraints_critical']}" in + false|False) + name_constraints="nameConstraints = permitted;DNS:${config_domain},permitted;DNS:.${config_domain}" + ;; + *) + name_constraints="nameConstraints = critical, permitted;DNS:${config_domain},permitted;DNS:.${config_domain}" + ;; + esac + ;; + false|False) + name_constraints="" + ;; + *) + name_constraints="nameConstraints = ${config['name_constraints']}" + ;; + esac + + echo "$name_constraints" +} + +get_openssl_crl_distribution_points_directive () { + local crl_distribution_points='' + case "${config['crl']}" in + true|True) + crl_distribution_points="crlDistributionPoints = @crl_info" + ;; + false|False) + crl_distribution_points="" + ;; + *) + crl_distribution_points="crlDistributionPoints = ${config['crl']}" + ;; + esac + + echo "$crl_distribution_points" +} + +initialize_environment () { + + declare -gA config + + config["pki_root"]="${PKI_ROOT:-$(pwd)}" + config["pki_library"]="${PKI_LIBRARY:-openssl}" + config["pki_ca_certificates"]="${PKI_CA_CERTIFICATES:-${config['pki_root']}/ca-certificates/by-group/all}" + config["system_ca"]="true" + + config["pki_authorities"]="${config['pki_root']}/authorities" + config["pki_requests"]="${config['pki_root']}/requests" + + config["pki_default_fqdn"]="$(get_fqdn)" + config["pki_default_domain"]="$(get_dnsdomainname)" + config["pki_default_domain_dn"]=$(echo "${config['pki_default_domain']}" | cut -d. -f1 | sed 's/.*/\u&/') + + config["domain"]="" + config["ca_type"]="" + config["issuer_name"]="" + config["alt_authority"]="" + config["name_constraints"]="" + + config["pki_default_sign_base"]="365" + config["pki_default_root_sign_multiplier"]="12" + config["pki_default_ca_sign_multiplier"]="10" + config["pki_default_cert_sign_multiplier"]="3" + + config["root_sign_days"]="" + config["ca_sign_days"]="" + config["cert_sign_days"]="" + config["key_size"]="4096" + config["crl"]="true" + config["ocsp"]="true" + + config["public_dir_group"]="$(id -g)" + config["public_file_group"]="$(id -g)" + + config["private_dir_group"]="$(id -g)" + config["private_file_group"]="$(id -g)" + + config["public_dir_mode"]="755" + config["private_dir_mode"]="700" + + config["public_file_mode"]="644" + config["private_file_mode"]="600" + + # shellcheck disable=SC2174 + test -d ${config['pki_root']} || mkdir -p -m ${config['public_dir_mode']} ${config['pki_root']} +} + +enter_authority () { + + local authority="${1}" + local config_file="${2:-config/authority.conf}" + + mkdir -p "${config['pki_authorities']}/${authority}" + chmod_idempotent ${config['public_dir_mode']} "${config['pki_authorities']}/${authority}" + + cd "${config['pki_authorities']}/${authority}" + local rc=$? + + if [ -r "${config_file}" ] ; then + + # shellcheck source=/dev/null + . "${config_file}" + fi + + return ${rc} +} + +update_symlink () { + + local symlink_target="${1}" + + if [ -n "${symlink_target}" ] ; then + + shift 1 + + for target in "${@}" ; do + if [ -r "${target}" ] ; then + if [ -L "${symlink_target}" ] && [ "$(readlink "${symlink_target}")" == "${target}" ] ; then + break + else + ln -sf "${target}" "${symlink_target}" + fi + break + fi + done + + fi +} + +create_openssl_request_config () { + + local config_file="${1:-config/openssl-request.conf}" + local config_dn="${2}" + + if [ -n "${config_file}" ] && [ -n "${config_dn}" ] && [ ! -r "${config_file}" ] ; then + + cat << EOF > "${config_file}" +# Configuration file generated by pki-authority + +[ req ] +default_md = sha256 +default_bits = ${config['key_size']} +default_keyfile = private/key.pem +prompt = no +encrypt_key = no +distinguished_name = ca_dn +utf8 = yes +string_mask = utf8only + +[ ca_dn ] +EOF + echo "${config_dn}" | tr "/" "\\n" | sed \ + -e 's/^[Cc]=/countryName=/' \ + -e 's/^[Ss][Tt]=/stateOrProvinceName=/' \ + -e 's/^[Ll]=/localityName=/' \ + -e 's/^[Oo]=/organizationName=/' \ + -e 's/^[Oo][Uu]=/organizationalUnitName=/' \ + -e 's/^[Cc][Nn]=/commonName=/' >> "${config_file}" + + fi +} + +create_gnutls_request_config () { + + local config_file="${1:-config/gnutls-request.conf}" + local config_dn="${2}" + + if [ -n "${config_file}" ] && [ -n "${config_dn}" ] && [ ! -r "${config_file}" ] ; then + + cat << EOF > "${config_file}" +# Configuration file generated by pki-authority + +EOF + echo "${config_dn}" | tr "/" "\\n" | sed \ + -e 's/^[Cc]=/country = "/' \ + -e 's/^[Ss][Tt]=/state = "/' \ + -e 's/^[Ll]=/locality = "/' \ + -e 's/^[Oo]=/organization = "/' \ + -e 's/^[Oo][Uu]=/unit = "/' \ + -e 's/^[Cc][Nn]=/cn = "/' \ + -e 's/$/"/' >> "${config_file}" + + fi +} + +create_openssl_selfsign_config () { + + local config_file="${1:-config/openssl-selfsign.conf}" + local config_name="${2}" + local config_domain="${3}" + local config_ca_type="${4}" + + if [ -n "${config_file}" ] && [ ! -r "${config_file}" ] ; then + local ocsp_uri + ocsp_uri="$(get_openssl_ocsp_uri_directive)" + + cat << EOF > "${config_file}" +# Configuration file generated by pki-authority + +[ default ] +name = ${config_name} +domain_suffix = ${config_domain} +aia_url = http://\$name.\$domain_suffix/crt/ +crl_url = http://\$name.\$domain_suffix/crl/ +ocsp_url = http://\$name.\$domain_suffix/ocsp/ +default_ca = ca_default +name_opt = utf8,esc_ctrl,multiline,lname,align + +[ ca_default ] +home = . +database = \$home/database/index +serial = \$home/database/serial +crlnumber = \$home/database/crlnumber +certificate = \$home/subject/cert.pem +private_key = \$home/private/key.pem +RANDFILE = \$home/private/random +new_certs_dir = \$home/certs +unique_subject = no +copy_extensions = none +default_days = ${config['root_sign_days']:-$(( config['pki_default_sign_base'] * config['pki_default_root_sign_multiplier'] ))} +default_crl_days = 365 +default_md = sha256 +policy = policy_default +x509_extensions = extension_default + +[ crl_info ] +URI.0 = \$crl_url + +[ issuer_info ] +caIssuers;URI.0 = \$aia_url +${ocsp_uri} + +[ extension_ocsp ] +authorityKeyIdentifier = keyid:always +basicConstraints = critical, CA:false +extendedKeyUsage = OCSPSigning +keyUsage = critical, digitalSignature +subjectKeyIdentifier = hash + +[ policy_default ] +countryName = optional +stateOrProvinceName = optional +organizationName = optional +organizationalUnitName = optional +commonName = optional +emailAddress = optional + +[ extension_default ] +EOF + + local name_constraints='' + name_constraints="$(get_openssl_name_constraints_directive "$config_domain")" + local crl_distribution_points='' + crl_distribution_points="$(get_openssl_crl_distribution_points_directive)" + if [ -z "${config_ca_type}" ] || [ "${config_ca_type}" = "root" ] ; then + cat << EOF >> "${config_file}" +basicConstraints = critical, CA:TRUE +keyUsage = critical, keyCertSign, cRLSign +subjectKeyIdentifier = hash +${name_constraints} + +EOF + elif [ "${config_ca_type}" = "service" ] ; then + cat << EOF >> "${config_file}" +authorityInfoAccess = @issuer_info +basicConstraints = critical, CA:TRUE, pathlen:0 +${crl_distribution_points} +keyUsage = critical, keyCertSign, cRLSign +subjectKeyIdentifier = hash +${name_constraints} + +EOF + fi + + fi +} + +create_gnutls_selfsign_config () { + + local config_file="${1:-config/gnutls-selfsign.conf}" + local config_name="${2}" + local config_domain="${3}" + local config_ca_type="${4}" + + if [ -n "${config_file}" ] && [ ! -r "${config_file}" ] ; then + + cat << EOF > "${config_file}" +# Configuration file generated by pki-authority + +expiration_days = ${config['root_sign_days']:-$(( config['pki_default_sign_base'] * config['pki_default_root_sign_multiplier'] ))} + +EOF + + if [ -z "${config_ca_type}" ] || [ "${config_ca_type}" = "root" ] ; then + cat << EOF >> "${config_file}" +ca +cert_signing_key +crl_signing_key + +EOF + elif [ "${config_ca_type}" = "service" ] ; then + cat << EOF >> "${config_file}" +ca +cert_signing_key +crl_signing_key +path_len = 0 + +#ca_issuers_uri = "http://${config_name}.${config_domain}/crt/" +crl_dist_points = "http://${config_name}.${config_domain}/crl/" +#ocsp_uri = "http://${config_name}.${config_domain}/ocsp/" + +EOF + fi + + fi +} + +create_openssl_sign_config () { + + local config_file="${1:-config/openssl-sign.conf}" + local config_name="${2}" + local config_domain="${3}" + local config_ca_type="${4}" + local config_issuer="${5}" + + if [ -n "${config_file}" ] && [ ! -r "${config_file}" ] ; then + local ocsp_uri + ocsp_uri="$(get_openssl_ocsp_uri_directive)" + + cat << EOF > "${config_file}" +# Configuration file generated by pki-authority + +[ default ] +name = ${config_name} +domain_suffix = ${config_domain} +aia_url = http://\$name.\$domain_suffix/crt/ +crl_url = http://\$name.\$domain_suffix/crl/ +ocsp_url = http://\$name.\$domain_suffix/ocsp/ +default_ca = ca_default +name_opt = utf8,esc_ctrl,multiline,lname,align + +[ ca_default ] +home = . +database = \$home/database/index +serial = \$home/database/serial +crlnumber = \$home/database/crlnumber +certificate = \$home/subject/cert.pem +private_key = \$home/private/key.pem +RANDFILE = \$home/private/random +new_certs_dir = \$home/certs +unique_subject = no +policy = policy_default +x509_extensions = extension_default +EOF + + if [ -z "${config_issuer}" ] && [ -z "${config_ca_type}" ] || [ "${config_ca_type}" = "root" ] ; then + cat << EOF >> "${config_file}" +copy_extensions = none +default_days = ${config['ca_sign_days']:-$(( config['pki_default_sign_base'] * config['pki_default_ca_sign_multiplier'] ))} +default_crl_days = 365 +default_md = sha256 + +EOF + elif [ -z "${config_issuer}" ] && [ "${config_ca_type}" = "service" ] ; then + cat << EOF >> "${config_file}" +copy_extensions = copy +default_days = ${config['cert_sign_days']:-$(( config['pki_default_sign_base'] * config['pki_default_cert_sign_multiplier'] ))} +default_crl_days = 365 +default_md = sha256 + +EOF + elif [ -n "${config_issuer}" ] && [ -z "${config_ca_type}" ] || [ "${config_ca_type}" = "server" ] ; then + cat << EOF >> "${config_file}" +copy_extensions = copy +default_days = ${config['cert_sign_days']:-$(( config['pki_default_sign_base'] * config['pki_default_cert_sign_multiplier'] ))} +default_crl_days = 30 +default_md = sha256 + +EOF + fi + + cat << EOF >> "${config_file}" +[ crl_info ] +URI.0 = \$crl_url + +[ issuer_info ] +caIssuers;URI.0 = \$aia_url +${ocsp_uri} + +[ extension_ocsp ] +authorityKeyIdentifier = keyid:always +basicConstraints = critical, CA:false +extendedKeyUsage = OCSPSigning +keyUsage = critical, digitalSignature +subjectKeyIdentifier = hash + +EOF + + if [ -z "${config_issuer}" ] && [ -z "${config_ca_type}" ] || [ "${config_ca_type}" = "root" ] ; then + cat << EOF >> "${config_file}" +[ policy_default ] +countryName = optional +stateOrProvinceName = optional +organizationName = optional +organizationalUnitName = optional +commonName = optional +emailAddress = optional + +EOF + elif [ -z "${config_issuer}" ] && [ "${config_ca_type}" = "service" ] ; then + cat << EOF >> "${config_file}" +[ policy_default ] +countryName = optional +stateOrProvinceName = optional +organizationName = optional +organizationalUnitName = optional +commonName = optional +emailAddress = optional + +EOF + elif [ -n "${config_issuer}" ] && [ -z "${config_ca_type}" ] || [ "${config_ca_type}" = "server" ] ; then + cat << EOF >> "${config_file}" +[ policy_default ] +countryName = optional +stateOrProvinceName = optional +organizationName = optional +organizationalUnitName = optional +commonName = optional +emailAddress = optional + +EOF + fi + + local name_constraints='' + name_constraints="$(get_openssl_name_constraints_directive "$config_domain")" + local crl_distribution_points='' + crl_distribution_points="$(get_openssl_crl_distribution_points_directive)" + if [ -z "${config_issuer}" ] && [ -z "${config_ca_type}" ] || [ "${config_ca_type}" = "root" ] ; then + cat << EOF >> "${config_file}" +[ extension_default ] +authorityInfoAccess = @issuer_info +authorityKeyIdentifier = keyid:always +basicConstraints = critical, CA:TRUE, pathlen:0 +${crl_distribution_points} +keyUsage = critical, keyCertSign, cRLSign +subjectKeyIdentifier = hash +${name_constraints} + +EOF + elif [ -z "${config_issuer}" ] && [ "${config_ca_type}" = "service" ] ; then + cat << EOF >> "${config_file}" +[ extension_default ] +authorityInfoAccess = @issuer_info +authorityKeyIdentifier = keyid:always, issuer:always +basicConstraints = critical, CA:FALSE +${crl_distribution_points} +extendedKeyUsage = clientAuth, serverAuth +keyUsage = critical, digitalSignature, keyEncipherment +subjectKeyIdentifier = hash + +EOF + elif [ -n "${config_issuer}" ] && [ -z "${config_ca_type}" ] || [ "${config_ca_type}" = "server" ] ; then + cat << EOF >> "${config_file}" +[ extension_default ] +authorityInfoAccess = @issuer_info +authorityKeyIdentifier = keyid:always, issuer:always +basicConstraints = critical, CA:FALSE +${crl_distribution_points} +extendedKeyUsage = clientAuth, serverAuth +keyUsage = critical, digitalSignature, keyEncipherment +subjectKeyIdentifier = hash + +EOF + fi + + fi +} + +create_gnutls_sign_config () { + + local config_file="${1:-config/gnutls-sign.conf}" + local config_name="${2}" + local config_domain="${3}" + local config_ca_type="${4}" + local config_issuer="${5}" + + if [ -n "${config_file}" ] && [ ! -r "${config_file}" ] ; then + + cat << EOF > "${config_file}" +# Configuration file generated by pki-authority + +EOF + + if [ -z "${config_issuer}" ] && [ -z "${config_ca_type}" ] || [ "${config_ca_type}" = "root" ] ; then + cat << EOF >> "${config_file}" +expiration_days = ${config['ca_sign_days']:-$(( config['pki_default_sign_base'] * config['pki_default_ca_sign_multiplier'] ))} + +ca +cert_signing_key +crl_signing_key +path_len = 0 + +#ca_issuers_uri = "http://${config_name}.${config_domain}/crt/" +crl_dist_points = "http://${config_name}.${config_domain}/crl/" +#ocsp_uri = "http://${config_name}.${config_domain}/ocsp/" + +EOF + elif [ -z "${config_issuer}" ] && [ "${config_ca_type}" = "service" ] ; then + cat << EOF >> "${config_file}" +expiration_days = ${config['cert_sign_days']:-$(( config['pki_default_sign_base'] * config['pki_default_cert_sign_multiplier'] ))} +#copy_extensions = copy + +signing_key +encryption_key +tls_www_client +tls_www_server + +#ca_issuers_uri = "http://${config_name}.${config_domain}/crt/" +crl_dist_points = "http://${config_name}.${config_domain}/crl/" +#ocsp_uri = "http://${config_name}.${config_domain}/ocsp/" + +EOF + elif [ -n "${config_issuer}" ] && [ -z "${config_ca_type}" ] || [ "${config_ca_type}" = "server" ] ; then + cat << EOF >> "${config_file}" +expiration_days = ${config['cert_sign_days']:-$(( config['pki_default_sign_base'] * config['pki_default_cert_sign_multiplier'] ))} +#copy_extensions = copy + +signing_key +encryption_key +tls_www_client +tls_www_server + +#ca_issuers_uri = "http://${config_name}.${config_domain}/crt/" +crl_dist_points = "http://${config_name}.${config_domain}/crl/" +#ocsp_uri = "http://${config_name}.${config_domain}/ocsp/" + +EOF + fi + fi + +} + +save_authority_config () { + + local config_file="${1:-config/authority.conf}" + + # shellcheck disable=SC2034 + local ignored_config_vars=( pki_root pki_requests pki_authorities pki_ca_certificates public_file_group public_dir_group private_file_group private_dir_group ) + + if [ -r "${config_file}" ] ; then + if grep -q -E "^#\\s+Configuration\\s+file\\s+generated\\s+by\\s+pki-authority$" "${config_file}" ; then + rm -f "${config_file}" + fi + fi + + if [ ! -r "${config_file}" ] ; then + cat << EOF > "${config_file}" +# Configuration file generated by pki-authority + +EOF + for key in "${!config[@]}" ; do + if ! array_exists ignored_config_vars "${key}" ; then + echo "config['${key}']='${config[${key}]}'" >> "${config_file}" + fi + done + fi +} + +check_openssl_req_session_match () { + local check_req="${1}" + local check_session="${PKI_SESSION_TOKEN:-}" + + if [ -n "${check_req}" ] && [ -n "${check_session}" ] ; then + if [ -r "${check_req}" ] ; then + openssl asn1parse -in "${check_req}" | grep -q "${check_session}" + rc=$? + return ${rc} + fi + fi + return 1 +} + +check_gnutls_req_session_match () { + return "$(check_openssl_req_session_match "${@}")" +} + +check_openssl_crt_ca_match () { + local check_crt="${1}" + local check_ca="${2}" + local check_ca_issuer="${3:-}" + + if [ -n "${check_crt}" ] && [ -n "${check_ca}" ] ; then + if [ -r "${check_crt}" ] && [ -r "${check_ca}" ] ; then + if [ -n "${check_ca_issuer}" ] && [ -r "${check_ca_issuer}" ] ; then + _openssl verify -CAfile "${check_ca_issuer}" -untrusted "${check_ca}" "${check_crt}" + local rc=$? + else + _openssl verify -CAfile "${check_ca}" "${check_crt}" + local rc=$? + fi + return ${rc} + fi + fi + return 1 +} + +check_gnutls_crt_ca_match () { + return "$(check_openssl_crt_ca_match "${@}")" +} + +check_openssl_req_crt_match () { + local check_req="${1}" + local check_crt="${2}" + + local req_modulus + local crt_modulus + + req_modulus="$(openssl req -noout -modulus -in "${check_req}" | base64)" + crt_modulus="$(openssl x509 -noout -modulus -in "${check_crt}" | base64)" + + if [ "${req_modulus}" = "${crt_modulus}" ] ; then + return 0 + else + return 1 + fi +} + +check_gnutls_req_crt_match () { + return "$(check_openssl_req_crt_match "${@}")" +} + +sign_openssl_certificate () { + local sign_config="${1}" + local sign_request="${2}" + local sign_out="${3}" + local sign_sect="${4}" + local sign_ext="${5}" + + if [ -n "${sign_config}" ] && [ -n "${sign_request}" ] && [ -n "${sign_out}" ] ; then + + if [ -r "${sign_request}" ] && [ ! -r "${sign_out}" ] ; then + + _openssl ca -batch -notext \ + -in "${sign_request}" -out "${sign_out}.tmp" \ + -name "${sign_sect}" -extensions "${sign_ext}" \ + -config "${sign_config}" + + if [ -r "${sign_out}.tmp" ] && [ -s "${sign_out}.tmp" ] ; then + mv "${sign_out}.tmp" "${sign_out}" + fi + + if [ -d issuer ] ; then + if [ -r "$(dirname "${sign_out}")/intermediate.pem" ] ; then + if ! diff -q -N "$(get_relative_path "subject/cert.pem" "$(dirname "${sign_out}")")" "$(dirname "${sign_out}")/intermediate.pem" > /dev/null ; then + ln -sf "$(get_relative_path "subject/cert.pem" "$(dirname "${sign_out}")")" "$(dirname "${sign_out}")/intermediate.pem" + fi + else + ln -sf "$(get_relative_path "subject/cert.pem" "$(dirname "${sign_out}")")" "$(dirname "${sign_out}")/intermediate.pem" + fi + if [ -r "$(dirname "${sign_out}")/root.pem" ] ; then + if ! diff -q -N "$(get_relative_path "issuer/subject/cert.pem" "$(dirname "${sign_out}")")" "$(dirname "${sign_out}")/root.pem" > /dev/null ; then + ln -sf "$(get_relative_path "issuer/subject/cert.pem" "$(dirname "${sign_out}")")" "$(dirname "${sign_out}")/root.pem" + fi + else + ln -sf "$(get_relative_path "issuer/subject/cert.pem" "$(dirname "${sign_out}")")" "$(dirname "${sign_out}")/root.pem" + fi + else + if [ -r "$(dirname "${sign_out}")/root.pem" ] ; then + if ! diff -q -N "$(get_relative_path "subject/cert.pem" "$(dirname "${sign_out}")")" "$(dirname "${sign_out}")/root.pem" > /dev/null ; then + ln -sf "$(get_relative_path "subject/cert.pem" "$(dirname "${sign_out}")")" "$(dirname "${sign_out}")/root.pem" + fi + else + ln -sf "$(get_relative_path "subject/cert.pem" "$(dirname "${sign_out}")")" "$(dirname "${sign_out}")/root.pem" + fi + fi + fi + fi +} + +sign_openssl_host_certificate () { + local sign_config="${1}" + local sign_request="${2}" + local sign_out="${3}" + local sign_alt="${4:-}" + + if [ -n "${sign_config}" ] && [ -n "${sign_request}" ] && [ -n "${sign_out}" ] ; then + + if [ -r "${sign_request}" ] && [ ! -r "${sign_out}" ] ; then + + _openssl ca -batch -notext \ + -in "${sign_request}" -out "${sign_out}.tmp" \ + -config "${sign_config}" + + if [ -r "${sign_out}.tmp" ] && [ -s "${sign_out}.tmp" ] ; then + mv "${sign_out}.tmp" "${sign_out}" + fi + + if [ -d issuer ] ; then + if [ -r "$(dirname "${sign_out}")/intermediate.pem" ] ; then + if ! diff -q -N "$(get_relative_path "subject/cert.pem" "$(dirname "${sign_out}")")" "$(dirname "${sign_out}")/intermediate.pem" > /dev/null ; then + ln -sf "$(get_relative_path "subject/cert.pem" "$(dirname "${sign_out}")")" "$(dirname "${sign_out}")/intermediate.pem" + fi + else + ln -sf "$(get_relative_path "subject/cert.pem" "$(dirname "${sign_out}")")" "$(dirname "${sign_out}")/intermediate.pem" + fi + if [ -r "$(dirname "${sign_out}")/root.pem" ] ; then + if ! diff -q -N "$(get_relative_path "issuer/subject/cert.pem" "$(dirname "${sign_out}")")" "$(dirname "${sign_out}")/root.pem" > /dev/null ; then + ln -sf "$(get_relative_path "issuer/subject/cert.pem" "$(dirname "${sign_out}")")" "$(dirname "${sign_out}")/root.pem" + fi + else + ln -sf "$(get_relative_path "issuer/subject/cert.pem" "$(dirname "${sign_out}")")" "$(dirname "${sign_out}")/root.pem" + fi + else + if [ -r "$(dirname "${sign_out}")/root.pem" ] ; then + if ! diff -q -N "$(get_relative_path "subject/cert.pem" "$(dirname "${sign_out}")")" "$(dirname "${sign_out}")/root.pem" > /dev/null ; then + ln -sf "$(get_relative_path "subject/cert.pem" "$(dirname "${sign_out}")")" "$(dirname "${sign_out}")/root.pem" + fi + else + ln -sf "$(get_relative_path "subject/cert.pem" "$(dirname "${sign_out}")")" "$(dirname "${sign_out}")/root.pem" + fi + fi + + if [ -n "${sign_alt}" ] ; then + + if [ -d "${sign_alt}/issuer" ] ; then + if [ -r "$(dirname "${sign_out}")/alt_intermediate.pem" ] ; then + if ! diff -q -N "$(get_relative_path "${sign_alt}/subject/cert.pem" "$(dirname "${sign_out}")")" "$(dirname "${sign_out}")/alt_intermediate.pem" > /dev/null ; then + ln -sf "$(get_relative_path "${sign_alt}/subject/cert.pem" "$(dirname "${sign_out}")")" "$(dirname "${sign_out}")/alt_intermediate.pem" + fi + else + ln -sf "$(get_relative_path "${sign_alt}/subject/cert.pem" "$(dirname "${sign_out}")")" "$(dirname "${sign_out}")/alt_intermediate.pem" + fi + if [ -r "$(dirname "${sign_out}")/root.pem" ] ; then + if ! diff -q -N "$(get_relative_path "${sign_alt}/issuer/subject/cert.pem" "$(dirname "${sign_out}")")" "$(dirname "${sign_out}")/alt_root.pem" > /dev/null ; then + ln -sf "$(get_relative_path "${sign_alt}/issuer/subject/cert.pem" "$(dirname "${sign_out}")")" "$(dirname "${sign_out}")/alt_root.pem" + fi + else + ln -sf "$(get_relative_path "${sign_alt}/issuer/subject/cert.pem" "$(dirname "${sign_out}")")" "$(dirname "${sign_out}")/alt_root.pem" + fi + else + if [ -r "$(dirname "${sign_out}")/root.pem" ] ; then + if ! diff -q -N "$(get_relative_path "${sign_alt}/subject/cert.pem" "$(dirname "${sign_out}")")" "$(dirname "${sign_out}")/alt_root.pem" > /dev/null ; then + ln -sf "$(get_relative_path "${sign_alt}/subject/cert.pem" "$(dirname "${sign_out}")")" "$(dirname "${sign_out}")/alt_root.pem" + fi + else + ln -sf "$(get_relative_path "${sign_alt}/subject/cert.pem" "$(dirname "${sign_out}")")" "$(dirname "${sign_out}")/alt_root.pem" + fi + fi + + fi + fi + fi +} + +sign_gnutls_host_certificate () { + local sign_config="${1}" + local sign_request="${2}" + local sign_out="${3}" + local sign_alt="${4:-}" + + if [ -n "${sign_config}" ] && [ -n "${sign_request}" ] && [ -n "${sign_out}" ] ; then + + if [ -r "${sign_request}" ] && [ ! -r "${sign_out}" ] ; then + + certtool --generate-certificate --template "${sign_config}" \ + --load-request "${sign_request}" --load-ca-privkey private/key.pem \ + --load-ca-certificate subject/cert.pem --outfile "${sign_out}.tmp" + + if [ -r "${sign_out}.tmp" ] && [ -s "${sign_out}.tmp" ] ; then + mv "${sign_out}.tmp" "${sign_out}" + fi + + if [ -d issuer ] ; then + if [ -r "$(dirname "${sign_out}")/intermediate.pem" ] ; then + if ! diff -q -N "$(get_relative_path "subject/cert.pem" "$(dirname "${sign_out}")")" "$(dirname "${sign_out}")/intermediate.pem" > /dev/null ; then + ln -sf "$(get_relative_path "subject/cert.pem" "$(dirname "${sign_out}")")" "$(dirname "${sign_out}")/intermediate.pem" + fi + else + ln -sf "$(get_relative_path "subject/cert.pem" "$(dirname "${sign_out}")")" "$(dirname "${sign_out}")/intermediate.pem" + fi + if [ -r "$(dirname "${sign_out}")/root.pem" ] ; then + if ! diff -q -N "$(get_relative_path "issuer/subject/cert.pem" "$(dirname "${sign_out}")")" "$(dirname "${sign_out}")/root.pem" > /dev/null ; then + ln -sf "$(get_relative_path "issuer/subject/cert.pem" "$(dirname "${sign_out}")")" "$(dirname "${sign_out}")/root.pem" + fi + else + ln -sf "$(get_relative_path "issuer/subject/cert.pem" "$(dirname "${sign_out}")")" "$(dirname "${sign_out}")/root.pem" + fi + else + if [ -r "$(dirname "${sign_out}")/root.pem" ] ; then + if ! diff -q -N "$(get_relative_path "subject/cert.pem" "$(dirname "${sign_out}")")" "$(dirname "${sign_out}")/root.pem" > /dev/null ; then + ln -sf "$(get_relative_path "subject/cert.pem" "$(dirname "${sign_out}")")" "$(dirname "${sign_out}")/root.pem" + fi + else + ln -sf "$(get_relative_path "subject/cert.pem" "$(dirname "${sign_out}")")" "$(dirname "${sign_out}")/root.pem" + fi + fi + + if [ -n "${sign_alt}" ] ; then + + if [ -d "${sign_alt}/issuer" ] ; then + if [ -r "$(dirname "${sign_out}")/alt_intermediate.pem" ] ; then + if ! diff -q -N "$(get_relative_path "${sign_alt}/subject/cert.pem" "$(dirname "${sign_out}")")" "$(dirname "${sign_out}")/alt_intermediate.pem" > /dev/null ; then + ln -sf "$(get_relative_path "${sign_alt}/subject/cert.pem" "$(dirname "${sign_out}")")" "$(dirname "${sign_out}")/alt_intermediate.pem" + fi + else + ln -sf "$(get_relative_path "${sign_alt}/subject/cert.pem" "$(dirname "${sign_out}")")" "$(dirname "${sign_out}")/alt_intermediate.pem" + fi + if [ -r "$(dirname "${sign_out}")/root.pem" ] ; then + if ! diff -q -N "$(get_relative_path "${sign_alt}/issuer/subject/cert.pem" "$(dirname "${sign_out}")")" "$(dirname "${sign_out}")/alt_root.pem" > /dev/null ; then + ln -sf "$(get_relative_path "${sign_alt}/issuer/subject/cert.pem" "$(dirname "${sign_out}")")" "$(dirname "${sign_out}")/alt_root.pem" + fi + else + ln -sf "$(get_relative_path "${sign_alt}/issuer/subject/cert.pem" "$(dirname "${sign_out}")")" "$(dirname "${sign_out}")/alt_root.pem" + fi + else + if [ -r "$(dirname "${sign_out}")/root.pem" ] ; then + if ! diff -q -N "$(get_relative_path "${sign_alt}/subject/cert.pem" "$(dirname "${sign_out}")")" "$(dirname "${sign_out}")/alt_root.pem" > /dev/null ; then + ln -sf "$(get_relative_path "${sign_alt}/subject/cert.pem" "$(dirname "${sign_out}")")" "$(dirname "${sign_out}")/alt_root.pem" + fi + else + ln -sf "$(get_relative_path "${sign_alt}/subject/cert.pem" "$(dirname "${sign_out}")")" "$(dirname "${sign_out}")/alt_root.pem" + fi + fi + + fi + fi + fi +} + +sign_openssl_ca_certificate () { + local sign_config="${1}" + local sign_request="${2}" + local sign_out="${3}" + + if [ -n "${sign_config}" ] && [ -n "${sign_request}" ] && [ -n "${sign_out}" ] ; then + if [ -r "${sign_request}" ] && [ ! -r "${sign_out}" ] ; then + + _openssl ca -batch -notext \ + -in "${sign_request}" -out "${sign_out}.tmp" \ + -config "${sign_config}" + + if [ -r "${sign_out}.tmp" ] && [ -s "${sign_out}.tmp" ] ; then + mv "${sign_out}.tmp" "${sign_out}" + fi + + fi + fi + +} + +sign_gnutls_ca_certificate () { + local sign_config="${1}" + local sign_request="${2}" + local sign_out="${3}" + + if [ -n "${sign_config}" ] && [ -n "${sign_request}" ] && [ -n "${sign_out}" ] ; then + if [ -r "${sign_request}" ] && [ ! -r "${sign_out}" ] ; then + + certtool --generate-certificate --template "${sign_config}" \ + --load-request "${sign_request}" --load-ca-privkey private/key.pem \ + --load-ca-certificate subject/cert.pem --outfile "${sign_out}.tmp" + + if [ -r "${sign_out}.tmp" ] && [ -s "${sign_out}.tmp" ] ; then + mv "${sign_out}.tmp" "${sign_out}" + fi + + fi + fi + +} + +sign_openssl_root_certificate () { + local sign_config="${1}" + local sign_request="${2}" + local sign_out="${3}" + + if [ -n "${sign_config}" ] && [ -n "${sign_request}" ] && [ -n "${sign_out}" ] ; then + if [ -r "${sign_request}" ] && [ ! -r "${sign_out}" ] ; then + + _openssl ca -selfsign -batch -notext \ + -in "${sign_request}" -out "${sign_out}.tmp" \ + -config "${sign_config}" + + if [ -r "${sign_out}.tmp" ] && [ -s "${sign_out}.tmp" ] ; then + mv "${sign_out}.tmp" "${sign_out}" + fi + + fi + fi + +} + +sign_gnutls_root_certificate () { + local sign_config="${1}" + local sign_request="${2}" + local sign_out="${3}" + + if [ -n "${sign_config}" ] && [ -n "${sign_request}" ] && [ -n "${sign_out}" ] ; then + if [ -r "${sign_request}" ] && [ ! -r "${sign_out}" ] ; then + + certtool --generate-self-signed --template "${sign_config}" \ + --load-request "${sign_request}" --load-privkey private/key.pem \ + --outfile "${sign_out}.tmp" + + if [ -r "${sign_out}.tmp" ] && [ -s "${sign_out}.tmp" ] ; then + mv "${sign_out}.tmp" "${sign_out}" + fi + + fi + fi + +} + +generate_openssl_request () { + + local req_config="${1}" + local req_out="${2}" + + if [ -n "${req_config}" ] && [ -n "${req_out}" ] ; then + if [ -r "${req_config}" ] && [ ! -r "${req_out}" ] ; then + + local req_keyfile + req_keyfile=$(grep -E '^default_keyfile\s+=\s+' "${req_config}" | awk '{print $3}') + if [ -n "${req_keyfile}" ] ; then + openssl req -new -key "${req_keyfile}" -config "${req_config}" -out "${req_out}.tmp" + else + openssl req -new -config "${req_config}" -out "${req_out}.tmp" + fi + test -r "${req_out}.tmp" && mv "${req_out}.tmp" "${req_out}" + + fi + fi + +} + +generate_gnutls_request () { + + local req_config="${1}" + local req_out="${2}" + + if [ -n "${req_config}" ] && [ -n "${req_out}" ] ; then + if [ -r "${req_config}" ] && [ ! -r "${req_out}" ] ; then + + certtool --generate-request --template "${req_config}" \ + --load-privkey private/key.pem --outfile "${req_out}.tmp" + # Remove text output from the request + test -r "${req_out}.tmp" && sed -n -i '/-----BEGIN NEW CERTIFICATE REQUEST-----/,$ p' "${req_out}.tmp" + test -r "${req_out}.tmp" && mv "${req_out}.tmp" "${req_out}" + + fi + fi + +} + +generate_openssl_serial () { + local serial_file="${1}" + local serial_length="${2:-16}" + + if [ -n "${serial_file}" ] && [ ! -r "${serial_file}" ] ; then + openssl rand -hex "${serial_length}" > "${serial_file}" + fi +} + +generate_gnutls_serial () { + # GnuTLS doesn't use this, so do nothing + return 0 +} + +generate_openssl_rsa_private_key () { + + local key_file="${1:-private/key.pem}" + local key_size="${2:-${config['key_size']}}" + local key_group="${3:-${config['private_file_group']}}" + + test -r "${key_file}" || openssl genrsa -out "${key_file}.tmp" "${key_size}" + + if [ -r "${key_file}.tmp" ] ; then + chmod "${config['private_file_mode']}" "${key_file}.tmp" + chgrp "${key_group}" "${key_file}.tmp" + mv "${key_file}.tmp" "${key_file}" + fi + + chmod_idempotent ${config['private_file_mode']} "${key_file}" + chgrp_idempotent "${key_group}" "${key_file}" + +} + +generate_gnutls_rsa_private_key () { + + local key_file="${1:-private/key.pem}" + local key_size="${2:-${config['key_size']}}" + local key_group="${3:-${config['private_file_group']}}" + + if ! [ -r "${key_file}" ] ; then + if [ "$(version "$(certtool --version | head -n 1 | awk '{print $NF}')")" -lt "$(version 3.3.0)" ] ; then + certtool --generate-privkey --outfile "${key_file}.tmp" --bits "${key_size}" + else + certtool --generate-privkey --rsa --outfile "${key_file}.tmp" --bits "${key_size}" + fi + fi + + if [ -r "${key_file}.tmp" ] ; then + sed -n -i '/-----BEGIN RSA PRIVATE KEY-----/,$ p' "${key_file}.tmp" + chmod "${config['private_file_mode']}" "${key_file}.tmp" + chgrp "${key_group}" "${key_file}.tmp" + mv "${key_file}.tmp" "${key_file}" + fi + + chmod_idempotent "${config['private_file_mode']}" "${key_file}" + chgrp_idempotent "${key_group}" "${key_file}" + +} + +create_public_directories () { + + local dir_group="${1}" + if [ -n "${dir_group}" ] ; then + shift + else + return 1 + fi + + local directories + read -r -a directories <<< "${@}" + + for directory in "${directories[@]}" ; do + mkdir -p "${directory}" + chmod_idempotent "${config['public_dir_mode']}" "${directory}" + chgrp_idempotent "${dir_group}" "${directory}" + done + +} + +create_private_directories () { + + local dir_group="${1}" + if [ -n "${dir_group}" ] ; then + shift + else + return 1 + fi + + local directories + read -r -a directories <<< "${@}" + + for directory in "${directories[@]}" ; do + mkdir -p "${directory}" + chmod_idempotent "${config['private_dir_mode']}" "${directory}" + chgrp_idempotent "${dir_group}" "${directory}" + done + +} + +sub_sign () { + + local -A args + + local optspec=":hn-:" + while getopts "${optspec}" optchar; do + case "${optchar}" in + -) + case "${OPTARG}" in + name) + args["name"]="${!OPTIND}"; OPTIND=$(( OPTIND + 1 )) + ;; + name=*) + args["name"]=${OPTARG#*=} + ;; + req) + args["req"]="${!OPTIND}"; OPTIND=$(( OPTIND + 1 )) + ;; + req=*) + args["req"]=${OPTARG#*=} + ;; + out) + args["out"]="${!OPTIND}"; OPTIND=$(( OPTIND + 1 )) + ;; + out=*) + args["out"]=${OPTARG#*=} + ;; + *) + if [ "$OPTERR" = 1 ] && [ "${optspec:0:1}" != ":" ]; then + echo "Unknown option --${OPTARG}" >&2 + fi + ;; + esac + ;; + h) + echo "usage: ${script} init <-n|--name[=]authority>" >&2 + exit 2 + ;; + n) + args["name"]="${!OPTIND}"; OPTIND=$(( OPTIND + 1 )) + ;; + *) + if [ "$OPTERR" != 1 ] || [ "${optspec:0:1}" = ":" ]; then + echo "Non-option argument: '-${OPTARG}'" >&2 + fi + ;; + esac + done + + local name="" + local req="" + local out="" + + if key_exists args "name" ; then + + enter_authority "${args['name']}" + + local library="${config['pki_library']}" + local input + local output + input="$(get_absolute_path ${args['req']})" + output="$(get_absolute_path ${args['out']})" + + sign_${library}_certificate "config/${library}-sign.conf" "${input}" "${output}" + + fi +} + +sub_sign-by-host () { + + if [ $# -gt 0 ] ; then + if [ -d requests ] && [ -d realms ] ; then + for authority in requests/* ; do + if [ -r "authorities/$(basename "${authority}")/subject/cert.pem" ] ; then + for host in "${authority}"/* ; do + for play_host in "${@}" ; do + if [ "$(basename "${host}")" = "${play_host}" ] ; then + for realm in "${host}"/* ; do + if [ -r "${realm}/request.pem" ] ; then + + local input + local output + input="$(get_absolute_path "${realm}"/request.pem)" + output="$(get_absolute_path "realms/by-host/$(basename "${play_host}")/$(basename "${realm}")/internal/cert.pem")" + + enter_authority "$(basename "${authority}")" + + local alt_authority="" + + if [ -n "${config['alt_authority']}" ] && [ -d ../${config['alt_authority']} ] ; then + alt_authority="$(get_absolute_path ../${config['alt_authority']})" + fi + + if [ -r "${output}" ] && check_${config['pki_library']}_req_session_match "${input}" ; then + rm -f "${output}" + fi + + if [ -r "${output}" ] && ! check_${config['pki_library']}_req_crt_match "${input}" "${output}" ; then + rm -f "${output}" + if ! check_${config['pki_library']}_req_session_match "${input}" ; then + rm -f "${input}" + fi + fi + + if [ -r "${output}" ] && ! check_${config['pki_library']}_crt_ca_match "${output}" "subject/cert.pem" "issuer/subject/cert.pem" ; then + rm -f "${output}" + if ! check_${config['pki_library']}_req_session_match "${input}" ; then + rm -f "${input}" + fi + fi + + if [ ! -r "${output}" ] && ! check_${config['pki_library']}_req_session_match "${input}" ; then + rm -f "${input}" + fi + + if [ -r "${input}" ] ; then + sign_${config['pki_library']}_host_certificate "config/${config['pki_library']}-sign.conf" "${input}" "${output}" "${alt_authority}" + fi + + cd - > /dev/null + + fi + done + fi + done + done + fi + done + fi + else + cat << EOF >&2 +Usage: ${script} sign-by-host [host1 host2 ...] + +signs certificates for specified hosts and writes them to the secret/pki subdirectory +EOF + exit 1 + fi + +} + +sub_new-ca () { + + local -A args + + local optspec=":hn-:" + while getopts "${optspec}" optchar; do + case "${optchar}" in + -) + case "${OPTARG}" in + name) + args["name"]="${!OPTIND}"; OPTIND=$(( OPTIND + 1 )) + ;; + name=*) + args["name"]=${OPTARG#*=} + ;; + system-ca) + # shellcheck disable=SC2154 + args["system_ca"]="${!OPTIND}"; OPTIND=$(( OPTIND + 1 )) + ;; + system-ca=*) + args["system_ca"]=${OPTARG#*=} + ;; + alt-authority) + args["alt_authority"]="${!OPTIND}"; OPTIND=$(( OPTIND + 1 )) + ;; + alt-authority=*) + args["alt_authority"]=${OPTARG#*=} + ;; + library) + args["pki_library"]="${!OPTIND}"; OPTIND=$(( OPTIND + 1 )) + ;; + library=*) + args["pki_library"]=${OPTARG#*=} + ;; + subdomain) + # shellcheck disable=SC2154 + args["subdomain"]="${!OPTIND}"; OPTIND=$(( OPTIND + 1 )) + ;; + subdomain=*) + args["subdomain"]=${OPTARG#*=} + ;; + subject) + # shellcheck disable=SC2154 + args["subject"]="${!OPTIND}"; OPTIND=$(( OPTIND + 1 )) + ;; + subject=*) + args["subject"]=${OPTARG#*=} + ;; + type) + # shellcheck disable=SC2154 + args["ca_type"]="${!OPTIND}"; OPTIND=$(( OPTIND + 1 )) + ;; + type=*) + args["ca_type"]=${OPTARG#*=} + ;; + issuer-name) + # shellcheck disable=SC2154 + args["issuer_name"]="${!OPTIND}"; OPTIND=$(( OPTIND + 1 )) + ;; + issuer-name=*) + args["issuer_name"]=${OPTARG#*=} + ;; + domain) + # shellcheck disable=SC2154 + args["domain"]="${!OPTIND}"; OPTIND=$(( OPTIND + 1 )) + ;; + domain=*) + args["domain"]=${OPTARG#*=} + ;; + root-sign-days) + args["root_sign_days"]="${!OPTIND}"; OPTIND=$(( OPTIND + 1 )) + ;; + root-sign-days=*) + args["root_sign_days"]=${OPTARG#*=} + ;; + ca-sign-days) + args["ca_sign_days"]="${!OPTIND}"; OPTIND=$(( OPTIND + 1 )) + ;; + ca-sign-days=*) + args["ca_sign_days"]=${OPTARG#*=} + ;; + cert-sign-days) + args["cert_sign_days"]="${!OPTIND}"; OPTIND=$(( OPTIND + 1 )) + ;; + cert-sign-days=*) + args["cert_sign_days"]=${OPTARG#*=} + ;; + key-size) + args["key_size"]="${!OPTIND}"; OPTIND=$(( OPTIND + 1 )) + ;; + key-size=*) + args["key_size"]=${OPTARG#*=} + ;; + crl) + args["crl"]="${!OPTIND}"; OPTIND=$(( OPTIND + 1 )) + ;; + crl=*) + args["crl"]=${OPTARG#*=} + ;; + ocsp) + args["ocsp"]="${!OPTIND}"; OPTIND=$(( OPTIND + 1 )) + ;; + ocsp=*) + args["ocsp"]=${OPTARG#*=} + ;; + name-constraints) + args["name_constraints"]="${!OPTIND}"; OPTIND=$(( OPTIND + 1 )) + ;; + name-constraints=*) + args["name_constraints"]=${OPTARG#*=} + ;; + name-constraints-critical) + args["name_constraints_critical"]="${!OPTIND}"; OPTIND=$(( OPTIND + 1 )) + ;; + name-constraints-critical=*) + args["name_constraints_critical"]=${OPTARG#*=} + ;; + *) + if [ "$OPTERR" = 1 ] && [ "${optspec:0:1}" != ":" ]; then + echo "Unknown option --${OPTARG}" >&2 + fi + ;; + esac + ;; + h) + echo "usage: ${script} new-ca <-n|--name[=]authority>" >&2 + exit 2 + ;; + n) + args["name"]="${!OPTIND}"; OPTIND=$(( OPTIND + 1 )) + ;; + *) + if [ "$OPTERR" != 1 ] || [ "${optspec:0:1}" = ":" ]; then + echo "Non-option argument: '-${OPTARG}'" >&2 + fi + ;; + esac + done + + if key_exists args "name" ; then + + enter_authority "${args['name']}" + + local config_changed="false" + + for key in "${!args[@]}" ; do + if [ -n "${args[${key}]+x}" ] ; then + if key_exists config "${key}" ; then + if [ "${config[${key}]}" != "${args[${key}]}" ] ; then + local config_changed="true" + config["${key}"]="${args[${key}]}" + fi + else + local config_changed="true" + config["${key}"]="${args[${key}]}" + fi + fi + done + + create_public_directories ${config['public_dir_group']} config database subject certs requests signed + create_private_directories ${config['private_dir_group']} private + + if [ "${config_changed}" = "true" ] ; then + save_authority_config config/authority.conf + fi + + local name="${config['name']}" + local library="${config['pki_library']}" + + generate_${library}_rsa_private_key private/key.pem + + create_${library}_request_config config/${library}-request.conf "${config['subject']}" + if [ -z "${config['issuer_name']}" ] ; then + create_${library}_selfsign_config config/${library}-selfsign.conf "${config['subdomain']}" "${config['domain']}" "${config['ca_type']}" + fi + create_${library}_sign_config config/${library}-sign.conf "${config['subdomain']}" "${config['domain']}" "${config['ca_type']}" "${config['issuer_name']}" + if [ -n "${config['issuer_name']}" ] ; then + update_symlink issuer ../${config['issuer_name']} + fi + + if [ "${library}" = "openssl" ] ; then + generate_${library}_serial database/serial + test -r database/index || touch database/index + fi + + generate_${library}_request config/${library}-request.conf subject/request.pem + + if [ -z "${config['issuer_name']}" ] && [ ! -L issuer ] ; then + + sign_${library}_root_certificate config/${library}-selfsign.conf \ + subject/request.pem subject/cert.pem + + elif [ -n "${config['issuer_name']}" ] && [ -L issuer ] ; then + local subject_dir + subject_dir="$(pwd)" + cd issuer || exit 1 + sign_${library}_ca_certificate config/${library}-sign.conf \ + "${subject_dir}/subject/request.pem" "${subject_dir}/subject/cert.pem" + cd - > /dev/null + fi + + if [ "${config['system_ca']}" = "true" ] && [ -n "${config['pki_ca_certificates']}" ] && [ -n "${config['subdomain']}" ] && [ -z "${config['issuer_name']}" ] && [ ! -L issuer ] ; then + if [ -r "$(dirname "${config['pki_ca_certificates']}")/${config['subdomain']}.${config['domain']}.crt" ] ; then + if ! diff -q -N "$(get_relative_path "subject/cert.pem" "${config['pki_ca_certificates']}")" "${config['pki_ca_certificates']}/${config['subdomain']}.${config['domain']}.crt" > /dev/null ; then + ln -sf "$(get_relative_path "subject/cert.pem" "${config['pki_ca_certificates']}")" "${config['pki_ca_certificates']}/${config['subdomain']}.${config['domain']}.crt" + fi + else + ln -sf "$(get_relative_path "subject/cert.pem" "${config['pki_ca_certificates']}")" "${config['pki_ca_certificates']}/${config['subdomain']}.${config['domain']}.crt" + fi + fi + + fi +} + +sub_init () { + + local -A args + + local optspec=":hn-:" + while getopts "${optspec}" optchar; do + case "${optchar}" in + -) + case "${OPTARG}" in + name) + args["name"]="${!OPTIND}"; OPTIND=$(( OPTIND + 1 )) + ;; + name=*) + args["name"]=${OPTARG#*=} + ;; + library) + args["pki_library"]="${!OPTIND}"; OPTIND=$(( OPTIND + 1 )) + ;; + library=*) + args["pki_library"]=${OPTARG#*=} + ;; + default-sign-base) + args["pki_default_sign_base"]="${!OPTIND}"; OPTIND=$(( OPTIND + 1 )) + ;; + default-sign-base=*) + args["pki_default_sign_base"]=${OPTARG#*=} + ;; + root-sign-multiplier) + args["pki_default_root_sign_multiplier"]="${!OPTIND}"; OPTIND=$(( OPTIND + 1 )) + ;; + root-sign-multiplier=*) + args["pki_default_root_sign_multiplier"]=${OPTARG#*=} + ;; + ca-sign-multiplier) + args["pki_default_ca_sign_multiplier"]="${!OPTIND}"; OPTIND=$(( OPTIND + 1 )) + ;; + ca-sign-multiplier=*) + args["pki_default_ca_sign_multiplier"]=${OPTARG#*=} + ;; + cert-sign-multiplier) + args["pki_default_cert_sign_multiplier"]="${!OPTIND}"; OPTIND=$(( OPTIND + 1 )) + ;; + cert-sign-multiplier=*) + args["pki_default_cert_sign_multiplier"]=${OPTARG#*=} + ;; + *) + if [ "$OPTERR" = 1 ] && [ "${optspec:0:1}" != ":" ]; then + echo "Unknown option --${OPTARG}" >&2 + fi + ;; + esac + ;; + h) + echo "usage: ${script} init <-n|--name[=]authority>" >&2 + exit 2 + ;; + n) + args["name"]="${!OPTIND}"; OPTIND=$(( OPTIND + 1 )) + ;; + *) + if [ "$OPTERR" != 1 ] || [ "${optspec:0:1}" = ":" ]; then + echo "Non-option argument: '-${OPTARG}'" >&2 + fi + ;; + esac + done + + if key_exists args "name" ; then + + enter_authority ${args['name']} + + for key in "${!args[@]}" ; do + if [ -n "${args[${key}]+x}" ] ; then + if key_exists config "${key}" ; then + if [ "${config[${key}]}" != "${args[${key}]}" ] ; then + local config_changed="true" + config["${key}"]="${args[${key}]}" + fi + else + local config_changed="true" + config["${key}"]="${args[${key}]}" + fi + fi + done + + create_public_directories ${config['public_dir_group']} config database subject certs requests signed + create_private_directories ${config['private_dir_group']} private + + if [ "${config_changed}" = "true" ] ; then + save_authority_config config/authority.conf + fi + + fi +} + +print_usage () { + cat << EOF >&2 +Usage: ${script} [parameters] + +Available commands: + + init + usage: pki-authority init <-n|--name[=]authority> + + new-ca + usage: pki-authority new-ca <-n|--name[=]authority> + + sign + usage: pki-authority init <-n|--name[=]authority> + + sign-by-host + usage: ${script} sign-by-host [host1 host2 ...] + signs certificates for specified hosts and writes them to the secret/pki subdirectory +EOF + +} + +initialize_environment + +if [ $# -gt 0 ] ; then + + subcommand="${1}" + + if [ -n "${subcommand}" ] ; then + case "${subcommand}" in + init|new-ca|sign|sign-by-host) + shift + "sub_${subcommand}" "${@}" + ;; + + *) + echo "${script}: Error: unknown subcommand '${subcommand}'" >&2 + print_usage + exit 1 + ;; + esac + fi + +else + print_usage + exit 1 +fi diff --git a/secret/pki/realms/by-host/acacia/domain/internal/cert.pem b/secret/pki/realms/by-host/acacia/domain/internal/cert.pem new file mode 100644 index 0000000..8808732 --- /dev/null +++ b/secret/pki/realms/by-host/acacia/domain/internal/cert.pem @@ -0,0 +1,32 @@ +-----BEGIN CERTIFICATE----- +MIIFhTCCA22gAwIBAgIRAJ4RviwDRJDtJpwPrnKO2vEwDQYJKoZIhvcNAQELBQAw +JjEQMA4GA1UECgwHRWNvZ29vZDESMBAGA1UECwwJRG9tYWluIENBMB4XDTIyMDgw +MzAzMDkxNloXDTI1MDgwMjAzMDkxNlowHTEbMBkGA1UEAxMSYWNhY2lhLmVjb2dv +b2Qub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA17AI5NtAlFc5 +wY+NayYVDn68LNzgbYOZeTHzOxYoh7iIQxdcDMJWnGEVhQDpKy2ymZ6pAfbIO/Si +UfSR0qqN3vcE/3pPlff3mwshqT/PYXZfYME5YpwkgW3nWtIKSN2zGA3A/nKHFKFD +d6SWbweaUSGeynxhKBHssEVv62FxSoEQRgLjM9t2Vq2Q48Zyv5FNN9dzwKdUihpw +HkmAhyMn8dqycPfnuQ755v3kgMnsLwQ0GivBXw/BoGYx6Xc28e7mhyidjZQIuu2I ++TC3HKSZL9Cl2owwamqDFh19j8HnKwUo5PWrgLfVmZLorX/XuAqC998lznAjTokG +NcDqaqxktwIDAQABo4IBtTCCAbEwbQYIKwYBBQUHAQEEYTBfMC0GCCsGAQUFBzAC +hiFodHRwOi8vZG9tYWluLWNhLmVjb2dvb2Qub3JnL2NydC8wLgYIKwYBBQUHMAGG +Imh0dHA6Ly9kb21haW4tY2EuZWNvZ29vZC5vcmcvb2NzcC8wXwYDVR0jBFgwVoAU +NjKTdoP4roaBWMjJ8qs497PJ8NihLKQqMCgxJjAkBgNVBAoMHUVjb2dvb2QgQ2Vy +dGlmaWNhdGUgQXV0aG9yaXR5ghAc/alS+Prue8lEkmpvlO5zMAwGA1UdEwEB/wQC +MAAwMgYDVR0fBCswKTAnoCWgI4YhaHR0cDovL2RvbWFpbi1jYS5lY29nb29kLm9y +Zy9jcmwvMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcDATAOBgNVHQ8BAf8E +BAMCBaAwHQYDVR0OBBYEFHtIuZuwcsCWQyB/X3LejynZe3SgME8GA1UdEQRIMEaC +C2Vjb2dvb2Qub3JnghJhY2FjaWEuZWNvZ29vZC5vcmeCFCouYWNhY2lhLmVjb2dv +b2Qub3Jngg0qLmVjb2dvb2Qub3JnMA0GCSqGSIb3DQEBCwUAA4ICAQB2oKIVEYd2 +5b1t9qZSaJbZ28KZJFoHiJO/ZXHa9ejD+wnxV1ie0nzSV+GY5sEqwXPEOpTU0MSi +fgaEwR5J54FhD4iNOH3zM/22nbtVvkkDAZshH37VHLvDZ9u81gCVLLGtD+JV2u8F +Gr/xHPRS8H5QpLIeeLW4wXPGbS7Wrb8xttvzdL5yveF45gXAxgCr7ww4uexcMN0M +mR+EFcDICOnfcA0pUFFWDnGfEZef4/5s7Z/7CgIN/PhUGwPE9FsR6e4YqHFyzr19 +RJi+kvjMxT/8HL05WLoxAF8g/XGy6dxsUUjxQP06gAXkjmFBHv9RJZg958xqZtY2 +grYg+8ULLm5aSIxkgJJM8+D6nYa2Um6/vdPsQFGjhSN0KKvfDyWQKxmZezTEklq8 +gP1ZwbWlsoW/yg8FGaBOHUQpmGsYzlAs0fTETLuvNrthb7yOtp7h8DBG4DVGPZ6+ +rECdPlpNdOg/yT05Mq9qWIDsw7onTnm1lvMwYLstT4OSi7atAia6fi0b/VdFkiyk +fqsjqwvkmdR/albcQ2Lyh/kQ49KGGpZEiLxFjZImsN9+XA/ych4FpH6EuPrNxA2h +WLThz/XhpsqhFq1bejGVc4VgJ7uUy5OwlX9F6JvNohQTY00TAUy+qhFcroewNrCA +eziVOPxbRSp+ozGLwTcIjxTUmJErS2vOYw== +-----END CERTIFICATE----- diff --git a/secret/pki/realms/by-host/acacia/domain/internal/intermediate.pem b/secret/pki/realms/by-host/acacia/domain/internal/intermediate.pem new file mode 120000 index 0000000..99ea97d --- /dev/null +++ b/secret/pki/realms/by-host/acacia/domain/internal/intermediate.pem @@ -0,0 +1 @@ +../../../../../authorities/domain/subject/cert.pem \ No newline at end of file diff --git a/secret/pki/realms/by-host/acacia/domain/internal/root.pem b/secret/pki/realms/by-host/acacia/domain/internal/root.pem new file mode 120000 index 0000000..11ed675 --- /dev/null +++ b/secret/pki/realms/by-host/acacia/domain/internal/root.pem @@ -0,0 +1 @@ +../../../../../authorities/domain/issuer/subject/cert.pem \ No newline at end of file diff --git a/secret/pki/requests/domain/acacia/domain/request.pem b/secret/pki/requests/domain/acacia/domain/request.pem new file mode 100644 index 0000000..8d37bda --- /dev/null +++ b/secret/pki/requests/domain/acacia/domain/request.pem @@ -0,0 +1,20 @@ +-----BEGIN NEW CERTIFICATE REQUEST----- +MIIDWjCCAkICAQAwHTEbMBkGA1UEAxMSYWNhY2lhLmVjb2dvb2Qub3JnMIIBIjAN +BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA17AI5NtAlFc5wY+NayYVDn68LNzg +bYOZeTHzOxYoh7iIQxdcDMJWnGEVhQDpKy2ymZ6pAfbIO/SiUfSR0qqN3vcE/3pP +lff3mwshqT/PYXZfYME5YpwkgW3nWtIKSN2zGA3A/nKHFKFDd6SWbweaUSGeynxh +KBHssEVv62FxSoEQRgLjM9t2Vq2Q48Zyv5FNN9dzwKdUihpwHkmAhyMn8dqycPfn +uQ755v3kgMnsLwQ0GivBXw/BoGYx6Xc28e7mhyidjZQIuu2I+TC3HKSZL9Cl2oww +amqDFh19j8HnKwUo5PWrgLfVmZLorX/XuAqC998lznAjTokGNcDqaqxktwIDAQAB +oIH3ME8GCSqGSIb3DQEJBzFCE0BhY2IwMWE2MGI0ODZlYTNkM2ZlYzI1MzA2NjUz +ODhlODBhMDVlOTg3OWQzNDEyY2MwMGRmM2JmODYwZDQ2ZTRiMIGjBgkqhkiG9w0B +CQ4xgZUwgZIwTwYDVR0RBEgwRoILZWNvZ29vZC5vcmeCEmFjYWNpYS5lY29nb29k +Lm9yZ4IUKi5hY2FjaWEuZWNvZ29vZC5vcmeCDSouZWNvZ29vZC5vcmcwDAYDVR0T +AQH/BAIwADAPBgNVHQ8BAf8EBQMDB6AAMCAGA1UdJQEB/wQWMBQGCCsGAQUFBwMC +BggrBgEFBQcDATANBgkqhkiG9w0BAQsFAAOCAQEAJrnFEYdugCKqkYpu/g9cGKXT +tC0OYpl3fkqu8ll69699oWAhB36RVtt3u3tt91jMDkQM6ea2iPuuxVV4kxsXIdMv +dOlQx3NUCfad6lw4iDwFhJ+eo+HoZ7HPrmHfDbQv91ESwkdfUX7t4GU/nyISWd4q +EvPMNS1pq9fq2FlHng89cg3EnQlfNZ11vYn78d+CuFKsFxotO1R+v7iBAnBzVjr0 +3dYI5UwYjrERVI5updngpthtNnTyGcuT3aKbFkTcnRIt8xms+RNgww0rnNVPsJmb +ABwdiCMxF7jupjrHR9A4//BcM6l/4ox66is8yv+vfMf6GQ9WmSSz5TVk0ofIQQ== +-----END NEW CERTIFICATE REQUEST-----