-
Notifications
You must be signed in to change notification settings - Fork 102
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add profile to use one intermediate CA
fixup .gitignore files update GHA python versions
- Loading branch information
1 parent
1f30af2
commit 3c524da
Showing
8 changed files
with
269 additions
and
8 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
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 @@ | ||
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 @@ | ||
include ../common.mk |
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,63 @@ | ||
# Chained (With One Intermediate) Certificates | ||
|
||
This tls-gen variation generates a root CA, one intermediary CA and two | ||
certificate/key pairs signed by the intermediate CA: | ||
|
||
* Chain 1: root CA => intermediate 1 => client certificate/key pair | ||
* Chain 2: root CA => intermediate 1 => server certificate/key pair | ||
|
||
## Generating | ||
|
||
``` shell | ||
# pass a password using the PASSWORD env variable | ||
make | ||
# results will be under the ./result directory | ||
ls -lha ./result | ||
``` | ||
|
||
Generated CA certificate as well as client and server certificate and private keys will be | ||
under the `result` directory. | ||
|
||
It possible to use [ECC][ecc-intro] for intermediate and leaf keys: | ||
|
||
``` | ||
# pass a private key password using the PASSWORD variable if needed | ||
make USE_ECC=true ECC_CURVE="prime256v1" | ||
# results will be under the ./result directory | ||
ls -lha ./result | ||
``` | ||
|
||
The list of available curves can be obtained with | ||
|
||
``` shell | ||
openssl ecparam -list_curves | ||
``` | ||
|
||
### Regeneration | ||
|
||
To regenerate, use | ||
|
||
``` shell | ||
# pass a private key password using the PASSWORD variable if needed | ||
make regen | ||
``` | ||
|
||
The `regen` target accepts the same variables as `gen` (default target) above. | ||
|
||
### Verification | ||
|
||
You can verify the generated client and server certificates against the generated CA one with | ||
|
||
``` shell | ||
make verify | ||
``` | ||
|
||
## Certificate Information | ||
|
||
To display client and server certificate information, use | ||
|
||
``` shell | ||
make info | ||
``` | ||
|
||
This assumes the certificates were previously generated. |
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,94 @@ | ||
# Copied over from the Basic profile | ||
# Note: LibreSSL 2.2.7 does not correctly support environment variables | ||
# here and that is the version that ships with OS X High Sierra. So, we | ||
# replace text using Python and generate a temporary cnf file | ||
|
||
common_name = @COMMON_NAME@ | ||
client_alt_name = @CLIENT_ALT_NAME@ | ||
server_alt_name = @SERVER_ALT_NAME@ | ||
|
||
[ ca ] | ||
default_ca = test_root_ca | ||
|
||
[ test_root_ca ] | ||
root_ca_dir = testca | ||
|
||
certificate = $root_ca_dir/cacert.pem | ||
database = $root_ca_dir/index.txt | ||
new_certs_dir = $root_ca_dir/certs | ||
private_key = $root_ca_dir/private/cakey.pem | ||
serial = $root_ca_dir/serial | ||
|
||
default_crl_days = 7 | ||
default_days = 1825 | ||
default_md = sha256 | ||
|
||
policy = test_root_ca_policy | ||
x509_extensions = certificate_extensions | ||
|
||
[ test_root_ca_policy ] | ||
commonName = supplied | ||
stateOrProvinceName = optional | ||
countryName = optional | ||
emailAddress = optional | ||
organizationName = optional | ||
organizationalUnitName = optional | ||
domainComponent = optional | ||
|
||
[ certificate_extensions ] | ||
basicConstraints = CA:false | ||
|
||
[ req ] | ||
default_bits = 4096 | ||
default_md = sha256 | ||
prompt = yes | ||
distinguished_name = root_ca_distinguished_name | ||
x509_extensions = root_ca_extensions | ||
|
||
[ root_ca_distinguished_name ] | ||
commonName = hostname | ||
|
||
[ root_ca_extensions ] | ||
basicConstraints = critical,CA:true | ||
keyUsage = keyCertSign, cRLSign | ||
subjectKeyIdentifier = hash | ||
authorityKeyIdentifier = keyid:always,issuer | ||
|
||
[ ca_extensions ] | ||
basicConstraints = critical,CA:true,pathlen:0 | ||
keyUsage = keyCertSign, cRLSign | ||
# nameConstraints = critical,@name_constraints | ||
|
||
[ client_extensions ] | ||
basicConstraints = CA:false | ||
keyUsage = digitalSignature,keyEncipherment | ||
extendedKeyUsage = clientAuth | ||
subjectAltName = @client_alt_names | ||
|
||
[ server_extensions ] | ||
basicConstraints = CA:false | ||
keyUsage = digitalSignature,keyEncipherment | ||
extendedKeyUsage = serverAuth | ||
subjectAltName = @server_alt_names | ||
subjectKeyIdentifier = hash | ||
authorityKeyIdentifier = keyid,issuer | ||
|
||
[ client_alt_names ] | ||
DNS.1 = $common_name | ||
DNS.2 = $client_alt_name | ||
DNS.3 = localhost | ||
# examples of more Subject Alternative Names | ||
# DNS.4 = guest | ||
# email = [email protected] | ||
# URI = amqps://123.client.warp10.local | ||
# otherName = 1.3.6.1.4.1.54392.5.436;FORMAT:UTF8,UTF8String:other-username | ||
|
||
[ server_alt_names ] | ||
DNS.1 = $common_name | ||
DNS.2 = $server_alt_name | ||
DNS.3 = localhost | ||
|
||
[ name_constraints ] | ||
permitted;DNS.1 = .your.domain.name | ||
permitted;DNS.2 = $server_alt_name | ||
permitted;DNS.3 = localhost |
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,105 @@ | ||
#!/usr/bin/env python3 | ||
# This Source Code Form is subject to the terms of the Mozilla Public | ||
# License, v. 2.0. If a copy of the MPL was not distributed with this | ||
# file, You can obtain one at https://mozilla.org/MPL/2.0/. | ||
# | ||
# Copyright (c) 2007-2014 VMware, Inc. or its affiliates. All rights reserved. | ||
# Copyright (c) 2014-2020 Michael Klishin and contributors. | ||
# Copyright (c) 2022 VMware, Inc. or its affiliates. All rights reserved. | ||
|
||
import sys | ||
import os | ||
import shutil | ||
from subprocess import call | ||
|
||
|
||
def _copy_artifacts_to_results(): | ||
os.makedirs(p.relative_path("result"), exist_ok=True) | ||
g.copy_root_ca_certificate_and_key_pair() | ||
g.copy_leaf_certificate_and_key_pair("server") | ||
g.copy_leaf_certificate_and_key_pair("client") | ||
|
||
|
||
def _concat_certificates(): | ||
# concat [intermediate CA 1] [root CA] > full_chain | ||
print("Will concatenate all CA certificates into {}".format(p.result_chained_certificate_path())) | ||
chain_file = open(p.result_chained_certificate_path(), "w") | ||
call(["cat", | ||
p.intermediate_ca_certificate_path("1"), | ||
p.root_ca_certificate_path()], | ||
stdout=chain_file) | ||
chain_file.close() | ||
|
||
|
||
def generate(opts): | ||
cli.validate_password_if_provided(opts) | ||
print("Will generate a root CA and two certificate/key pairs (server and client)") | ||
g.generate_root_ca(opts) | ||
print("Will generate intermediate CA signed by the root CA") | ||
g.generate_intermediate_ca(opts, | ||
parent_certificate_path=p.root_ca_certificate_path(), | ||
parent_key_path=p.root_ca_key_path(), | ||
suffix="1") | ||
print("Will generate server certificate/key pair signed by the intermediate CA") | ||
g.generate_server_certificate_and_key_pair(opts, | ||
parent_certificate_path=p.intermediate_ca_certificate_path("1"), | ||
parent_key_path=p.intermediate_ca_key_path("1")) | ||
print("Will generate client certificate/key pair signed by the intermediate CA") | ||
g.generate_client_certificate_and_key_pair(opts, | ||
parent_certificate_path=p.intermediate_ca_certificate_path("1"), | ||
parent_key_path=p.intermediate_ca_key_path("1")) | ||
_copy_artifacts_to_results() | ||
_concat_certificates() | ||
print("Done! Find generated certificates and private keys under ./result!") | ||
|
||
|
||
def clean(opts): | ||
for s in [p.root_ca_path(), | ||
p.intermediate_ca_path("1"), | ||
p.result_path(), | ||
p.leaf_pair_path("server"), | ||
p.leaf_pair_path("client")]: | ||
print("Removing {}".format(s)) | ||
try: | ||
shutil.rmtree(s) | ||
except FileNotFoundError: | ||
pass | ||
|
||
|
||
def regenerate(opts): | ||
clean(opts) | ||
generate(opts) | ||
|
||
|
||
def verify(opts): | ||
print("Will verify generated certificates against the CA certificate chain...") | ||
v.verify_leaf_certificate_against_ca_chain("client") | ||
v.verify_leaf_certificate_against_ca_chain("server") | ||
|
||
|
||
def info(opts): | ||
i.leaf_certificate_info("client") | ||
i.leaf_certificate_info("server") | ||
|
||
|
||
def alias_leaf_artifacts(opts): | ||
print("This command is not supported by this profile") | ||
|
||
|
||
commands = {"generate": generate, | ||
"gen": generate, | ||
"clean": clean, | ||
"regenerate": regenerate, | ||
"regen": regenerate, | ||
"verify": verify, | ||
"info": info, | ||
"alias-leaf-artifacts": alias_leaf_artifacts} | ||
|
||
if __name__ == "__main__": | ||
sys.path.append(os.path.realpath('..')) | ||
import tls_gen.cli as cli | ||
import tls_gen.gen as g | ||
import tls_gen.info as i | ||
import tls_gen.paths as p | ||
import tls_gen.verify as v | ||
cli.run(commands) |
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 |
---|---|---|
@@ -1,2 +1 @@ | ||
root_ca/openssl.cnf | ||
intermediate_*_ca | ||
intermediate_*/ |
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 |
---|---|---|
@@ -1,3 +1 @@ | ||
root_ca/openssl.cnf | ||
intermediate_ca1/openssl.cnf | ||
intermediate_ca2/openssl.cnf | ||
intermediate_ca*/ |