Re: Verification of a certificate chain

> Hi,
>
> I'm having a comprehension question on certificate verification.
>
> Having a trustchain like this:
>
> rootCA -> subCA -> subCA2
>
> I can verify the subCA2 certificate using the command:
>
> openssl verify -CAfile rootCA.pem -untrusted subCA.pem subCA2.pem
>
> But, should't it also be possible to only verify the trust chain up to
> the subCA (i.e., if I fully trust this CA)?

yes, then the rootCA is in your cert store, and OpenSSL must have access
to this, implied by settings in openssl.cnf
> I would have expected that
> this will verify sucessfully:
>
> openssl verify -CAfile subCA.pem subCA2.pem

Re: Verification of a certificate chain

> But, should't it also be possible to only verify the trust chain up to
> the subCA (i.e., if I fully trust this CA)? I would have expected that
> this will verify sucessfully:

OpenSSL versions prior to 1.0.2 require that all trusted certificates
be self-signed. In 1.0.2 it is possible to use X509_verify_cert()
with a trust anchor that is not self-signed, but I don't recall
whether this is possible through the CLI.

Re: Verification of a certificate chain

On Tue, May 27, 2014, Viktor Dukhovni wrote:

> On Tue, May 27, 2014 at 03:44:46PM +0200, Sven Reissmann wrote:
>
> > But, should't it also be possible to only verify the trust chain up to
> > the subCA (i.e., if I fully trust this CA)? I would have expected that
> > this will verify sucessfully:
>
> OpenSSL versions prior to 1.0.2 require that all trusted certificates
> be self-signed. In 1.0.2 it is possible to use X509_verify_cert()
> with a trust anchor that is not self-signed, but I don't recall
> whether this is possible through the CLI.
>

> On Tue, May 27, 2014, Viktor Dukhovni wrote:
>
>> On Tue, May 27, 2014 at 03:44:46PM +0200, Sven Reissmann wrote:
>>
>>> But, should't it also be possible to only verify the trust chain up to
>>> the subCA (i.e., if I fully trust this CA)? I would have expected that
>>> this will verify sucessfully:
>>
>> OpenSSL versions prior to 1.0.2 require that all trusted certificates
>> be self-signed. In 1.0.2 it is possible to use X509_verify_cert()
>> with a trust anchor that is not self-signed, but I don't recall
>> whether this is possible through the CLI.
>>
>
> It is with the -parial_chain option.
>
> Steve.
> --
> Dr Stephen N. Henson. OpenSSL project core developer.
> Commercial tech support now available see: http://www.openssl.org> ______________________________________________________________________
> OpenSSL Project http://www.openssl.org> User Support Mailing List [hidden email]> Automated List Manager [hidden email]>

RE: Verification of a certificate chain

Hi Sven,

> -----Original Message-----
> From: Sven Reissmann
>
> What I want to achieve is having a new rootCA, which replaces an
> oldRootCA, which I am using until now.
>
> So far the trust chain is: oldRoot -> oldServerCert.
>
> What I thought should be possible is building this trust chain:
> oldRoot -> newRoot -> newSubCA -> newServerCert
>
> As Users are trusting oldRoot, changing the oldServerCert to
> newServerCert is no problem. After some time, users would move trust to
> newRoot and I can "disable" oldRoot.
>
> This doesn't seem possible, if I understand your answers correct.
>
> Is there another/better/default way of smoothly changing a trust anchor?
> I.e. by cross-signing the newRoot by itself and the oldRoot?

Just add the new root-CA certificate to all relevant truststores. Afterwards you can start issueing certificates that are trusted by all parties with updated truststores.

Re: Verification of a certificate chain

The X.509-canonical way to do this is to have the old trust anchor sign a new certificate containing the new public key, using the same Issuer name and a different AuthorityKeyIdentifier. This is called "key rollover", but it retains the security level of the old key (meaning, if the original trust anchor is a 1024-bit key, then when the original key is brute-forced it could sign an alternative rollover certificate).

