Certificate Verify and non-root Trust Anchors

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

Certificate Verify and non-root Trust Anchors

Dr. Pala

Hi all,

I am trying to verify a certificate and provide the possibility to directly trust an intermediate CA's certificate (not self-signed). After setting up the STORE and STORE_CTX and add the intermediate CA to the trusted certificates, when I use the "X509_verify_cert(ctx)" I get the usual "unable to get issuer certificate" - which would be fine for a "non-trusted" cert, but I would expect that to not be an issue for a trusted certificate.

Therefore, my question is what is the best method to have that behavior ?

I tried to use the certificate callback to do that, but there is no function to get the trusted certificates' stack (i.e., there is a X509_STORE_CTX_get0_untrusted() but there is no equivalent for the trusted certificates' stack) - so I could not verify if the current certificate (in the verify callback call) is in the trusted stack or not...

Maybe there are flags / trust settings that can be used instead ?

Cheers,
Max

--
Best Regards,
Massimiliano Pala, Ph.D.
OpenCA Labs Director
OpenCA Logo

--
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users

smime.p7s (5K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Certificate Verify and non-root Trust Anchors

Viktor Dukhovni


> On Dec 11, 2017, at 5:06 PM, Dr. Pala <[hidden email]> wrote:
>
> Hi all,
>
> I am trying to verify a certificate and provide the possibility to directly trust an intermediate CA's certificate (not self-signed). After setting up the STORE and STORE_CTX and add the intermediate CA to the trusted certificates, when I use the "X509_verify_cert(ctx)" I get the usual "unable to get issuer certificate" - which would be fine for a "non-trusted" cert, but I would expect that to not be an issue for a trusted certificate.
>
> Therefore, my question is what is the best method to have that behavior ?
>
> I tried to use the certificate callback to do that, but there is no function to get the trusted certificates' stack (i.e., there is a X509_STORE_CTX_get0_untrusted() but there is no equivalent for the trusted certificates' stack) - so I could not verify if the current certificate (in the verify callback call) is in the trusted stack or not...
>
> Maybe there are flags / trust settings that can be used instead ?

It seems we've neglected to document the X509_V_FLAG_PARTIAL_CHAIN
flag, which can be passed to X509_VERIFY_PARAM_set_flags() to
permit intermediate trust-anchors.

https://www.openssl.org/docs/man1.0.2/crypto/X509_VERIFY_PARAM_set_flags.html
https://www.openssl.org/docs/man1.1.0/crypto/X509_VERIFY_PARAM_set_flags.html


--
--
        Viktor.

--
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users
Reply | Threaded
Open this post in threaded view
|

Re: Certificate Verify and non-root Trust Anchors

Dr. Pala-2
Hi Victor,

thanks :D I just tried to set it and I get a different error now : 22
(certificate chain too long)... I suspect it is a side effect of using
the  X509_V_FLAG_PARTIAL_CHAIN flag... ? (no chain restrictions are set
in the certificates themselves...), but I have not dug into the vfy code
yet...

... any suggestion on how to fix this ? Do you think it is actually a
bug ? ... or am I missing some other configs / setting I should have
done for the verify param ?

Cheers,
Max


On 12/11/17 3:18 PM, Viktor Dukhovni wrote:

>
>> On Dec 11, 2017, at 5:06 PM, Dr. Pala <[hidden email]> wrote:
>>
>> Hi all,
>>
>> I am trying to verify a certificate and provide the possibility to directly trust an intermediate CA's certificate (not self-signed). After setting up the STORE and STORE_CTX and add the intermediate CA to the trusted certificates, when I use the "X509_verify_cert(ctx)" I get the usual "unable to get issuer certificate" - which would be fine for a "non-trusted" cert, but I would expect that to not be an issue for a trusted certificate.
>>
>> Therefore, my question is what is the best method to have that behavior ?
>>
>> I tried to use the certificate callback to do that, but there is no function to get the trusted certificates' stack (i.e., there is a X509_STORE_CTX_get0_untrusted() but there is no equivalent for the trusted certificates' stack) - so I could not verify if the current certificate (in the verify callback call) is in the trusted stack or not...
>>
>> Maybe there are flags / trust settings that can be used instead ?
> It seems we've neglected to document the X509_V_FLAG_PARTIAL_CHAIN
> flag, which can be passed to X509_VERIFY_PARAM_set_flags() to
> permit intermediate trust-anchors.
>
> https://www.openssl.org/docs/man1.0.2/crypto/X509_VERIFY_PARAM_set_flags.html
> https://www.openssl.org/docs/man1.1.0/crypto/X509_VERIFY_PARAM_set_flags.html
>
>

