Quantcast

CertPath validation bug in BC 1.46?

classic Classic list List threaded Threaded
10 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

CertPath validation bug in BC 1.46?

Emerson Luiz Navarro Tozette
I'm trying to validate a very simple certificate chain using
CertPathBuilder and the Bouncycastle provider (bcprov-jdk15-146.jar).

The chain contains three certificates (end entity, intermediate CA and
root CA) and two CRLs (issued by the two CAs).
The CRL issued by the intermediate CA revokes the end entity
certificate. The revocation date is "Jan 2, 2001".
There are no delta CRLs.

The problem is that I'm using the date "Jan 1, 2001" as the time for
which the validity of the certification path should be determined.
The certificate chain is valid at that date. Anyway the provider is
throwing an exception:


Caused by: org.bouncycastle.jce.exception.ExtCertPathValidatorException:
Certificate revocation after Tue Jan 02 10:00:00 BRST 2001, reason:
unspecified
        at org.bouncycastle.jce.provider.RFC3280CertPathUtilities.processCertA(Unknown
Source)
        at org.bouncycastle.jce.provider.PKIXCertPathValidatorSpi.engineValidate(Unknown
Source)
        at java.security.cert.CertPathValidator.validate(CertPathValidator.java:206)
        at org.bouncycastle.jce.provider.PKIXCertPathBuilderSpi.build(Unknown Source)
        at org.bouncycastle.jce.provider.PKIXCertPathBuilderSpi.build(Unknown Source)
        ... 20 more
Caused by: org.bouncycastle.jce.provider.AnnotatedException:
Certificate revocation after Tue Jan 02 10:00:00 BRST 2001, reason:
unspecified
        at org.bouncycastle.jce.provider.RFC3280CertPathUtilities.checkCRLs(Unknown
Source)
        ... 25 more


I debbuged the BC provider (using bcprov-jdk15-146b29.jar) and find
out that the problem is in the method
CertPathValidatorUtilities.getCertStatus(..), called by the method
RFC3280CertPathUtilities.processCRLJ(..)

