Skip to content

Commit 49d9253

Browse files
Merge pull request #65 from rabbitmq/lukebakken/generate-direct-certs-in-one-intermediate
Add "direct" certs to one_intermediate
2 parents efb3766 + fb48b52 commit 49d9253

3 files changed

Lines changed: 71 additions & 8 deletions

File tree

one_intermediate/README.md

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,29 @@
11
# Chained (With One Intermediate) Certificates
22

3-
This tls-gen variation generates a root CA, one intermediary CA and two
4-
certificate/key pairs signed by the intermediate CA:
3+
This tls-gen variation generates a root CA, one intermediary CA and four
4+
certificate/key pairs:
55

66
* Chain 1: root CA => intermediate 1 => client certificate/key pair
77
* Chain 2: root CA => intermediate 1 => server certificate/key pair
8+
* Chain 3: root CA => client_direct certificate/key pair (no intermediate)
9+
* Chain 4: root CA => server_direct certificate/key pair (no intermediate)
10+
11+
## Certificate Chain Structure
12+
13+
```
14+
Root CA
15+
16+
├─→ Intermediate CA
17+
│ │
18+
│ ├─→ server_certificate.pem
19+
│ └─→ client_certificate.pem
20+
21+
├─→ server_direct_certificate.pem
22+
└─→ client_direct_certificate.pem
23+
```
24+
25+
All certificates share the same root CA, allowing you to test both intermediate
26+
and direct certificate chains with a single trusted root.
827

928
## Generating
1029

@@ -15,10 +34,10 @@ make
1534
ls -lha ./result
1635
```
1736

18-
Generated CA certificate as well as client and server certificate and private keys will be
19-
under the `result` directory.
37+
Generated CA certificates as well as four certificate/key pairs (server, client,
38+
server_direct, and client_direct) will be under the `result` directory.
2039

21-
It possible to use [ECC][ecc-intro] for intermediate and leaf keys:
40+
It is possible to use [ECC][ecc-intro] for intermediate and leaf keys:
2241

2342
```
2443
# pass a private key password using the PASSWORD variable if needed
@@ -46,15 +65,19 @@ The `regen` target accepts the same variables as `gen` (default target) above.
4665

4766
### Verification
4867

49-
You can verify the generated client and server certificates against the generated CA one with
68+
You can verify the generated certificates against the CA chain with
5069

5170
``` shell
5271
make verify
5372
```
5473

74+
This verifies the intermediate-signed certificates (server and client) against
75+
the full CA chain. The direct certificates (server_direct and client_direct)
76+
can be verified directly against the root CA.
77+
5578
## Certificate Information
5679

57-
To display client and server certificate information, use
80+
To display certificate information for all generated certificates, use
5881

5982
``` shell
6083
make info

one_intermediate/openssl.cnf

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,25 @@ subjectAltName = @server_alt_names
7373
subjectKeyIdentifier = hash
7474
authorityKeyIdentifier = keyid,issuer
7575

76+
# The following sections are duplicates of the above, required because
77+
# OpenSSL's ca command looks for extensions named {peer}_extensions.
78+
# When generating certificates with peer names 'server_direct' and 'client_direct',
79+
# OpenSSL expects to find 'server_direct_extensions' and 'client_direct_extensions'.
80+
81+
[ server_direct_extensions ]
82+
basicConstraints = CA:false
83+
keyUsage = digitalSignature,keyEncipherment
84+
extendedKeyUsage = serverAuth
85+
subjectAltName = @server_alt_names
86+
subjectKeyIdentifier = hash
87+
authorityKeyIdentifier = keyid,issuer
88+
89+
[ client_direct_extensions ]
90+
basicConstraints = CA:false
91+
keyUsage = digitalSignature,keyEncipherment
92+
extendedKeyUsage = clientAuth
93+
subjectAltName = @client_alt_names
94+
7695
[ client_alt_names ]
7796
DNS.1 = $common_name
7897
DNS.2 = $client_alt_name

one_intermediate/profile.py

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ def _copy_artifacts_to_results():
1818
g.copy_root_ca_certificate_and_key_pair()
1919
g.copy_leaf_certificate_and_key_pair("server")
2020
g.copy_leaf_certificate_and_key_pair("client")
21+
g.copy_leaf_certificate_and_key_pair("server_direct")
22+
g.copy_leaf_certificate_and_key_pair("client_direct")
2123

2224

2325
def _concat_certificates():
@@ -48,6 +50,18 @@ def generate(opts):
4850
g.generate_client_certificate_and_key_pair(opts,
4951
parent_certificate_path=p.intermediate_ca_certificate_path("1"),
5052
parent_key_path=p.intermediate_ca_key_path("1"))
53+
print("Will generate server certificate/key pair signed directly by the root CA")
54+
g.generate_leaf_certificate_and_key_pair('server_direct', opts,
55+
peer_path='server_direct',
56+
parent_certificate_path=p.root_ca_certificate_path(),
57+
parent_key_path=p.root_ca_key_path(),
58+
parent_certs_path=p.root_ca_certs_path())
59+
print("Will generate client certificate/key pair signed directly by the root CA")
60+
g.generate_leaf_certificate_and_key_pair('client_direct', opts,
61+
peer_path='client_direct',
62+
parent_certificate_path=p.root_ca_certificate_path(),
63+
parent_key_path=p.root_ca_key_path(),
64+
parent_certs_path=p.root_ca_certs_path())
5165
_copy_artifacts_to_results()
5266
_concat_certificates()
5367
print("Done! Find generated certificates and private keys under ./result!")
@@ -58,7 +72,9 @@ def clean(opts):
5872
p.intermediate_ca_path("1"),
5973
p.result_path(),
6074
p.leaf_pair_path("server"),
61-
p.leaf_pair_path("client")]:
75+
p.leaf_pair_path("client"),
76+
p.leaf_pair_path("server_direct"),
77+
p.leaf_pair_path("client_direct")]:
6278
print("Removing {}".format(s))
6379
try:
6480
shutil.rmtree(s)
@@ -75,11 +91,16 @@ def verify(opts):
7591
print("Will verify generated certificates against the CA certificate chain...")
7692
v.verify_leaf_certificate_against_ca_chain("client")
7793
v.verify_leaf_certificate_against_ca_chain("server")
94+
print("Will verify direct certificates against the root CA...")
95+
v.verify_leaf_certificate_against_root_ca("client_direct")
96+
v.verify_leaf_certificate_against_root_ca("server_direct")
7897

7998

8099
def info(opts):
81100
i.leaf_certificate_info("client")
82101
i.leaf_certificate_info("server")
102+
i.leaf_certificate_info("client_direct")
103+
i.leaf_certificate_info("server_direct")
83104

84105

85106
def alias_leaf_artifacts(opts):

0 commit comments

Comments
 (0)