--
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users
Reply | Threaded
Open this post in threaded view
|

Re: Certificate Verify and non-root Trust Anchors

Viktor Dukhovni


> On Dec 11, 2017, at 6:03 PM, Dr. Pala <[hidden email]> wrote:
>
> thanks :D I just tried to set it and I get a different error now : 22 (certificate chain too long)... I suspect it is a side effect of using the  X509_V_FLAG_PARTIAL_CHAIN flag... ? (no chain restrictions are set in the certificates themselves...), but I have not dug into the vfy code yet...

Perhaps you ended up creating a parameter structure with a
depth limit that's too small.  Just configuring partial
chains will never yield a chain that is longer than it
otherwise would be.  In fact you generally get shorter
chains.  So, no this is not a result of using the
new flag, but may be a result of how you're going about
setting the flag.

> ... any suggestion on how to fix this ? Do you think it is actually a bug ? ... or am I missing some other configs / setting I should have done for the verify param ?

You should obtain a reference to the existing parameters
from the context, and modify these to add the new flag.

--
        Viktor.

--
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users
Reply | Threaded
Open this post in threaded view
|

Re: Certificate Verify and non-root Trust Anchors

d3x0r
In reply to this post by Dr. Pala-2
I'm pretty sure you need the root also, not just the intermedia ca...
I use a custom generated chain... I encode the root cert in the application, and then pass it when inintializing the client socket.

This bit of code takes the root cert and adds it to the SSL_CTX the client socket is created from....
( if no root passed, it loads root certs from windows store; haven't finished linux load cert store)

THis is where the cert chain is verified....

looking at that, I guess I should split that if and fail if it fails to get the peer certificate...

On Mon, Dec 11, 2017 at 3:03 PM, Dr. Pala <[hidden email]> wrote:
Hi Victor,

thanks :D I just tried to set it and I get a different error now : 22 (certificate chain too long)... I suspect it is a side effect of using the  X509_V_FLAG_PARTIAL_CHAIN flag... ? (no chain restrictions are set in the certificates themselves...), but I have not dug into the vfy code yet...

... any suggestion on how to fix this ? Do you think it is actually a bug ? ... or am I missing some other configs / setting I should have done for the verify param ?

Cheers,
Max


On 12/11/17 3:18 PM, Viktor Dukhovni wrote:

On Dec 11, 2017, at 5:06 PM, Dr. Pala <[hidden email]> wrote:

Hi all,

I am trying to verify a certificate and provide the possibility to directly trust an intermediate CA's certificate (not self-signed). After setting up the STORE and STORE_CTX and add the intermediate CA to the trusted certificates, when I use the "X509_verify_cert(ctx)" I get the usual "unable to get issuer certificate" - which would be fine for a "non-trusted" cert, but I would expect that to not be an issue for a trusted certificate.

Therefore, my question is what is the best method to have that behavior ?

I tried to use the certificate callback to do that, but there is no function to get the trusted certificates' stack (i.e., there is a X509_STORE_CTX_get0_untrusted() but there is no equivalent for the trusted certificates' stack) - so I could not verify if the current certificate (in the verify callback call) is in the trusted stack or not...

Maybe there are flags / trust settings that can be used instead ?
It seems we've neglected to document the X509_V_FLAG_PARTIAL_CHAIN
flag, which can be passed to X509_VERIFY_PARAM_set_flags() to
permit intermediate trust-anchors.

https://www.openssl.org/docs/man1.0.2/crypto/X509_VERIFY_PARAM_set_flags.html
https://www.openssl.org/docs/man1.1.0/crypto/X509_VERIFY_PARAM_set_flags.html



--
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users


--
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users
Reply | Threaded
Open this post in threaded view
|

Re: Certificate Verify and non-root Trust Anchors

Michael Richardson
In reply to this post by Dr. Pala

I believe that I ran into a similar problem where by I could not pin
('trust') an intermediate certificate (which was not self-signed) for the
purposes of verifying a CMS/PKCS7 object.

I don't have a solution, and I believe that work is required.