The problem is that it doesn't matter if the validation date is before
the revocation date: the above code
ignores the date depending on the reasonCode of the revocation:


            // for reason keyCompromise, caCompromise, aACompromise or
            // unspecified
            if (!(validDate.getTime() < crl_entry.getRevocationDate().getTime())
                || reasonCode == null
                || reasonCode.getValue().intValue() == 0
                || reasonCode.getValue().intValue() == 1
                || reasonCode.getValue().intValue() == 2
                || reasonCode.getValue().intValue() == 8)
            {

                // (i) or (j) (1)
                if (reasonCode != null)
                {
                    // CERTIFICATE CAN BE MARKED AS REVOKED
INDEPENDENTLY OF THE VALIDATION DATE:
                    certStatus.setCertStatus(reasonCode.getValue().intValue());
                }



So my question is: is this a bug? Or is this a feature?

--
  Emerson Luiz Navarro Tozette

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: CertPath validation bug in BC 1.46?

David Hook-2

It's actually a feature, or at least a result of us coming down on the
side of caution and thinking it's a feature - the problem is that if the
certificate was revoked as a result of compromise (unspecified is
assumed to be the worst case) the date actually becomes irrelevant
(backdating a signature is trivial once you have a copy of the private
key). In situations like this the only way you can be sure you're
looking at the real deal is if the signature is independently time
stamped.

Regards,

David

On Tue, 2011-03-01 at 15:07 -0300, Emerson Luiz Navarro Tozette wrote:

> I'm trying to validate a very simple certificate chain using
> CertPathBuilder and the Bouncycastle provider (bcprov-jdk15-146.jar).
>
> The chain contains three certificates (end entity, intermediate CA and
> root CA) and two CRLs (issued by the two CAs).
> The CRL issued by the intermediate CA revokes the end entity
> certificate. The revocation date is "Jan 2, 2001".
> There are no delta CRLs.
>
> The problem is that I'm using the date "Jan 1, 2001" as the time for
> which the validity of the certification path should be determined.
> The certificate chain is valid at that date. Anyway the provider is
> throwing an exception:
>
>
> Caused by: org.bouncycastle.jce.exception.ExtCertPathValidatorException:
> Certificate revocation after Tue Jan 02 10:00:00 BRST 2001, reason:
> unspecified
> at org.bouncycastle.jce.provider.RFC3280CertPathUtilities.processCertA(Unknown
> Source)
> at org.bouncycastle.jce.provider.PKIXCertPathValidatorSpi.engineValidate(Unknown
> Source)
> at java.security.cert.CertPathValidator.validate(CertPathValidator.java:206)
> at org.bouncycastle.jce.provider.PKIXCertPathBuilderSpi.build(Unknown Source)
> at org.bouncycastle.jce.provider.PKIXCertPathBuilderSpi.build(Unknown Source)
> ... 20 more
> Caused by: org.bouncycastle.jce.provider.AnnotatedException:
> Certificate revocation after Tue Jan 02 10:00:00 BRST 2001, reason:
> unspecified
> at org.bouncycastle.jce.provider.RFC3280CertPathUtilities.checkCRLs(Unknown
> Source)
> ... 25 more
>
>
> I debbuged the BC provider (using bcprov-jdk15-146b29.jar) and find
> out that the problem is in the method
> CertPathValidatorUtilities.getCertStatus(..), called by the method
> RFC3280CertPathUtilities.processCRLJ(..)
>
> The problem is that it doesn't matter if the validation date is before
> the revocation date: the above code
> ignores the date depending on the reasonCode of the revocation:
>
>
>             // for reason keyCompromise, caCompromise, aACompromise or
>             // unspecified
>             if (!(validDate.getTime() < crl_entry.getRevocationDate().getTime())
>                 || reasonCode == null
>                 || reasonCode.getValue().intValue() == 0
>                 || reasonCode.getValue().intValue() == 1
>                 || reasonCode.getValue().intValue() == 2
>                 || reasonCode.getValue().intValue() == 8)
>             {
>
>                 // (i) or (j) (1)
>                 if (reasonCode != null)
>                 {
>                     // CERTIFICATE CAN BE MARKED AS REVOKED
> INDEPENDENTLY OF THE VALIDATION DATE:
>                     certStatus.setCertStatus(reasonCode.getValue().intValue());
>                 }
>
>
>
> So my question is: is this a bug? Or is this a feature?
>
> --
>   Emerson Luiz Navarro Tozette
>



Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: CertPath validation bug in BC 1.46?

Emerson Luiz Navarro Tozette
Thanks for the answer, David.


My problem is that I'm validating a CAdES electronic signature, and
the CAdES constains a time-stamp that
I'm using to validate the signer certificate chain. The time inside
the time-stamp is "Jan 1, 2001" and the
signer certificate was revoked at "Jan 2, 2001". So in this case,
using "Jan 1, 2001" as the validation date,
shouldn't the signer certificate chain be considered valid?


What I'm doing nowadays is testing an application that uses
bouncycastle against a CAdES test suite
(the ECOM CAdES/XAdES Plugtest 2007).

The suite can be found at
http://www.jipdec.or.jp/archives/ecom/LongTermStorage/en/interoptest2007.html


My validation problem using bouncycastle refers to test case number 10004:

"The application should ignore the SigningTime attribute and validate
successfully the ES-T format in cases where it is
revoked at the time in the SigningTime attribute, but NOT revoked
according to the time in signature time-stamp."




2011/3/1 David Hook <[hidden email]>:

>
> It's actually a feature, or at least a result of us coming down on the
> side of caution and thinking it's a feature - the problem is that if the
> certificate was revoked as a result of compromise (unspecified is
> assumed to be the worst case) the date actually becomes irrelevant
> (backdating a signature is trivial once you have a copy of the private
> key). In situations like this the only way you can be sure you're
> looking at the real deal is if the signature is independently time
> stamped.
>
> Regards,
>
> David
>
> On Tue, 2011-03-01 at 15:07 -0300, Emerson Luiz Navarro Tozette wrote:
>> I'm trying to validate a very simple certificate chain using
>> CertPathBuilder and the Bouncycastle provider (bcprov-jdk15-146.jar).
>>
>> The chain contains three certificates (end entity, intermediate CA and
>> root CA) and two CRLs (issued by the two CAs).
>> The CRL issued by the intermediate CA revokes the end entity
>> certificate. The revocation date is "Jan 2, 2001".
>> There are no delta CRLs.
>>
>> The problem is that I'm using the date "Jan 1, 2001" as the time for
>> which the validity of the certification path should be determined.
>> The certificate chain is valid at that date. Anyway the provider is
>> throwing an exception:
>>
>>
>> Caused by: org.bouncycastle.jce.exception.ExtCertPathValidatorException:
>> Certificate revocation after Tue Jan 02 10:00:00 BRST 2001, reason:
>> unspecified
>>       at org.bouncycastle.jce.provider.RFC3280CertPathUtilities.processCertA(Unknown
>> Source)
>>       at org.bouncycastle.jce.provider.PKIXCertPathValidatorSpi.engineValidate(Unknown
>> Source)
>>       at java.security.cert.CertPathValidator.validate(CertPathValidator.java:206)
>>       at org.bouncycastle.jce.provider.PKIXCertPathBuilderSpi.build(Unknown Source)
>>       at org.bouncycastle.jce.provider.PKIXCertPathBuilderSpi.build(Unknown Source)
>>       ... 20 more
>> Caused by: org.bouncycastle.jce.provider.AnnotatedException:
>> Certificate revocation after Tue Jan 02 10:00:00 BRST 2001, reason:
>> unspecified
>>       at org.bouncycastle.jce.provider.RFC3280CertPathUtilities.checkCRLs(Unknown
>> Source)
>>       ... 25 more
>>
>>
>> I debbuged the BC provider (using bcprov-jdk15-146b29.jar) and find
>> out that the problem is in the method
>> CertPathValidatorUtilities.getCertStatus(..), called by the method
>> RFC3280CertPathUtilities.processCRLJ(..)
>>
>> The problem is that it doesn't matter if the validation date is before
>> the revocation date: the above code
>> ignores the date depending on the reasonCode of the revocation:
>>
>>
>>             // for reason keyCompromise, caCompromise, aACompromise or
>>             // unspecified
>>             if (!(validDate.getTime() < crl_entry.getRevocationDate().getTime())
>>                 || reasonCode == null
>>                 || reasonCode.getValue().intValue() == 0
>>                 || reasonCode.getValue().intValue() == 1
>>                 || reasonCode.getValue().intValue() == 2
>>                 || reasonCode.getValue().intValue() == 8)
>>             {
>>
>>                 // (i) or (j) (1)
>>                 if (reasonCode != null)
>>                 {
>>                     // CERTIFICATE CAN BE MARKED AS REVOKED
>> INDEPENDENTLY OF THE VALIDATION DATE:
>>                     certStatus.setCertStatus(reasonCode.getValue().intValue());
>>                 }
>>
>>
>>
>> So my question is: is this a bug? Or is this a feature?
>>
>> --
>>   Emerson Luiz Navarro Tozette
>>
>
>
>
>



--
--
  Emerson Luiz Navarro Tozette

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: CertPath validation bug in BC 1.46?

martijn.list
On 03/02/2011 02:49 PM, Emerson Luiz Navarro Tozette wrote:

> My problem is that I'm validating a CAdES electronic signature, and
> the CAdES constains a time-stamp that
> I'm using to validate the signer certificate chain. The time inside
> the time-stamp is "Jan 1, 2001" and the
> signer certificate was revoked at "Jan 2, 2001". So in this case,
> using "Jan 1, 2001" as the validation date,
> shouldn't the signer certificate chain be considered valid?
>
>
> What I'm doing nowadays is testing an application that uses
> bouncycastle against a CAdES test suite
> (the ECOM CAdES/XAdES Plugtest 2007).
>
> The suite can be found at
> http://www.jipdec.or.jp/archives/ecom/LongTermStorage/en/interoptest2007.html
>
>
> My validation problem using bouncycastle refers to test case number 10004:
>
> "The application should ignore the SigningTime attribute and validate
> successfully the ES-T format in cases where it is
> revoked at the time in the SigningTime attribute, but NOT revoked
> according to the time in signature time-stamp."
>
>
> 2011/3/1 David Hook <[hidden email]>:
>>
>> It's actually a feature, or at least a result of us coming down on the
>> side of caution and thinking it's a feature - the problem is that if the
>> certificate was revoked as a result of compromise (unspecified is
>> assumed to be the worst case) the date actually becomes irrelevant
>> (backdating a signature is trivial once you have a copy of the private
>> key). In situations like this the only way you can be sure you're
>> looking at the real deal is if the signature is independently time
>> stamped.
>>

Whether or not you consider the signature valid depends on what policy
you follow. The 'policy' that BC uses is the best policy to use by
default (imho) because like David explains, if a certificate is revoked
on a certain date it does not imply that the private key was not
compromised before the revocation date. Your policy however assumes that
the signature was valid because it was created before the revocation
date. One solution to your problem would be to remove any CRL which was
issued after the date you want to check. Because the CRL in your example
was issued after the signature date, you can remove the CRL from the
CertPath validation.

Kind regards,

Martijn Brinkers

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: CertPath validation bug in BC 1.46?

Emerson Luiz Navarro Tozette
My concern is that Bouncycastle provider does not implement exactly
the RFC3280 certpath validation algorithm,
but extends that algorithm using a 'hardcoded policy', which can cause
interoperability problems.

My objective is to build an application that is compatible with the
RFC3280 and also provider-independent, so
I can change the provider anytime I wish (and without having to adapt
my code to the provider I'm using).

Even if I need to implement some specific signature verification
policy, that implementation should be provider independent.

In others words I expect that every time I call:

CertPathBuilder.getInstance("PKIX")

I can get a different provider, but all the providers will implement
exactly the same algorithm, so my application
will behave always the same.


Regards


2011/3/2 martijn.list <[hidden email]>:

> On 03/02/2011 02:49 PM, Emerson Luiz Navarro Tozette wrote:
>> My problem is that I'm validating a CAdES electronic signature, and
>> the CAdES constains a time-stamp that
>> I'm using to validate the signer certificate chain. The time inside
>> the time-stamp is "Jan 1, 2001" and the
>> signer certificate was revoked at "Jan 2, 2001". So in this case,
>> using "Jan 1, 2001" as the validation date,
>> shouldn't the signer certificate chain be considered valid?
>>
>>
>> What I'm doing nowadays is testing an application that uses
>> bouncycastle against a CAdES test suite
>> (the ECOM CAdES/XAdES Plugtest 2007).
>>
>> The suite can be found at
>> http://www.jipdec.or.jp/archives/ecom/LongTermStorage/en/interoptest2007.html
>>
>>
>> My validation problem using bouncycastle refers to test case number 10004:
>>
>> "The application should ignore the SigningTime attribute and validate
>> successfully the ES-T format in cases where it is
>> revoked at the time in the SigningTime attribute, but NOT revoked
>> according to the time in signature time-stamp."
>>
>>
>> 2011/3/1 David Hook <[hidden email]>:
>>>
>>> It's actually a feature, or at least a result of us coming down on the
>>> side of caution and thinking it's a feature - the problem is that if the
>>> certificate was revoked as a result of compromise (unspecified is
>>> assumed to be the worst case) the date actually becomes irrelevant
>>> (backdating a signature is trivial once you have a copy of the private
>>> key). In situations like this the only way you can be sure you're
>>> looking at the real deal is if the signature is independently time
>>> stamped.
>>>
>
> Whether or not you consider the signature valid depends on what policy
> you follow. The 'policy' that BC uses is the best policy to use by
> default (imho) because like David explains, if a certificate is revoked
> on a certain date it does not imply that the private key was not
> compromised before the revocation date. Your policy however assumes that
> the signature was valid because it was created before the revocation
> date. One solution to your problem would be to remove any CRL which was
> issued after the date you want to check. Because the CRL in your example
> was issued after the signature date, you can remove the CRL from the
> CertPath validation.
>
> Kind regards,
>
> Martijn Brinkers
>
>



--
--
  Emerson Luiz Navarro Tozette

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: CertPath validation bug in BC 1.46?

martijn.list
On 03/02/2011 07:47 PM, Emerson Luiz Navarro Tozette wrote:
> My concern is that Bouncycastle provider does not implement exactly
> the RFC3280 certpath validation algorithm,
> but extends that algorithm using a 'hardcoded policy', which can cause
> interoperability problems.

Can you show me which part of RFC3280 tells that BC is faulty according
to RFC3280? Because afaik RFC3280 does not say anything about checking
validity in the past. As David already explains, if a private key is
compromised, it is trivial to create a signed document dated in the past
(unless a trusted time stamp service is used).

Kind regards,

Martijn Brinkers

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: CertPath validation bug in BC 1.46?

Greg Stark-3
In reply to this post by Emerson Luiz Navarro Tozette
A time stamp is not enough, it needs to be counter-signed by a trusted
timestamping authority. Otherwise the timestamp is just as easy to
forge as everything else that has been signed.

On Wed, Mar 2, 2011 at 8:49 AM, Emerson Luiz Navarro Tozette
<[hidden email]> wrote:

> Thanks for the answer, David.
>
>
> My problem is that I'm validating a CAdES electronic signature, and
> the CAdES constains a time-stamp that
> I'm using to validate the signer certificate chain. The time inside
> the time-stamp is "Jan 1, 2001" and the
> signer certificate was revoked at "Jan 2, 2001". So in this case,
> using "Jan 1, 2001" as the validation date,
> shouldn't the signer certificate chain be considered valid?
>
>
> What I'm doing nowadays is testing an application that uses
> bouncycastle against a CAdES test suite
> (the ECOM CAdES/XAdES Plugtest 2007).
>
> The suite can be found at
> http://www.jipdec.or.jp/archives/ecom/LongTermStorage/en/interoptest2007.html
>
>
> My validation problem using bouncycastle refers to test case number 10004:
>
> "The application should ignore the SigningTime attribute and validate
> successfully the ES-T format in cases where it is
> revoked at the time in the SigningTime attribute, but NOT revoked
> according to the time in signature time-stamp."
>
>
>
>
> 2011/3/1 David Hook <[hidden email]>:
>>
>> It's actually a feature, or at least a result of us coming down on the
>> side of caution and thinking it's a feature - the problem is that if the
>> certificate was revoked as a result of compromise (unspecified is
>> assumed to be the worst case) the date actually becomes irrelevant
>> (backdating a signature is trivial once you have a copy of the private
>> key). In situations like this the only way you can be sure you're
>> looking at the real deal is if the signature is independently time
>> stamped.
>>
>> Regards,
>>
>> David
>>
>> On Tue, 2011-03-01 at 15:07 -0300, Emerson Luiz Navarro Tozette wrote:
>>> I'm trying to validate a very simple certificate chain using
>>> CertPathBuilder and the Bouncycastle provider (bcprov-jdk15-146.jar).
>>>
>>> The chain contains three certificates (end entity, intermediate CA and
>>> root CA) and two CRLs (issued by the two CAs).
>>> The CRL issued by the intermediate CA revokes the end entity
>>> certificate. The revocation date is "Jan 2, 2001".
>>> There are no delta CRLs.
>>>
>>> The problem is that I'm using the date "Jan 1, 2001" as the time for
>>> which the validity of the certification path should be determined.
>>> The certificate chain is valid at that date. Anyway the provider is
>>> throwing an exception:
>>>
>>>
>>> Caused by: org.bouncycastle.jce.exception.ExtCertPathValidatorException:
>>> Certificate revocation after Tue Jan 02 10:00:00 BRST 2001, reason:
>>> unspecified
>>>       at org.bouncycastle.jce.provider.RFC3280CertPathUtilities.processCertA(Unknown
>>> Source)
>>>       at org.bouncycastle.jce.provider.PKIXCertPathValidatorSpi.engineValidate(Unknown
>>> Source)
>>>       at java.security.cert.CertPathValidator.validate(CertPathValidator.java:206)
>>>       at org.bouncycastle.jce.provider.PKIXCertPathBuilderSpi.build(Unknown Source)
>>>       at org.bouncycastle.jce.provider.PKIXCertPathBuilderSpi.build(Unknown Source)
>>>       ... 20 more
>>> Caused by: org.bouncycastle.jce.provider.AnnotatedException:
>>> Certificate revocation after Tue Jan 02 10:00:00 BRST 2001, reason:
>>> unspecified
>>>       at org.bouncycastle.jce.provider.RFC3280CertPathUtilities.checkCRLs(Unknown
>>> Source)
>>>       ... 25 more
>>>
>>>
>>> I debbuged the BC provider (using bcprov-jdk15-146b29.jar) and find
>>> out that the problem is in the method
>>> CertPathValidatorUtilities.getCertStatus(..), called by the method
>>> RFC3280CertPathUtilities.processCRLJ(..)
>>>
>>> The problem is that it doesn't matter if the validation date is before
>>> the revocation date: the above code
>>> ignores the date depending on the reasonCode of the revocation:
>>>
>>>
>>>             // for reason keyCompromise, caCompromise, aACompromise or
>>>             // unspecified
>>>             if (!(validDate.getTime() < crl_entry.getRevocationDate().getTime())
>>>                 || reasonCode == null
>>>                 || reasonCode.getValue().intValue() == 0
>>>                 || reasonCode.getValue().intValue() == 1
>>>                 || reasonCode.getValue().intValue() == 2
>>>                 || reasonCode.getValue().intValue() == 8)
>>>             {
>>>
>>>                 // (i) or (j) (1)
>>>                 if (reasonCode != null)
>>>                 {
>>>                     // CERTIFICATE CAN BE MARKED AS REVOKED
>>> INDEPENDENTLY OF THE VALIDATION DATE:
>>>                     certStatus.setCertStatus(reasonCode.getValue().intValue());
>>>                 }
>>>
>>>
>>>
>>> So my question is: is this a bug? Or is this a feature?
>>>
>>> --
>>>   Emerson Luiz Navarro Tozette
>>>
>>
>>
>>
>>
>
>
>
> --
> --
>   Emerson Luiz Navarro Tozette
>
>



--
quid pro quo

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: CertPath validation bug in BC 1.46?

David Hook-2
In reply to this post by Emerson Luiz Navarro Tozette

The CertPath validation is RFC 3280 compliant, RFC 5280 even. The
particular issue you are looking at is actually in the fogy section of
the standards, section 6 really just talks about finding the reason
code, how you interpret the reason code in conjunction with the date is
left as an exercise.

I would say the test suite example is poorly defined though, they should
specify a revocation type of privilegeWithdrawn if they want to
generally get the behaviour described (for caveats see comment about
6.3.2 below). I'm pretty sure we're not the only validator that assumes
the worst if it runs into unspecified.

Part of the issue here is with the way the CRL processing is handled,
ideally it would be possible to establish an object that determines the
policy with which a CRL is dealt with (for example RFC 5280 6.3.2
mentions that in some cases CRL processing may only be interested in
caCompromise and keyCompromise, in this case a "compliant" validator
would also fail the test). Will have to think about this one...

Regards,

David

On Wed, 2011-03-02 at 15:47 -0300, Emerson Luiz Navarro Tozette wrote:

> My concern is that Bouncycastle provider does not implement exactly
> the RFC3280 certpath validation algorithm,
> but extends that algorithm using a 'hardcoded policy', which can cause
> interoperability problems.
>
> My objective is to build an application that is compatible with the
> RFC3280 and also provider-independent, so
> I can change the provider anytime I wish (and without having to adapt
> my code to the provider I'm using).
>
> Even if I need to implement some specific signature verification
> policy, that implementation should be provider independent.
>
> In others words I expect that every time I call:
>
> CertPathBuilder.getInstance("PKIX")
>
> I can get a different provider, but all the providers will implement
> exactly the same algorithm, so my application
> will behave always the same.
>
>
> Regards
>
>
> 2011/3/2 martijn.list <[hidden email]>:
> > On 03/02/2011 02:49 PM, Emerson Luiz Navarro Tozette wrote:
> >> My problem is that I'm validating a CAdES electronic signature, and
> >> the CAdES constains a time-stamp that
> >> I'm using to validate the signer certificate chain. The time inside
> >> the time-stamp is "Jan 1, 2001" and the
> >> signer certificate was revoked at "Jan 2, 2001". So in this case,
> >> using "Jan 1, 2001" as the validation date,
> >> shouldn't the signer certificate chain be considered valid?
> >>
> >>
> >> What I'm doing nowadays is testing an application that uses
> >> bouncycastle against a CAdES test suite
> >> (the ECOM CAdES/XAdES Plugtest 2007).
> >>
> >> The suite can be found at
> >> http://www.jipdec.or.jp/archives/ecom/LongTermStorage/en/interoptest2007.html
> >>
> >>
> >> My validation problem using bouncycastle refers to test case number 10004:
> >>
> >> "The application should ignore the SigningTime attribute and validate
> >> successfully the ES-T format in cases where it is
> >> revoked at the time in the SigningTime attribute, but NOT revoked
> >> according to the time in signature time-stamp."
> >>
> >>
> >> 2011/3/1 David Hook <[hidden email]>:
> >>>
> >>> It's actually a feature, or at least a result of us coming down on the
> >>> side of caution and thinking it's a feature - the problem is that if the
> >>> certificate was revoked as a result of compromise (unspecified is
> >>> assumed to be the worst case) the date actually becomes irrelevant
> >>> (backdating a signature is trivial once you have a copy of the private
> >>> key). In situations like this the only way you can be sure you're
> >>> looking at the real deal is if the signature is independently time
> >>> stamped.
> >>>
> >
> > Whether or not you consider the signature valid depends on what policy
> > you follow. The 'policy' that BC uses is the best policy to use by
> > default (imho) because like David explains, if a certificate is revoked
> > on a certain date it does not imply that the private key was not
> > compromised before the revocation date. Your policy however assumes that
> > the signature was valid because it was created before the revocation
> > date. One solution to your problem would be to remove any CRL which was
> > issued after the date you want to check. Because the CRL in your example
> > was issued after the signature date, you can remove the CRL from the
> > CertPath validation.
> >
> > Kind regards,
> >
> > Martijn Brinkers
> >
> >
>
>
>



Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: CertPath validation bug in BC 1.46?

Kyle Hamilton
In reply to this post by Emerson Luiz Navarro Tozette


On Wed, Mar 2, 2011 at 11:37 AM, martijn.list <[hidden email]> wrote:
> On 03/02/2011 07:47 PM, Emerson Luiz Navarro Tozette wrote:
>> My concern is that Bouncycastle provider does not implement exactly
>> the RFC3280 certpath validation algorithm,
>> but extends that algorithm using a 'hardcoded policy', which can cause
>> interoperability problems.
>
> Can you show me which part of RFC3280 tells that BC is faulty according
> to RFC3280? Because afaik RFC3280 does not say anything about checking
> validity in the past.

RFC3280 (and 5280) specifies 'the current time'.  The ability to validate based on a prior time is an extension.

However, since BC's validator allows any arbitrary time to be passed as 'the current time', the expectation of the client is that there is only one variable changed in the path validation logic -- not that there is an additional input to the validator ("stuff that says it happens in the future").

> As David already explains, if a private key is
> compromised, it is trivial to create a signed document dated in the past
> (unless a trusted time stamp service is used).

If a trusted time stamp service is used, BC doesn't have a way to pass a timestamp certificate into the path validation code.  BC also doesn't have a way to force the path validation code to work as of that time, such as would be necessary in the event that the client did have such a time stamp.

Thus, even if a trusted time stamp existed and was authenticated by the client of the library, BC would still fail the path validation as of that time.  The "it will work if you have a trusted time stamp" implication is false.

Would BC do this if the CRL brought in claimed to have been issued next century versus the authoritative Now ("current time")?  The answer is 'yes', since BC's path validation implementation doesn't compare the passed time to Now.  The client isn't protected against glitches in the CA's systems, and the library doesn't perform sanity checking of its inputs -- and because the output of the validator is a boolean, the library also doesn't return what rule it failed on or why.  This makes for extremely difficult debugging scenarios.

The OP is trying to use BC to implement another standard, which relies upon correct and expected temporal semantics.  That BC doesn't support them (because BC's team thought it knew better than any mere client of the code) is a failure of BC, not of either the other standard or the client.  It doesn't matter if the consequences of strict conformance are usually a bad idea, the Legion's code is not conformant.

In temporal semantics, the watchword is 'causality': the effect happens only after the cause.  It doesn't matter if there's a potential gaping hole ripe for an attack -- since 3280 and 5280 have an input of "the current time", the client has a legitimate expectation that the output is deterministic -as of the time the validator uses as the current time-.  BC breaks this determinism by adding a new variable into the validation logic: "stuff that says it happens in the future".

The reason for the current implementation limitation is a very good one.  This is beyond dispute.  I'm all for it being added as an extension to the PKIX-specified path validation algorithm.  But it would have to be that -- an extension, with the ability to turn it off.

Even if there did exist a trusted third-party timestamp which was being checked against, BC's code currently does not allow for the path validation logic to be forced as of that time.  If a later CRL entry would make it fail in the path validator's future, that doesn't mean that it fails now -- it isn't up to the validator to determine what policy should be applied, it's only up to the validator to implement PKIX-conformant path-validation logic.

BC's path validation algorithm doesn't take a timestamp certificate as part of its input, it can't verify that timestamp which it doesn't take as part of its path validation processing, and it doesn't verify that the time it's being called to verify as 'the current time' is even Now.  The authentication of the trusted timestamp is on the client to do, as an operation distinct from validating the certification path as of the time it wants to verify against.

Because BC doesn't allow for the client to do his own due diligence and override the failure mode to determine if a certificate was valid as of a particular (authenticated or unauthenticated, it doesn't matter) nominated time, I regret that I think BC's behavior here is broken.

-Kyle H

Verify This Message with Penango.p7s (5K) Download Attachment
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: CertPath validation bug in BC 1.46?

David Hook-2

We're always happy to accept contributions on this one. We've been
discussing the idea of developing an alternate cert path API to allow
people to follow the different policies that various CAs operate under
for some time now.

Having said that, I would point out that BC is not responsible for the
capabilities and semantics of the JCA API, and that RFC 5280 does not
even discuss doing this. If a trusted time stamp was available which
could prove that a certificate was signed at a given time, the path
validation process could be run with revocation turned on and then the
certificate examined more thoroughly due to the failure (possibly by
simply turning revocation off, revalidating, and then implementing the
appropriate policy to handle the revocation such as timeStamp +
revocation date after = accept, anything else reject).

I still maintain that the test data been compared against is still
flawed - it should not be using unspecified on the basis that a path
validator isn't going to care about the reason for revocation, RFC 5280
specifically mentions that final treatment of a certificate for a
specific reason is up to the validator (6.3.3). In the situation
described in the test the most appropriate reason is privilegeWithdrawn.

Regards,

David

On Thu, 2011-03-03 at 04:35 -0800, Kyle Hamilton wrote:

>
> On Wed, Mar 2, 2011 at 11:37 AM, martijn.list <[hidden email]> wrote:
> > On 03/02/2011 07:47 PM, Emerson Luiz Navarro Tozette wrote:
> >> My concern is that Bouncycastle provider does not implement exactly
> >> the RFC3280 certpath validation algorithm,
> >> but extends that algorithm using a 'hardcoded policy', which can cause
> >> interoperability problems.
> >
> > Can you show me which part of RFC3280 tells that BC is faulty according
> > to RFC3280? Because afaik RFC3280 does not say anything about checking
> > validity in the past.
>
> RFC3280 (and 5280) specifies 'the current time'.  The ability to validate based on a prior time is an extension.
>
> However, since BC's validator allows any arbitrary time to be passed as 'the current time', the expectation of the client is that there is only one variable changed in the path validation logic -- not that there is an additional input to the validator ("stuff that says it happens in the future").
>
> > As David already explains, if a private key is
> > compromised, it is trivial to create a signed document dated in the past
> > (unless a trusted time stamp service is used).
>
> If a trusted time stamp service is used, BC doesn't have a way to pass a timestamp certificate into the path validation code.  BC also doesn't have a way to force the path validation code to work as of that time, such as would be necessary in the event that the client did have such a time stamp.
>
> Thus, even if a trusted time stamp existed and was authenticated by the client of the library, BC would still fail the path validation as of that time.  The "it will work if you have a trusted time stamp" implication is false.
>
> Would BC do this if the CRL brought in claimed to have been issued next century versus the authoritative Now ("current time")?  The answer is 'yes', since BC's path validation implementation doesn't compare the passed time to Now.  The client isn't protected against glitches in the CA's systems, and the library doesn't perform sanity checking of its inputs -- and because the output of the validator is a boolean, the library also doesn't return what rule it failed on or why.  This makes for extremely difficult debugging scenarios.
>
> The OP is trying to use BC to implement another standard, which relies upon correct and expected temporal semantics.  That BC doesn't support them (because BC's team thought it knew better than any mere client of the code) is a failure of BC, not of either the other standard or the client.  It doesn't matter if the consequences of strict conformance are usually a bad idea, the Legion's code is not conformant.
>
> In temporal semantics, the watchword is 'causality': the effect happens only after the cause.  It doesn't matter if there's a potential gaping hole ripe for an attack -- since 3280 and 5280 have an input of "the current time", the client has a legitimate expectation that the output is deterministic -as of the time the validator uses as the current time-.  BC breaks this determinism by adding a new variable into the validation logic: "stuff that says it happens in the future".
>
> The reason for the current implementation limitation is a very good one.  This is beyond dispute.  I'm all for it being added as an extension to the PKIX-specified path validation algorithm.  But it would have to be that -- an extension, with the ability to turn it off.
>
> Even if there did exist a trusted third-party timestamp which was being checked against, BC's code currently does not allow for the path validation logic to be forced as of that time.  If a later CRL entry would make it fail in the path validator's future, that doesn't mean that it fails now -- it isn't up to the validator to determine what policy should be applied, it's only up to the validator to implement PKIX-conformant path-validation logic.
>
> BC's path validation algorithm doesn't take a timestamp certificate as part of its input, it can't verify that timestamp which it doesn't take as part of its path validation processing, and it doesn't verify that the time it's being called to verify as 'the current time' is even Now.  The authentication of the trusted timestamp is on the client to do, as an operation distinct from validating the certification path as of the time it wants to verify against.
>
> Because BC doesn't allow for the client to do his own due diligence and override the failure mode to determine if a certificate was valid as of a particular (authenticated or unauthenticated, it doesn't matter) nominated time, I regret that I think BC's behavior here is broken.
>
> -Kyle H



Loading...