Verification of a certificate chain

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
11 messages Options
Reply | Threaded
Open this post in threaded view
|

Verification of a certificate chain

Sven Reissmann
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)? I would have expected that
this will verify sucessfully:

openssl verify -CAfile subCA.pem subCA2.pem

Instead, I'm getting "error 2 at 1 depth lookup:unable to get issuer
certificate"

What do I miss?

Thanks, Sven.

--
PGP Key: https://0x80.io/pub/files/key.asc
PGP Key Fingerprint: 2DF2 79CD 48DD 4D38 F0B6  7557 2E68 D557 49AA 1D99

Note: I'll be transitioning away from this key in the near future.


signature.asc (919 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Verification of a certificate chain

Walter H.
Hello,

On Tue, May 27, 2014 15:44, Sven Reissmann wrote:

> 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

> Instead, I'm getting "error 2 at 1 depth lookup:unable to get issuer
> certificate"
>
> What do I miss?

settings in openssl.cnf

Walter

______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    [hidden email]
Automated List Manager                           [hidden email]
Reply | Threaded
Open this post in threaded view
|

Re: Verification of a certificate chain

Viktor Dukhovni
In reply to this post by Sven Reissmann
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.

> openssl verify -CAfile subCA.pem subCA2.pem
>
> Instead, I'm getting "error 2 at 1 depth lookup:unable to get issuer
> certificate"
>
> What do I miss?

The chain construction code in X509_verify_cert() is currently limited
to self-signed trust anchors.

--
        Viktor.
______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    [hidden email]
Automated List Manager                           [hidden email]
Reply | Threaded
Open this post in threaded view
|

Re: Verification of a certificate chain

Dr. Stephen Henson
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]
Reply | Threaded
Open this post in threaded view
|

Re: Verification of a certificate chain

Sven Reissmann
Hi,

thank you all for the clarification. As most users do not have OpenSSL
1.0.2, this doesn't seem to solve my problem.

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?

Thanks, Sven.

--
PGP Key: https://0x80.io/pub/files/key.asc
PGP Key Fingerprint: 2DF2 79CD 48DD 4D38 F0B6  7557 2E68 D557 49AA 1D99

Note: I'll be transitioning away from this key in the near future.

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]
>


signature.asc (919 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

RE: Verification of a certificate chain

Eisenacher, Patrick
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.

HTH,
Patrick Eisenacher

:��I"Ϯ��r�m���� (���Z+�K�+����1���x ��h���[�z�(���Z+� ��f�y������f���h��)z{,���
Reply | Threaded
Open this post in threaded view
|

Re: Verification of a certificate chain

Kyle Hamilton
In reply to this post by Sven Reissmann
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).

-Kyle H


On Tue, May 27, 2014 at 8:58 AM, Sven Reissmann <[hidden email]> wrote:
Hi,

thank you all for the clarification. As most users do not have OpenSSL
1.0.2, this doesn't seem to solve my problem.

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?

Thanks, Sven.

--
PGP Key: https://0x80.io/pub/files/key.asc
PGP Key Fingerprint: 2DF2 79CD 48DD 4D38 F0B6  7557 2E68 D557 49AA 1D99

Note: I'll be transitioning away from this key in the near future.

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]
>


Reply | Threaded
Open this post in threaded view
|

RE: Verification of a certificate chain

Dave Thompson-5
In reply to this post by Eisenacher, Patrick
> From: [hidden email] On Behalf Of Eisenacher, Patrick
> Sent: Tuesday, May 27, 2014 12:41

> > 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.



______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    [hidden email]
Automated List Manager                           [hidden email]
Reply | Threaded
Open this post in threaded view
|

RE: Verification of a certificate chain

Sven Reissmann
In reply to this post by Sven Reissmann
Hi,

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.


--
PGP Key: https://0x80.io/pub/files/key.asc


signature.asc (919 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

RE: Verification of a certificate chain

Dave Thompson-5
> 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]
Reply | Threaded
Open this post in threaded view
|

Re: Verification of a certificate chain

Sven Reissmann
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.

Thank you very much for your help.

Regards, Sven.

--
PGP Key: https://0x80.io/pub/files/key.asc
PGP Key Fingerprint: 2DF2 79CD 48DD 4D38 F0B6  7557 2E68 D557 49AA 1D99

Note: I'll be transitioning away from this key in the near future.

On 05/30/2014 12:03 AM, Dave Thompson wrote:

>> 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]
>


signature.asc (919 bytes) Download Attachment