Dr. Pala <[hidden email]> wrote:
    > I am trying to verify a certificate and provide the possibility to
    > directly trust an intermediate CA's certificate (not self-signed).
    > After setting up the STORE and STORE_CTX and add the intermediate CA to
    > the trusted certificates, when I use the "X509_verify_cert(ctx)" I get
    > the usual "unable to get issuer certificate" - which would be fine for
    > a "non-trusted" cert, but I would expect that to not be an issue for a
    > trusted certificate.

    > Therefore, my question is what is the best method to have that behavior
    > ?

    > I tried to use the certificate callback to do that, but there is no
    > function to get the trusted certificates' stack (i.e., there is a
    > X509_STORE_CTX_get0_untrusted() but there is no equivalent for the
    > trusted certificates' stack) - so I could not verify if the current
    > certificate (in the verify callback call) is in the trusted stack or
    > not...

    > Maybe there are flags / trust settings that can be used instead ?

    > Cheers, Max

    > --
    > Best Regards, Massimiliano Pala, Ph.D.  OpenCA Labs Director OpenCA
    > Logo



    > --
    > openssl-users mailing list To unsubscribe:
    > https://mta.openssl.org/mailman/listinfo/openssl-users


--
]               Never tell me the odds!                 | ipv6 mesh networks [
]   Michael Richardson, Sandelman Software Works        | network architect  [
]     [hidden email]  http://www.sandelman.ca/        |   ruby on rails    [


--
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users

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

Re: Certificate Verify and non-root Trust Anchors

Viktor Dukhovni
In reply to this post by d3x0r


> On Dec 11, 2017, at 6:20 PM, J Decker <[hidden email]> wrote:
>
> I'm pretty sure you need the root also, not just the intermedia ca...

The purpose of X509_V_FLAG_PARTIAL_CHAIN is to make it possible
to make do with just the intermediate certificate in the trust
store.  So, no, the root is not always required.

--
        Viktor.

--
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users
Reply | Threaded
Open this post in threaded view
|

Re: Certificate Verify and non-root Trust Anchors

Viktor Dukhovni
In reply to this post by Michael Richardson


> On Dec 11, 2017, at 6:27 PM, Michael Richardson <[hidden email]> wrote:
>
> I believe that I ran into a similar problem where by I could not pin
> ('trust') an intermediate certificate (which was not self-signed) for the
> purposes of verifying a CMS/PKCS7 object.
>
> I don't have a solution, and I believe that work is required.

As I already mentioned a few times, the new X509_V_FLAG_PARTIAL_CHAIN
flag added in 1.0.2 addresses this issue.

To get pinning provide a trust store with just the pinned issuer CA,
and X509_V_FLAG_PARTIAL_CHAIN set.

With OpenSSL 1.1.0 one can also implement pinning by computing a TLSA
record for the pinned CA, and using OpenSSL's DANE support.  OpenSSL
does not do the DNS lookups to find TLSA records, that's up to the
application, so the TLSA records can be entirely synthetic (e.g.
derived from suitable hashes of a pinned CA cert or its public key).

--
        Viktor.

--
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users
Reply | Threaded
Open this post in threaded view
|

Re: Certificate Verify and non-root Trust Anchors

Dr. Pala-2
In reply to this post by Viktor Dukhovni

Hi Victor,

On 12/11/17 4:18 PM, Viktor Dukhovni wrote:
[...]

Perhaps you ended up creating a parameter structure with a
depth limit that's too small.  Just configuring partial
chains will never yield a chain that is longer than it
otherwise would be.  In fact you generally get shorter
chains.  So, no this is not a result of using the
new flag, but may be a result of how you're going about
setting the flag.
I actually do not set anything but the flag in the verify parameter, that is (error checking removed for clarity):

param = X509_VERIFY_PARAM_new();
X509_STORE_CTX_set0_param(ctx, param);
X509_VERIFY_PARAM_set_flags(param, X509_V_FLAG_PARTIAL_CHAIN);
X509_STORE_CTX_set0_trusted_stack(ctx, trustedCerts); // trustedCerts has only the SubCA
ret = X509_verify_cert(ctx);

fprintf(stderr, "[%s:%d] ctx->error = %d (%s)\n\n", __FILE__, __LINE__,
        X509_STORE_CTX_get_error(ctx),
        X509_verify_cert_error_string(X509_STORE_CTX_get_error(ctx)));

With this setting, I get the error.. which is the strange part as you said (the chain can not be longer :D). Maybe the code thinks that if you have a SubCA then you should have an additional level.. and since you do not have it, it sends the error... ???
... any suggestion on how to fix this ? Do you think it is actually a bug ? ... or am I missing some other configs / setting I should have done for the verify param ?
You should obtain a reference to the existing parameters
from the context, and modify these to add the new flag.

Well.. considering the code structure, the flags should be ok (since I just set it and then use it right away...) ???

Thanks,
Max


--
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users
Reply | Threaded
Open this post in threaded view
|

Re: Certificate Verify and non-root Trust Anchors

Dr. Pala-2
In reply to this post by Viktor Dukhovni
Hi Victor,

