Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Based on https://pki-tutorial.readthedocs.io/en/latest/expert/index.html Changes: bits: 4096 - that's good for decades Default MD: sha512, even if sha256 is fine
- Loading branch information
Showing
7 changed files
with
612 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
#!/usr/bin/env python3 | ||
import os | ||
import shlex | ||
|
||
import subprocess | ||
|
||
import sys | ||
|
||
BASEDIR = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) | ||
os.chdir(BASEDIR) | ||
|
||
|
||
def create_file(path: str, content: str = ''): | ||
full_path = os.path.join(BASEDIR, path) | ||
|
||
if os.path.exists(full_path): | ||
return | ||
|
||
with open(full_path, 'w') as f: | ||
f.write(content) | ||
|
||
|
||
def split_and_run(command: str): | ||
if subprocess.call(shlex.split(command, posix=True)): | ||
sys.exit(1) | ||
|
||
|
||
def init_ca_files(ca_name: str): | ||
root_ca_dirs = [ | ||
'ca/{}/db'.format(ca_name), | ||
'crl', | ||
'certs', | ||
] | ||
|
||
for d in root_ca_dirs: | ||
os.makedirs(os.path.join(BASEDIR, d), 0o755, exist_ok=True) | ||
private_dir = os.path.join(BASEDIR, 'ca/{ca_name}/private'.format(ca_name=ca_name)) | ||
os.makedirs(private_dir, 0o700, exist_ok=True) | ||
|
||
os.chmod(private_dir, 0o700) | ||
|
||
create_file('ca/{ca_name}/db/{ca_name}.db'.format(ca_name=ca_name)) | ||
create_file('ca/{ca_name}/db/{ca_name}.db.attr'.format(ca_name=ca_name)) | ||
create_file('ca/{ca_name}/db/{ca_name}.crt.srl'.format(ca_name=ca_name), '01') | ||
create_file('ca/{ca_name}/db/{ca_name}.crl.srl'.format(ca_name=ca_name), '01') | ||
|
||
if not os.path.exists('{root}/ca/{ca_name}/private/{ca_name}.key'.format(root=BASEDIR, ca_name=ca_name)): | ||
split_and_run('''openssl req -new \ | ||
-config {root}/etc/{ca_name}.conf \ | ||
-out {root}/ca/{ca_name}.csr \ | ||
-keyout {root}/ca/{ca_name}/private/{ca_name}.key'''.format(root=BASEDIR, ca_name=ca_name)) | ||
|
||
|
||
def sign_and_create_crl(ca_name: str, parent_ca_name: str, extension_prefix: str, *, selfsign: bool = False): | ||
if not os.path.exists('{root}/ca/{ca_name}.crt'.format(root=BASEDIR, ca_name=ca_name)): | ||
selfsign_param = '-selfsign' if selfsign else '' | ||
split_and_run('''openssl ca {selfsign}\ | ||
-config {root}/etc/{parent_ca_name}.conf \ | ||
-in {root}/ca/{ca_name}.csr \ | ||
-out {root}/ca/{ca_name}.crt \ | ||
-extensions {extension}_ext \ | ||
-enddate 20361231235959Z'''.format(root=BASEDIR, ca_name=ca_name, parent_ca_name=parent_ca_name, | ||
extension=extension_prefix, selfsign=selfsign_param)) | ||
|
||
if not os.path.exists('{root}/crl/{ca_name}.crl'.format(root=BASEDIR, ca_name=ca_name)): | ||
split_and_run('''openssl ca -gencrl \ | ||
-config {root}/etc/{ca_name}.conf \ | ||
-out {root}/crl/{ca_name}.crl'''.format(root=BASEDIR, ca_name=ca_name)) | ||
|
||
|
||
init_ca_files('component-ca') | ||
sign_and_create_crl('component-ca', 'network-ca', 'signing_ca') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
#!/usr/bin/env python3 | ||
import os | ||
import shlex | ||
|
||
import subprocess | ||
|
||
import sys | ||
|
||
BASEDIR = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) | ||
os.chdir(BASEDIR) | ||
|
||
|
||
def create_file(path: str, content: str = ''): | ||
full_path = os.path.join(BASEDIR, path) | ||
|
||
if os.path.exists(full_path): | ||
return | ||
|
||
with open(full_path, 'w') as f: | ||
f.write(content) | ||
|
||
|
||
def split_and_run(command: str): | ||
if subprocess.call(shlex.split(command, posix=True)): | ||
sys.exit(1) | ||
|
||
|
||
def init_ca_files(ca_name: str): | ||
root_ca_dirs = [ | ||
'ca/{}/db'.format(ca_name), | ||
'crl', | ||
'certs', | ||
] | ||
|
||
for d in root_ca_dirs: | ||
os.makedirs(os.path.join(BASEDIR, d), 0o755, exist_ok=True) | ||
private_dir = os.path.join(BASEDIR, 'ca/{ca_name}/private'.format(ca_name=ca_name)) | ||
os.makedirs(private_dir, 0o700, exist_ok=True) | ||
|
||
os.chmod(private_dir, 0o700) | ||
|
||
create_file('ca/{ca_name}/db/{ca_name}.db'.format(ca_name=ca_name)) | ||
create_file('ca/{ca_name}/db/{ca_name}.db.attr'.format(ca_name=ca_name)) | ||
create_file('ca/{ca_name}/db/{ca_name}.crt.srl'.format(ca_name=ca_name), '01') | ||
create_file('ca/{ca_name}/db/{ca_name}.crl.srl'.format(ca_name=ca_name), '01') | ||
|
||
if not os.path.exists('{root}/ca/{ca_name}/private/{ca_name}.key'.format(root=BASEDIR, ca_name=ca_name)): | ||
split_and_run('''openssl req -new \ | ||
-config {root}/etc/{ca_name}.conf \ | ||
-out {root}/ca/{ca_name}.csr \ | ||
-keyout {root}/ca/{ca_name}/private/{ca_name}.key'''.format(root=BASEDIR, ca_name=ca_name)) | ||
|
||
|
||
def init_using_root_ca_config(ca_name: str, extension_prefix: str, *, selfsign: bool = False): | ||
if not os.path.exists('{root}/ca/{ca_name}.crt'.format(root=BASEDIR, ca_name=ca_name)): | ||
selfsign_param = '-selfsign' if selfsign else '' | ||
split_and_run('''openssl ca {selfsign}\ | ||
-config {root}/etc/root-ca.conf \ | ||
-in {root}/ca/{ca_name}.csr \ | ||
-out {root}/ca/{ca_name}.crt \ | ||
-extensions {extension}_ext \ | ||
-enddate 20361231235959Z'''.format(root=BASEDIR, ca_name=ca_name, | ||
extension=extension_prefix, selfsign=selfsign_param)) | ||
|
||
if not os.path.exists('{root}/crl/{ca_name}.crl'.format(root=BASEDIR, ca_name=ca_name)): | ||
split_and_run('''openssl ca -gencrl \ | ||
-config {root}/etc/{ca_name}.conf \ | ||
-out {root}/crl/{ca_name}.crl'''.format(root=BASEDIR, ca_name=ca_name)) | ||
|
||
|
||
init_ca_files('network-ca') | ||
init_using_root_ca_config('network-ca', 'intermediate_ca') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
#!/usr/bin/env python3 | ||
import os | ||
import shlex | ||
|
||
import subprocess | ||
|
||
import sys | ||
|
||
BASEDIR = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) | ||
os.chdir(BASEDIR) | ||
|
||
|
||
def create_file(path: str, content: str = ''): | ||
full_path = os.path.join(BASEDIR, path) | ||
|
||
if os.path.exists(full_path): | ||
return | ||
|
||
with open(full_path, 'w') as f: | ||
f.write(content) | ||
|
||
|
||
def split_and_run(command: str): | ||
if subprocess.call(shlex.split(command, posix=True)): | ||
sys.exit(1) | ||
|
||
|
||
def init_ca_files(ca_name: str): | ||
root_ca_dirs = [ | ||
'ca/{}/db'.format(ca_name), | ||
'crl', | ||
'certs', | ||
] | ||
|
||
for d in root_ca_dirs: | ||
os.makedirs(os.path.join(BASEDIR, d), 0o755, exist_ok=True) | ||
private_dir = os.path.join(BASEDIR, 'ca/{ca_name}/private'.format(ca_name=ca_name)) | ||
os.makedirs(private_dir, 0o700, exist_ok=True) | ||
|
||
os.chmod(private_dir, 0o700) | ||
|
||
create_file('ca/{ca_name}/db/{ca_name}.db'.format(ca_name=ca_name)) | ||
create_file('ca/{ca_name}/db/{ca_name}.db.attr'.format(ca_name=ca_name)) | ||
create_file('ca/{ca_name}/db/{ca_name}.crt.srl'.format(ca_name=ca_name), '01') | ||
create_file('ca/{ca_name}/db/{ca_name}.crl.srl'.format(ca_name=ca_name), '01') | ||
|
||
if not os.path.exists('{root}/ca/{ca_name}/private/{ca_name}.key'.format(root=BASEDIR, ca_name=ca_name)): | ||
split_and_run('''openssl req -new \ | ||
-config {root}/etc/{ca_name}.conf \ | ||
-out {root}/ca/{ca_name}.csr \ | ||
-keyout {root}/ca/{ca_name}/private/{ca_name}.key'''.format(root=BASEDIR, ca_name=ca_name)) | ||
|
||
|
||
def init_using_root_ca_config(ca_name: str, extension_prefix: str, *, selfsign: bool = False): | ||
if not os.path.exists('{root}/ca/{ca_name}.crt'.format(root=BASEDIR, ca_name=ca_name)): | ||
selfsign_param = '-selfsign' if selfsign else '' | ||
split_and_run('''openssl ca {selfsign}\ | ||
-config {root}/etc/root-ca.conf \ | ||
-in {root}/ca/{ca_name}.csr \ | ||
-out {root}/ca/{ca_name}.crt \ | ||
-extensions {extension}_ext \ | ||
-enddate 20361231235959Z'''.format(root=BASEDIR, ca_name=ca_name, | ||
extension=extension_prefix, selfsign=selfsign_param)) | ||
|
||
if not os.path.exists('{root}/crl/{ca_name}.crl'.format(root=BASEDIR, ca_name=ca_name)): | ||
split_and_run('''openssl ca -gencrl \ | ||
-config {root}/etc/{ca_name}.conf \ | ||
-out {root}/crl/{ca_name}.crl'''.format(root=BASEDIR, ca_name=ca_name)) | ||
|
||
|
||
init_ca_files('root-ca') | ||
init_using_root_ca_config('root-ca', 'root_ca', selfsign=True) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,141 @@ | ||
# Blue Component CA | ||
|
||
[ default ] | ||
ca = component-ca # CA name | ||
dir = . # Top dir | ||
base_url = http://pki.panthernet # CA base URL | ||
aia_url = $base_url/$ca.cer # CA certificate URL | ||
crl_url = $base_url/$ca.crl # CRL distribution point | ||
ocsp_url = http://ocsp.blue.se # OCSP responder URL | ||
name_opt = multiline,-esc_msb,utf8 # Display UTF-8 characters | ||
openssl_conf = openssl_init # Library config section | ||
|
||
# CA certificate request | ||
|
||
[ req ] | ||
default_bits = 4096 # RSA key size | ||
encrypt_key = yes # Protect private key | ||
default_md = sha1 # MD to use | ||
utf8 = yes # Input is UTF-8 | ||
string_mask = utf8only # Emit UTF-8 strings | ||
prompt = no # Don't prompt for DN | ||
distinguished_name = ca_dn # DN section | ||
req_extensions = ca_reqext # Desired extensions | ||
|
||
[ ca_dn ] | ||
countryName = "HU" | ||
organizationName = "Panther's Co." | ||
organizationalUnitName = "Panther's Component CA" | ||
commonName = "Panther's Component CA" | ||
|
||
[ ca_reqext ] | ||
keyUsage = critical,keyCertSign,cRLSign | ||
basicConstraints = critical,CA:true,pathlen:0 | ||
subjectKeyIdentifier = hash | ||
|
||
# CA operational settings | ||
|
||
[ ca ] | ||
default_ca = component_ca # The default CA section | ||
|
||
[ component_ca ] | ||
certificate = $dir/ca/$ca.crt # The CA cert | ||
private_key = $dir/ca/$ca/private/$ca.key # CA private key | ||
new_certs_dir = $dir/ca/$ca # Certificate archive | ||
serial = $dir/ca/$ca/db/$ca.crt.srl # Serial number file | ||
crlnumber = $dir/ca/$ca/db/$ca.crl.srl # CRL number file | ||
database = $dir/ca/$ca/db/$ca.db # Index file | ||
unique_subject = no # Require unique subject | ||
default_days = 730 # How long to certify for | ||
default_md = sha512 # MD to use | ||
policy = match_pol # Default naming policy | ||
email_in_dn = no # Add email to cert DN | ||
preserve = no # Keep passed DN ordering | ||
name_opt = $name_opt # Subject DN display options | ||
cert_opt = ca_default # Certificate display options | ||
copy_extensions = copy # Copy extensions from CSR | ||
x509_extensions = server_ext # Default cert extensions | ||
default_crl_days = 1 # How long before next CRL | ||
crl_extensions = crl_ext # CRL extensions | ||
|
||
[ match_pol ] | ||
countryName = match | ||
stateOrProvinceName = optional | ||
localityName = optional | ||
organizationName = match | ||
organizationalUnitName = optional | ||
commonName = supplied | ||
|
||
[ any_pol ] | ||
domainComponent = optional | ||
countryName = optional | ||
stateOrProvinceName = optional | ||
localityName = optional | ||
organizationName = optional | ||
organizationalUnitName = optional | ||
commonName = optional | ||
emailAddress = optional | ||
|
||
# Extensions | ||
|
||
[ server_ext ] | ||
keyUsage = critical,digitalSignature,keyEncipherment | ||
basicConstraints = CA:false | ||
extendedKeyUsage = serverAuth,clientAuth | ||
subjectKeyIdentifier = hash | ||
authorityKeyIdentifier = keyid:always | ||
authorityInfoAccess = @ocsp_info | ||
crlDistributionPoints = @crl_info | ||
certificatePolicies = blueMediumDevice | ||
|
||
[ client_ext ] | ||
keyUsage = critical,digitalSignature | ||
basicConstraints = CA:false | ||
extendedKeyUsage = clientAuth | ||
subjectKeyIdentifier = hash | ||
authorityKeyIdentifier = keyid:always | ||
authorityInfoAccess = @ocsp_info | ||
crlDistributionPoints = @crl_info | ||
certificatePolicies = blueMediumDevice | ||
|
||
[ timestamp_ext ] | ||
keyUsage = critical,digitalSignature | ||
basicConstraints = CA:false | ||
extendedKeyUsage = critical,timeStamping | ||
subjectKeyIdentifier = hash | ||
authorityKeyIdentifier = keyid:always | ||
authorityInfoAccess = @issuer_info | ||
crlDistributionPoints = @crl_info | ||
certificatePolicies = blueMediumDevice | ||
|
||
[ ocspsign_ext ] | ||
keyUsage = critical,digitalSignature | ||
basicConstraints = CA:false | ||
extendedKeyUsage = critical,OCSPSigning | ||
subjectKeyIdentifier = hash | ||
authorityKeyIdentifier = keyid:always | ||
authorityInfoAccess = @issuer_info | ||
noCheck = null | ||
certificatePolicies = blueMediumDevice | ||
|
||
[ crl_ext ] | ||
authorityKeyIdentifier = keyid:always | ||
authorityInfoAccess = @issuer_info | ||
|
||
[ ocsp_info ] | ||
caIssuers;URI.0 = $aia_url | ||
OCSP;URI.0 = $ocsp_url | ||
|
||
[ issuer_info ] | ||
caIssuers;URI.0 = $aia_url | ||
|
||
[ crl_info ] | ||
URI.0 = $crl_url | ||
|
||
# Policy OIDs | ||
|
||
[ openssl_init ] | ||
oid_section = additional_oids | ||
|
||
[ additional_oids ] | ||
MediumDevice = Medium Device Assurance, 1.3.6.1.4.1.0.1.7.9 |
Oops, something went wrong.