On 05/27/2014 05:16 PM, Dr. Stephen Henson wrote:
> On Tue, May 27, 2014, Viktor Dukhovni wrote:
>
>> On Tue, May 27, 2014 at 03:44:46PM +0200, Sven Reissmann wrote:
>>
>>> But, should't it also be possible to only verify the trust chain up to
>>> the subCA (i.e., if I fully trust this CA)? I would have expected that
>>> this will verify sucessfully:
>>
>> OpenSSL versions prior to 1.0.2 require that all trusted certificates
>> be self-signed. In 1.0.2 it is possible to use X509_verify_cert()
>> with a trust anchor that is not self-signed, but I don't recall
>> whether this is possible through the CLI.
>>
>
> It is with the -parial_chain option.
>
> Steve.
> --
> Dr Stephen N. Henson. OpenSSL project core developer.
> Commercial tech support now available see: http://www.openssl.org
> ______________________________________________________________________
> OpenSSL Project http://www.openssl.org
> User Support Mailing List [hidden email]
> Automated List Manager [hidden email]
>

RE: Verification of a certificate chain

> > From: Sven Reissmann
> >
> > What I want to achieve is having a new rootCA, which replaces an
> > oldRootCA, which I am using until now.
> >
> > So far the trust chain is: oldRoot -> oldServerCert.
> >
> > What I thought should be possible is building this trust chain:
> > oldRoot -> newRoot -> newSubCA -> newServerCert
> >
> > As Users are trusting oldRoot, changing the oldServerCert to
> > newServerCert is no problem. After some time, users would move trust to
> > newRoot and I can "disable" oldRoot.
> >
> > This doesn't seem possible, if I understand your answers correct.
> >
> > Is there another/better/default way of smoothly changing a trust anchor?
> > I.e. by cross-signing the newRoot by itself and the oldRoot?
>
> Just add the new root-CA certificate to all relevant truststores. Afterwards you
> can start issueing certificates that are trusted by all parties with updated
> truststores.
>

If you can get (all) the clients to update, yes. Sometimes that's hard.
Sometimes it's hard even *locating* the clients, especially programs.

You shouldn't cross-sign the new root itself, then it isn't a true root
and (more importantly) won't consistently be accepted as an anchor.

What you can do, and in my experience real public CAs actually do, is:

- create new root key, and new (selfsigned) root cert for it.