does it matter that we are not in the TLS case (maybe the code is
different in the SSL_CTX ) ? I am just trying to validate the chain with
the TA set to the SubCA... :D

IMHO, the correct (or, better, the expected) behavior (from a
developer's standpoint) would be to trust keys in the trusted
certificates list, no matter if they are in the form of a Self-Signed or
non-Self-Signed certificate - after all, it is a Trust Anchor --> just a
Public Key :D

Just my 2 cents...

Cheers,
Max


On 12/11/17 4:54 PM, Viktor Dukhovni wrote:

>
>> On Dec 11, 2017, at 6:27 PM, Michael Richardson <[hidden email]> wrote:
>>
>> I believe that I ran into a similar problem where by I could not pin
>> ('trust') an intermediate certificate (which was not self-signed) for the
>> purposes of verifying a CMS/PKCS7 object.
>>
>> I don't have a solution, and I believe that work is required.
> As I already mentioned a few times, the new X509_V_FLAG_PARTIAL_CHAIN
> flag added in 1.0.2 addresses this issue.
>
> To get pinning provide a trust store with just the pinned issuer CA,
> and X509_V_FLAG_PARTIAL_CHAIN set.
>
> With OpenSSL 1.1.0 one can also implement pinning by computing a TLSA
> record for the pinned CA, and using OpenSSL's DANE support.  OpenSSL
> does not do the DNS lookups to find TLSA records, that's up to the
> application, so the TLSA records can be entirely synthetic (e.g.
> derived from suitable hashes of a pinned CA cert or its public key).
>

--
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users
Reply | Threaded
Open this post in threaded view
|

Re: Certificate Verify and non-root Trust Anchors

Viktor Dukhovni
In reply to this post by Dr. Pala-2


> On Dec 11, 2017, at 7:35 PM, Dr. Pala <[hidden email]> wrote:
>
>> Perhaps you ended up creating a parameter structure with a
>> depth limit that's too small.  Just configuring partial
>> chains will never yield a chain that is longer than it
>> otherwise would be.  In fact you generally get shorter
>> chains.  So, no this is not a result of using the
>> new flag, but may be a result of how you're going about
>> setting the flag.

> I actually do not set anything but the flag in the verify parameter, that is (error checking removed for clarity):
> param = X509_VERIFY_PARAM_new();
> X509_STORE_CTX_set0_param(ctx, param);
> X509_VERIFY_PARAM_set_flags(param, X509_V_FLAG_PARTIAL_CHAIN);

There's the problem, you're creating new parameters, instead of
modifying the default parameters.

Instead, you must call:

        param = X509_STORE_CTX_get0_param(ctx);
        X509_VERIFY_PARAM_set_flags(param, X509_V_FLAG_PARTIAL_CHAIN);

> With this setting, I get the error..

Not surprising, the parameters you created don't have the default depth
setting.

> which is the strange part as you said (the chain can not be longer :D). Maybe the code thinks that if you have a SubCA then you should have an additional level.. and since you do not have it, it sends the error... ???
>>> ... any suggestion on how to fix this ? Do you think it is actually a bug ? ... or am I missing some other configs / setting I should have done for the verify param ?
>>>
>> You should obtain a reference to the existing parameters
>> from the context, and modify these to add the new flag.
>>
>>
> Well.. considering the code structure, the flags should be ok
> (since I just set it and then use it right away...) ???

Actually, no.  You're losing all the verification parameter initialization
done by X509_STORE_CTX_new():

    ctx->param = X509_VERIFY_PARAM_new();
    if (!ctx->param) {
        X509err(X509_F_X509_STORE_CTX_INIT, ERR_R_MALLOC_FAILURE);
        return 0;
    }

    /*
     * Inherit callbacks and flags from X509_STORE if not set use defaults.
     */
    if (store)
        ret = X509_VERIFY_PARAM_inherit(ctx->param, store->param);
    else
        ctx->param->inh_flags |= X509_VP_FLAG_DEFAULT | X509_VP_FLAG_ONCE;

    if (store) {
        ctx->verify_cb = store->verify_cb;
        /* Seems to always be 0 in OpenSSL, else must be idempotent */
        ctx->cleanup = store->cleanup;
    } else
        ctx->cleanup = 0;

    if (ret)
        ret = X509_VERIFY_PARAM_inherit(ctx->param,
                                        X509_VERIFY_PARAM_lookup("default"));

--
        Viktor.

--
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users
Reply | Threaded
Open this post in threaded view
|

Re: Certificate Verify and non-root Trust Anchors

Viktor Dukhovni
In reply to this post by Dr. Pala-2


> On Dec 11, 2017, at 7:41 PM, Dr. Pala <[hidden email]> wrote:
>
> Does it matter that we are not in the TLS case?

No, the issue is not TLS-specific.

> IMHO, the correct (or, better, the expected) behavior (from a developer's standpoint) would be to trust keys in the trusted certificates list, no matter if they are in the form of a Self-Signed or non-Self-Signed certificate - after all, it is a Trust Anchor --> just a Public Key :D

Intermediate CAs in the trust store were historically used just
to augment the peer's chain in case they were left out, and not
necessarily to signal independent trust in the intermediate CA.

The new flag makes it possible to indicate that you fully trust
also the intermediate CAs in the trust store.

With OpenSSL 1.1.0 or later, you can also decorate intermediate
CAs with explicit auxiliary trust EKUs and instead of storing
a regular X509 "CERTIFICATE" store a "TRUSTED CERTIFICATE".
Such intermediate CAs will work also for applications that don't
set X509_V_FLAG_PARTIAL_CHAIN.  That, together with the change
to default X509_V_FLAG_TRUSTED_FIRST, makes it possible to deploy
trusted intermediates with no application code changes.

Which reminds me, with OpenSSL 1.0.2 you should also set
X509_V_FLAG_TRUSTED_FIRST.  We did not backport that default
change to the stable 1.0.2 release out of caution, but it is
I think a more sensible default behaviour.

--
--
        Viktor.

--
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users
Reply | Threaded
Open this post in threaded view
|

Re: Certificate Verify and non-root Trust Anchors

Dr. Pala-2
In reply to this post by Viktor Dukhovni
Hi Victor,

Ahhhh... that is why :D I wrongly assumed that the newly created
parameters would hold the same initialization. This approach works!

Thanks again!

Cheers,
Max

On 12/11/17 5:45 PM, Viktor Dukhovni wrote:

>
>> On Dec 11, 2017, at 7:35 PM, Dr. Pala <[hidden email]> wrote:
>>
>>> Perhaps you ended up creating a parameter structure with a
>>> depth limit that's too small.  Just configuring partial
>>> chains will never yield a chain that is longer than it
>>> otherwise would be.  In fact you generally get shorter
>>> chains.  So, no this is not a result of using the
>>> new flag, but may be a result of how you're going about
>>> setting the flag.
>> I actually do not set anything but the flag in the verify parameter, that is (error checking removed for clarity):
>> param = X509_VERIFY_PARAM_new();
>> X509_STORE_CTX_set0_param(ctx, param);
>> X509_VERIFY_PARAM_set_flags(param, X509_V_FLAG_PARTIAL_CHAIN);
> There's the problem, you're creating new parameters, instead of
> modifying the default parameters.
>
> Instead, you must call:
>
> param = X509_STORE_CTX_get0_param(ctx);
>          X509_VERIFY_PARAM_set_flags(param, X509_V_FLAG_PARTIAL_CHAIN);
>
>> With this setting, I get the error..
> Not surprising, the parameters you created don't have the default depth
> setting.
>
>> which is the strange part as you said (the chain can not be longer :D). Maybe the code thinks that if you have a SubCA then you should have an additional level.. and since you do not have it, it sends the error... ???
>>>> ... any suggestion on how to fix this ? Do you think it is actually a bug ? ... or am I missing some other configs / setting I should have done for the verify param ?
>>>>
>>> You should obtain a reference to the existing parameters
>>> from the context, and modify these to add the new flag.
>>>
>>>
>> Well.. considering the code structure, the flags should be ok
>> (since I just set it and then use it right away...) ???
> Actually, no.  You're losing all the verification parameter initialization
> done by X509_STORE_CTX_new():
>
>      ctx->param = X509_VERIFY_PARAM_new();
>      if (!ctx->param) {
>          X509err(X509_F_X509_STORE_CTX_INIT, ERR_R_MALLOC_FAILURE);
>          return 0;
>      }
>
>      /*
>       * Inherit callbacks and flags from X509_STORE if not set use defaults.
>       */
>      if (store)
>          ret = X509_VERIFY_PARAM_inherit(ctx->param, store->param);
>      else
>          ctx->param->inh_flags |= X509_VP_FLAG_DEFAULT | X509_VP_FLAG_ONCE;
>
>      if (store) {
>          ctx->verify_cb = store->verify_cb;
>          /* Seems to always be 0 in OpenSSL, else must be idempotent */
>          ctx->cleanup = store->cleanup;
>      } else
>          ctx->cleanup = 0;
>
>      if (ret)
>          ret = X509_VERIFY_PARAM_inherit(ctx->param,
>                                          X509_VERIFY_PARAM_lookup("default"));
>

--
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users