ca: Add support for appending intermediates to issued TLS certs#2027
Conversation
| -----END EC PRIVATE KEY----- | ||
| `) | ||
|
|
||
| // ExpiredCert is an ECDSA certificate that expired in 2007 |
There was a problem hiding this comment.
The test in this PR no longer uses this particular cert, but while I was trying stuff I discovered that I had set the validity times wrong for this cert: it was previously valid from 1987-1977 (not a valid date range). So I regenerated this one.
e73a5df to
5b44ccc
Compare
Codecov Report
@@ Coverage Diff @@
## master #2027 +/- ##
==========================================
- Coverage 53.92% 53.85% -0.07%
==========================================
Files 109 109
Lines 19093 19100 +7
==========================================
- Hits 10296 10287 -9
- Misses 7553 7575 +22
+ Partials 1244 1238 -6Continue to review full report at Codecov.
|
31b30cf to
a78c89a
Compare
|
LGTM |
| // Calculate the digest for our Root CA bundle | ||
| digest := digest.FromBytes(certBytes) | ||
|
|
||
| // TODO(cyli): We currently do not yet support arbitrary chains of intermediates (e.g. the case of an offline root, with the CA signing with |
There was a problem hiding this comment.
@diogomonica @aaronlehmann I can probably also handle this case but it may be better to do that in another PR, because there could be a bunch of changes (to distinguishing the root certs the RootCA should trust, vs the signing cert).
diogomonica
left a comment
There was a problem hiding this comment.
Overall LGTM, but just to be clear: with this change we're enforcing that the intermediate always starts with a cross-signed version of the new root by the old root.
|
|
||
| // Intermediates contains a bundle of PEM encoded certificates to append to any issued TLS certificates. | ||
| // If more than one are provided, the first one must have the same public key and subject as the signing | ||
| // root certificate (or, if no key is provided, at least one of the root certificates), and the rest |
There was a problem hiding this comment.
we require the Intermediates to also include the root? Usually certificates don't include the full chain all the way up to the root.
There was a problem hiding this comment.
No sorry, my comment was not clear - just that a chain can be formed using the intermediates to one of the root certs in the pool (e.g. the intermediates doesn't have to have the root, but one of them should be signed by one of the roots)
There was a problem hiding this comment.
Maybe we add little ASCII Diagrams? We will sendup with a certificate that contains: [Leaf] | [Intermediate] and a root that contains [Root]. We guarantee that there is always a valid chain [Leaf] to [Root] using [Intermediate].
😄
| digest := digest.FromBytes(certBytes) | ||
|
|
||
| // TODO(cyli): We currently do not yet support arbitrary chains of intermediates (e.g. the case of an offline root, with the CA signing with | ||
| // an intermediate) - we currently only only intermediates for which the first intermediate is cross-signed version of the signing (first) root |
|
|
||
| // TODO(cyli): We currently do not yet support arbitrary chains of intermediates (e.g. the case of an offline root, with the CA signing with | ||
| // an intermediate) - we currently only only intermediates for which the first intermediate is cross-signed version of the signing (first) root | ||
| // for the purposes of root rotation. If we wanted to support offline roots, rather than require at the first intermediate is the cross-signed |
| // TODO(cyli): We currently do not yet support arbitrary chains of intermediates (e.g. the case of an offline root, with the CA signing with | ||
| // an intermediate) - we currently only only intermediates for which the first intermediate is cross-signed version of the signing (first) root | ||
| // for the purposes of root rotation. If we wanted to support offline roots, rather than require at the first intermediate is the cross-signed | ||
| // version of the signing CA, it should *either* be a cross-signed version of the signing CA or it should be the issuer of the signing CA. |
There was a problem hiding this comment.
There is a lot to unpack in this comment. Not sure I understand this last sentence.
There was a problem hiding this comment.
Oh I see what you mean. Ok, how I was interpreting this to work was:
Right now, we require that the first cert of the intermediate be a cross-signed root. But that shouldn't be a requirement if we support the offline root case. I originally thought for the offline root case, we'd append our intermediate signing CA, and then append these intermediates, which would chain up to the root.
But you're right that the intermediate signing CA can then just be included in the list of intermediates in which case it will still have the same public key and subject as the current signing CA, and that would make this logic simpler. I'll update.
| // Calculate the digest for our Root CA bundle | ||
| digest := digest.FromBytes(certBytes) | ||
|
|
||
| // TODO(cyli): We currently do not yet support arbitrary chains of intermediates (e.g. the case of an offline root, with the CA signing with |
7faa2df to
9f8d4f1
Compare
9f8d4f1 to
6bb9ab4
Compare
| // signing root certificate, and the rest must form a chain, each one certifying the one above it, | ||
| // as per RFC5246 section 7.4.2: | ||
| // | ||
| // RootCA.Cert: [ signing CA cert][CA cert][CA cert][CA cert] |
There was a problem hiding this comment.
@diogomonica Does this diagram make sense?
64c1b2c to
a0befd0
Compare
…sued by a RootCA object or by an external CA object. Signed-off-by: cyli <ying.li@docker.com>
a0befd0 to
bdc3703
Compare
Part of addressing intermediate support in #1990.