- also create a 'bridge' cert for the new root key, and the new root DN if
different (which it usually is, e.g. Joe's Clam, Oyster and Cert Emporium Gen3
supercedes Joe's Clam and Cert Shack Gen2), (cross)signed by the old root
(thus with issuer and AKI if present identifying oldroot, but SKI same as newroot).

- issue the subCA cert(s) with AKI keyid for the new root key or omitted, and
issuer matching both newroot and bridge, but NOT using AKI issuer&serial

- have server(s) handshake send subCA and bridge certs, at least for a period of time.
A stale client has only oldroot will chain bridge to oldroot and succeed as long as
oldroot doesn't expire. A clever fresh client has newroot abd will chain subCA to
newroot, ignoring bridge -- while a dumb client will ignore available newroot and
insist on chaining bridge to oldroot. Every time I've looked (not systematically)
major browsers and Java are clever, but OpenSSL (client/relier) through 1.0.1 is not.
I know 1.0.2 will change verification but don't know about this particular point.

RE: Verification of a certificate chain

Dave, thank you very much for your suggestions. This sounds like the
solution I'm looking for. I've set up a completely new PKI to test this,
but I'm still having one problem.

What I did was:

- I generated a newRootCA (new keypair, selfsigned certificate).

- I generated another selfsigned certificate (bridgeCert) from the
newRootCA's private key. From this cert, I used the -x509toreq
option to generate a csr (bridgeCSR).

- I took the bridgeCSR and issued a certificate using the oldRootCA.
The certificate issued has AKI = oldRootCA and SKI = newRootCA

- I generated a CSR for a new subCA and issued a certificate using
newRootCA. The AKI of the subCA cert is the same as the SKI of
newRootCA and bridgeCert. The AKI does not include any issuer or
serial information

What I am able to do now is:

- As long as I trust oldRoot and my server handshake send subCA and
bridge, the trustchain verifies: "Verify return code: 0 (ok)"

- As long as I trust newRoot any my server handshake send subCA but NOT
bridge, the trustchain verifies: "Verify return code: 0 (ok)"

- If I only trust newRoot but send the bridgeCert, I get an error. Also,
if I only trust oldRoot and do not send bridge, I get an error.

Am I still missing something?

Regards, Sven.

> If you can get (all) the clients to update, yes. Sometimes that's hard.
> Sometimes it's hard even *locating* the clients, especially programs.
>
> You shouldn't cross-sign the new root itself, then it isn't a true root
> and (more importantly) won't consistently be accepted as an anchor.
>
> What you can do, and in my experience real public CAs actually do, is:
>
> - create new root key, and new (selfsigned) root cert for it.
>
> - also create a 'bridge' cert for the new root key, and the new root DN if
> different (which it usually is, e.g. Joe's Clam, Oyster and Cert Emporium Gen3
> supercedes Joe's Clam and Cert Shack Gen2), (cross)signed by the old root
> (thus with issuer and AKI if present identifying oldroot, but SKI same as newroot).
>
> - issue the subCA cert(s) with AKI keyid for the new root key or omitted, and
> issuer matching both newroot and bridge, but NOT using AKI issuer&serial
>
> - have server(s) handshake send subCA and bridge certs, at least for a period of time.
> A stale client has only oldroot will chain bridge to oldroot and succeed as long as
> oldroot doesn't expire. A clever fresh client has newroot abd will chain subCA to
> newroot, ignoring bridge -- while a dumb client will ignore available newroot and
> insist on chaining bridge to oldroot. Every time I've looked (not systematically)
> major browsers and Java are clever, but OpenSSL (client/relier) through 1.0.1 is not.
> I know 1.0.2 will change verification but don't know about this particular point.

RE: Verification of a certificate chain

> From: [hidden email] On Behalf Of Sven Reissmann
> Sent: Thursday, May 29, 2014 12:24
<snip>
> What I did was:
>
> - I generated a newRootCA (new keypair, selfsigned certificate).
>
> - I generated another selfsigned certificate (bridgeCert) from the
> newRootCA's private key. From this cert, I used the -x509toreq
> option to generate a csr (bridgeCSR).
>
(You didn't really need that, you could just -x509toreq from newroot,
but no harm done as long as the DN is the same and per below it is.
Or you can req -new directly from the key, but that's less convenient.)

> - I took the bridgeCSR and issued a certificate using the oldRootCA.
> The certificate issued has AKI = oldRootCA and SKI = newRootCA
>
> - I generated a CSR for a new subCA and issued a certificate using
> newRootCA. The AKI of the subCA cert is the same as the SKI of
> newRootCA and bridgeCert. The AKI does not include any issuer or
> serial information
>
> What I am able to do now is:
>
> - As long as I trust oldRoot and my server handshake send subCA and
> bridge, the trustchain verifies: "Verify return code: 0 (ok)"
>
> - As long as I trust newRoot any my server handshake send subCA but NOT
> bridge, the trustchain verifies: "Verify return code: 0 (ok)"
>

As expected and desired.

> - If I only trust newRoot but send the bridgeCert, I get an error. Also,
> if I only trust oldRoot and do not send bridge, I get an error.
>
If the client trusts only oldroot and server doesn't send bridge, that
should fail. The server isn't providing a chain that reaches something
the client trusts, so the client can't verify the server is authentic.

If the client trusts only newroot and the server does send bridge,
are you talking about a client using OpenSSL or something else?
OpenSSL client, at least through 1.0.1, doesn't handle that well,
but in my experience other clients (notably browsers and Java) do.

As I said in part:
<snip>
> > A stale client has only oldroot will chain bridge to oldroot and succeed
as long
> as
> > oldroot doesn't expire. A clever fresh client has newroot abd will chain
subCA
> to
> > newroot, ignoring bridge -- while a dumb client will ignore available
newroot
> and
> > insist on chaining bridge to oldroot. Every time I've looked (not
> systematically)
> > major browsers and Java are clever, but OpenSSL (client/relier) through
1.0.1
> is not.
> > I know 1.0.2 will change verification but don't know about this
particular
> point.
<snip>
In my simplified description, "not clever" is "dumb". OpenSSL relier (here
client)
through 1.0.1 when it receives a chain that *could* reach a trust anchor
from
the middle (i.e. subCA->newroot) doesn't actually look for that, it looks
only
at the end (i.e. bridge->oldroot?) and when that isn't found it returns
"unverified".

As indicated I haven't looked whether 1.0.2 will fix this; if it does, I
don't know
when it will be released and how long it will take your systems to be
upgraded
if they even can be (e.g. there is not another dependency on older OpenSSL).

Re: Verification of a certificate chain

Hi,

I'm actually testing this with openssl 1.0.1, which explains the
behavior. I misunderstood what you where saying about openssl 1.0.1
being "not clever".

Looks like I'll have to wait for openssl 1.0.2 being rolled out to all
my clients, or do a hard transition to the new CA, meaning some clients
will stop working until installing the new CA certificate.

>> From: [hidden email] On Behalf Of Sven Reissmann
>> Sent: Thursday, May 29, 2014 12:24
> <snip>
>> What I did was:
>>
>> - I generated a newRootCA (new keypair, selfsigned certificate).
>>
>> - I generated another selfsigned certificate (bridgeCert) from the
>> newRootCA's private key. From this cert, I used the -x509toreq
>> option to generate a csr (bridgeCSR).
>>
> (You didn't really need that, you could just -x509toreq from newroot,
> but no harm done as long as the DN is the same and per below it is.
> Or you can req -new directly from the key, but that's less convenient.)
>
>> - I took the bridgeCSR and issued a certificate using the oldRootCA.
>> The certificate issued has AKI = oldRootCA and SKI = newRootCA
>>
>> - I generated a CSR for a new subCA and issued a certificate using
>> newRootCA. The AKI of the subCA cert is the same as the SKI of
>> newRootCA and bridgeCert. The AKI does not include any issuer or
>> serial information
>>
>> What I am able to do now is:
>>
>> - As long as I trust oldRoot and my server handshake send subCA and
>> bridge, the trustchain verifies: "Verify return code: 0 (ok)"
>>
>> - As long as I trust newRoot any my server handshake send subCA but NOT
>> bridge, the trustchain verifies: "Verify return code: 0 (ok)"
>>
> As expected and desired.
>
>> - If I only trust newRoot but send the bridgeCert, I get an error. Also,
>> if I only trust oldRoot and do not send bridge, I get an error.
>>
> If the client trusts only oldroot and server doesn't send bridge, that
> should fail. The server isn't providing a chain that reaches something
> the client trusts, so the client can't verify the server is authentic.
>
> If the client trusts only newroot and the server does send bridge,
> are you talking about a client using OpenSSL or something else?
> OpenSSL client, at least through 1.0.1, doesn't handle that well,
> but in my experience other clients (notably browsers and Java) do.
>
> As I said in part:
> <snip>
>>> A stale client has only oldroot will chain bridge to oldroot and succeed
> as long
>> as
>>> oldroot doesn't expire. A clever fresh client has newroot abd will chain
> subCA
>> to
>>> newroot, ignoring bridge -- while a dumb client will ignore available
> newroot
>> and
>>> insist on chaining bridge to oldroot. Every time I've looked (not
>> systematically)
>>> major browsers and Java are clever, but OpenSSL (client/relier) through
> 1.0.1
>> is not.
>>> I know 1.0.2 will change verification but don't know about this
> particular
>> point.
> <snip>
> In my simplified description, "not clever" is "dumb". OpenSSL relier (here
> client)
> through 1.0.1 when it receives a chain that *could* reach a trust anchor
> from
> the middle (i.e. subCA->newroot) doesn't actually look for that, it looks
> only
> at the end (i.e. bridge->oldroot?) and when that isn't found it returns
> "unverified".
>
> As indicated I haven't looked whether 1.0.2 will fix this; if it does, I
> don't know
> when it will be released and how long it will take your systems to be
> upgraded
> if they even can be (e.g. there is not another dependency on older OpenSSL).
>
>
> ______________________________________________________________________
> OpenSSL Project http://www.openssl.org> User Support Mailing List [hidden email]> Automated List Manager [hidden email]>