Discussion:
Source Repository
Björn Kautler
2014-08-26 01:35:56 UTC
Permalink
Hi there,

I have a hard time in finding the official repository of BC.
There is no main menu point, pointing to it that I see.

http://www.bouncycastle.org/latest_releases.html and
http://www.bouncycastle.org/wiki/display/JA1/Building+the+Code+from+Source+Distributions+or+CVS
suggest there is a CVS repository.
But http://www.bouncycastle.org/viewcvs/viewcvs.cgi/bc-java which is
linked from the first page just results in a Python Traceback.

http://www.bouncycastle.org/latest_releases.html also suggest there is
Git access via a mirror on GitHub.
This is fine basically, but only a mirror.
The GitHub page says it mirrors
http://git.bouncycastle.org/repositories/bc-java but this address just
gives a 404 as gives http://git.bouncycastle.org/repositories/.

So where is the offical repo now, is the GitHub repo the official one?
At least I see a commit that was 20 hours ago there, but that does not
mean that it is the leading repository.

And if it is the leading (or even if not), do you accept pull requests onto it?

Btw. the "wiki" link on the left when on
http://www.bouncycastle.org/mailing_lists.html is also dead.

Regards
Björn
Peter Dettman
2014-08-26 02:15:01 UTC
Permalink
Hi Björn,
Our official repo is a private one, mirrored at some short, irregular
delay to https://github.com/bcgit/bc-java . We accept pull requests at
github, and apply them to the private repo.

We'll look at making the state of things clearer on our website.

Regards,
Pete Dettman
Post by Björn Kautler
Hi there,
I have a hard time in finding the official repository of BC.
There is no main menu point, pointing to it that I see.
http://www.bouncycastle.org/latest_releases.html and
http://www.bouncycastle.org/wiki/display/JA1/Building+the+Code+from+Source+Distributions+or+CVS
suggest there is a CVS repository.
But http://www.bouncycastle.org/viewcvs/viewcvs.cgi/bc-java which is
linked from the first page just results in a Python Traceback.
http://www.bouncycastle.org/latest_releases.html also suggest there is
Git access via a mirror on GitHub.
This is fine basically, but only a mirror.
The GitHub page says it mirrors
http://git.bouncycastle.org/repositories/bc-java but this address just
gives a 404 as gives http://git.bouncycastle.org/repositories/.
So where is the offical repo now, is the GitHub repo the official one?
At least I see a commit that was 20 hours ago there, but that does not
mean that it is the leading repository.
And if it is the leading (or even if not), do you accept pull requests onto it?
Btw. the "wiki" link on the left when on
http://www.bouncycastle.org/mailing_lists.html is also dead.
Regards
Björn
Peter Dettman
2014-08-26 02:15:16 UTC
Permalink
Hi Björn,
Our official repo is a private one, mirrored at some short, irregular
delay to https://github.com/bcgit/bc-java . We accept pull requests at
github, and apply them to the private repo.

We'll look at making the state of things clearer on our website.

Regards,
Pete Dettman
Post by Björn Kautler
Hi there,
I have a hard time in finding the official repository of BC.
There is no main menu point, pointing to it that I see.
http://www.bouncycastle.org/latest_releases.html and
http://www.bouncycastle.org/wiki/display/JA1/Building+the+Code+from+Source+Distributions+or+CVS
suggest there is a CVS repository.
But http://www.bouncycastle.org/viewcvs/viewcvs.cgi/bc-java which is
linked from the first page just results in a Python Traceback.
http://www.bouncycastle.org/latest_releases.html also suggest there is
Git access via a mirror on GitHub.
This is fine basically, but only a mirror.
The GitHub page says it mirrors
http://git.bouncycastle.org/repositories/bc-java but this address just
gives a 404 as gives http://git.bouncycastle.org/repositories/.
So where is the offical repo now, is the GitHub repo the official one?
At least I see a commit that was 20 hours ago there, but that does not
mean that it is the leading repository.
And if it is the leading (or even if not), do you accept pull requests onto it?
Btw. the "wiki" link on the left when on
http://www.bouncycastle.org/mailing_lists.html is also dead.
Regards
Björn
David Hook
2014-08-26 02:15:46 UTC
Permalink
I've fixed the CVS error. We changed servers a week or so ago, seems RCS
didn't make it. CVS is also now a mirror of what's in git, but isn't
updated as often as github.

Yes https://github.com/bcgit/bc-java is our public mirror. You can issue
pull requests on that if you wish to introduce changes and (hopefully)
we will get to them in a timely manner.

Regards,

David
Post by Björn Kautler
Hi there,
I have a hard time in finding the official repository of BC.
There is no main menu point, pointing to it that I see.
http://www.bouncycastle.org/latest_releases.html and
http://www.bouncycastle.org/wiki/display/JA1/Building+the+Code+from+Source+Distributions+or+CVS
suggest there is a CVS repository.
But http://www.bouncycastle.org/viewcvs/viewcvs.cgi/bc-java which is
linked from the first page just results in a Python Traceback.
http://www.bouncycastle.org/latest_releases.html also suggest there is
Git access via a mirror on GitHub.
This is fine basically, but only a mirror.
The GitHub page says it mirrors
http://git.bouncycastle.org/repositories/bc-java but this address just
gives a 404 as gives http://git.bouncycastle.org/repositories/.
So where is the offical repo now, is the GitHub repo the official one?
At least I see a commit that was 20 hours ago there, but that does not
mean that it is the leading repository.
And if it is the leading (or even if not), do you accept pull requests onto it?
Btw. the "wiki" link on the left when on
http://www.bouncycastle.org/mailing_lists.html is also dead.
Regards
Björn
Björn Kautler
2014-08-26 12:41:13 UTC
Permalink
Thanks guys.
The point is that I found a blocker issue in how BC validates
certificate signatures.
I wanted to try and fix it myself, but I think it is too deeply rooted
to get it fixed by someone that is new to the codebase.
I'll tell you my findings and hopefully you can fix this soon, or at
least tell me how to work-around it.

The problem is e. g. with the attached certificate and the attached
issuer certificates.
This certificate is valid, against the certificate chain in the
issuers cert store attached.
The problem is the following:

X509CertificateObject.checkSignature() uses this.getTBSCertificate()
as input for Signature.update()
this.getTBSCertificate() uses
c.getTBSCertificate().getEncoded(ASN1Encoding.DER) to get the byte[]
and thus re-encodes the whole certificate
Unfortunately this does not result in the same data that is stored and
signed in the original certificate.
Where the problem is rooted, is ASN1Set.toDERObject() which sorts the
set entries.
In the certificate are three RDN values and this sorting is mixing
them up and thus a different byte[] is produced which differs exactly
at this one spot.

Two hacks(?) how those certificates validate correctly, is to either
not sort in ASN1Set.toDERObject() (I guess this is bad because the
sorting is part of the DER specification?),
or to change "return
c.getTBSCertificate().getEncoded(ASN1Encoding.DER);" to "return
c.getTBSCertificate().getEncoded(ASN1Encoding.DL);" in
X509CertificateObject.getTBSCertificate().

If you need any futher information or have an idea, please tell me. :-)

Regards
Björn
Post by David Hook
I've fixed the CVS error. We changed servers a week or so ago, seems RCS
didn't make it. CVS is also now a mirror of what's in git, but isn't updated
as often as github.
Yes https://github.com/bcgit/bc-java is our public mirror. You can issue
pull requests on that if you wish to introduce changes and (hopefully) we
will get to them in a timely manner.
Regards,
David
Post by Björn Kautler
Hi there,
I have a hard time in finding the official repository of BC.
There is no main menu point, pointing to it that I see.
http://www.bouncycastle.org/latest_releases.html and
http://www.bouncycastle.org/wiki/display/JA1/Building+the+Code+from+Source+Distributions+or+CVS
suggest there is a CVS repository.
But http://www.bouncycastle.org/viewcvs/viewcvs.cgi/bc-java which is
linked from the first page just results in a Python Traceback.
http://www.bouncycastle.org/latest_releases.html also suggest there is
Git access via a mirror on GitHub.
This is fine basically, but only a mirror.
The GitHub page says it mirrors
http://git.bouncycastle.org/repositories/bc-java but this address just
gives a 404 as gives http://git.bouncycastle.org/repositories/.
So where is the offical repo now, is the GitHub repo the official one?
At least I see a commit that was 20 hours ago there, but that does not
mean that it is the leading repository.
And if it is the leading (or even if not), do you accept pull requests onto it?
Btw. the "wiki" link on the left when on
http://www.bouncycastle.org/mailing_lists.html is also dead.
Regards
Björn
Peter Dettman
2014-08-26 13:21:22 UTC
Permalink
I haven't looked at the attachments yet, but it seems probable that the
certificate is in fact, _not_ valid. The signature in an X.509
certificate is over the DER encoding of the TBSCertificate (which
encoding is canonical), and that is regardless of what encoding the
certificate is presented in.

So the initial guess is that it was signed incorrectly, either by not
accounting for the canonical sort order of a DER encoding, or by failing
to explicitly re-encode as DER for input to the signer. I suppose we
should also check that BC is sorting the set correctly.

Would you mind sharing how the problem certificate was generated?

Pete.
Post by Björn Kautler
Thanks guys.
The point is that I found a blocker issue in how BC validates
certificate signatures.
I wanted to try and fix it myself, but I think it is too deeply rooted
to get it fixed by someone that is new to the codebase.
I'll tell you my findings and hopefully you can fix this soon, or at
least tell me how to work-around it.
The problem is e. g. with the attached certificate and the attached
issuer certificates.
This certificate is valid, against the certificate chain in the
issuers cert store attached.
X509CertificateObject.checkSignature() uses this.getTBSCertificate()
as input for Signature.update()
this.getTBSCertificate() uses
c.getTBSCertificate().getEncoded(ASN1Encoding.DER) to get the byte[]
and thus re-encodes the whole certificate
Unfortunately this does not result in the same data that is stored and
signed in the original certificate.
Where the problem is rooted, is ASN1Set.toDERObject() which sorts the
set entries.
In the certificate are three RDN values and this sorting is mixing
them up and thus a different byte[] is produced which differs exactly
at this one spot.
Two hacks(?) how those certificates validate correctly, is to either
not sort in ASN1Set.toDERObject() (I guess this is bad because the
sorting is part of the DER specification?),
or to change "return
c.getTBSCertificate().getEncoded(ASN1Encoding.DER);" to "return
c.getTBSCertificate().getEncoded(ASN1Encoding.DL);" in
X509CertificateObject.getTBSCertificate().
If you need any futher information or have an idea, please tell me. :-)
Regards
Björn
Björn Kautler
2014-08-26 14:16:17 UTC
Permalink
I'm sorry, but I have no idea.
The certificate is not generated by us.
We have to integrate a SmartCard login into our application with
SmartCards provided by a 3rd party.
If I use the Sun JCE Provider, the certificate validates and if I open
the certificate in Windows, the certificate also is shown as valid.
Thus I assumed that the problem lies in BC.
Post by Peter Dettman
I haven't looked at the attachments yet, but it seems probable that the
certificate is in fact, _not_ valid. The signature in an X.509 certificate
is over the DER encoding of the TBSCertificate (which encoding is
canonical), and that is regardless of what encoding the certificate is
presented in.
So the initial guess is that it was signed incorrectly, either by not
accounting for the canonical sort order of a DER encoding, or by failing to
explicitly re-encode as DER for input to the signer. I suppose we should
also check that BC is sorting the set correctly.
Would you mind sharing how the problem certificate was generated?
Pete.
Post by Björn Kautler
Thanks guys.
The point is that I found a blocker issue in how BC validates
certificate signatures.
I wanted to try and fix it myself, but I think it is too deeply rooted
to get it fixed by someone that is new to the codebase.
I'll tell you my findings and hopefully you can fix this soon, or at
least tell me how to work-around it.
The problem is e. g. with the attached certificate and the attached
issuer certificates.
This certificate is valid, against the certificate chain in the
issuers cert store attached.
X509CertificateObject.checkSignature() uses this.getTBSCertificate()
as input for Signature.update()
this.getTBSCertificate() uses
c.getTBSCertificate().getEncoded(ASN1Encoding.DER) to get the byte[]
and thus re-encodes the whole certificate
Unfortunately this does not result in the same data that is stored and
signed in the original certificate.
Where the problem is rooted, is ASN1Set.toDERObject() which sorts the
set entries.
In the certificate are three RDN values and this sorting is mixing
them up and thus a different byte[] is produced which differs exactly
at this one spot.
Two hacks(?) how those certificates validate correctly, is to either
not sort in ASN1Set.toDERObject() (I guess this is bad because the
sorting is part of the DER specification?),
or to change "return
c.getTBSCertificate().getEncoded(ASN1Encoding.DER);" to "return
c.getTBSCertificate().getEncoded(ASN1Encoding.DL);" in
X509CertificateObject.getTBSCertificate().
If you need any futher information or have an idea, please tell me. :-)
Regards
Björn
Matthew Hall
2014-08-26 17:12:22 UTC
Permalink
If I use the Sun JCE Provider, the certificate validates and if I open the
certificate in Windows, the certificate also is shown as valid. Thus I
assumed that the problem lies in BC.
This is a classic example of the Postel Robustness Principle:

"Be conservative in what you send, be liberal in what you accept".

Not every buggy roach-infested obscure ASN.1 certificate codebase out there is
going to do it right.

Matthew.
David Hook
2014-08-27 00:57:58 UTC
Permalink
At the risk of sounding like I'm too conservative, I don't think I'd
want to be quite that liberal.

Accepting a BER encoding of a certificate at face value (which is really
what is being asked for here) would dramatically increase the chances of
someone being able to fake one with a valid signature. Fifteen years ago
this would have sounded a bit far fetched, but these days I don't think
I'd risk it - we've already been given an excellent example of how
"lazy" parsing and encoding can be used with surprising results with
Daniel Bleichenbacher's work on adaptive-chosen-ciphertext. While this
is not quite the same thing, I'd argue that dismissing it as a
"theoretical concern" these days is reckless.

First things first. Section 4.1 of RFC 5280 says:

"For signature calculation, the data that is to be signed is encoded
using the ASN.1 distinguished encoding rules (DER) [X.690
<http://tools.ietf.org/html/rfc5280#ref-X.690>]."

Every previous profile has said the same thing, as does X.509. The
certificates are invalid, whoever it is who is producing them should be
told to stop and fix the problem.

Why? The reason all these standards specify DER is that it means that a
pile of ASN.1 will encode to one, and only one, string of encoded bytes.
If you're willing to use BER you can introduce constructed data (and yes
this can still be used with definite lengths) in anything (including
strings) which while it will produce something that looks identical to
an outside observer, will completely change the hash of the encoded data
(or more importantly, potentially allow you to introduce changes which
won't change the hash of the encoded data. but change the one thing you
want the outside observer to see). There is no limit on the number of
permutations you can try with this either.

So this is not a bug in BC and it will not be changed. The only outcome
is sometime in the future someone will show this is not theoretical
attack, or simply get lucky, and we'll get to fix it (the hard way). I
don't think it's a question of "if", it's simply a matter of "when".

In terms of Bjorn's options. If you're unable to get the parties
concerned to stop producing faulty signatures I'd recommend extending
X509Certificate or writing your own certificate factory and then using
it to create a wrapper based on the ASN.1 encoded cert that just returns
the TBSCertificate using DL encoding for the DNs only. Alternately, if
you're happy to deal with the risk there's going to be another global
panic when someone finally fakes a certificate, use the default provider
(option 1, also entails this risk, but at least you'd be limiting the
scope of any attack to the fields in question). You can get by with your
own certificate factory as CertificateFactory is a JCA component so does
not need to come from a signed provider.

As for how other vendors are doing it, all I'll say is we all get to
make our own beds. I would hope that some time in the future they will
tighten this up and do it properly.

If anyone doesn't understand what I have said, please free to ask.

Regards,

David
Post by Matthew Hall
If I use the Sun JCE Provider, the certificate validates and if I open the
certificate in Windows, the certificate also is shown as valid. Thus I
assumed that the problem lies in BC.
"Be conservative in what you send, be liberal in what you accept".
Not every buggy roach-infested obscure ASN.1 certificate codebase out there is
going to do it right.
Matthew.
Björn Kautler
2014-08-27 16:10:17 UTC
Permalink
)Thanks David for your extensive answer.
In the meantime I also delved into this a bit more.
You are absolutely right, those signatures are completely invalid.
The reason why the Sun provider (and probably also Windows) do not
detect these invalidities is, that they do not re-encode the decoded
TBSCertificate, but take the signed data blob as it is stored in the
X509Certificate and validate it against the signature. As soon as you
cast the X509CertImpl and run get("x509.info").set("serialnumber,
get("g509.info.serialnumber")) on it, the certificate gets re-encoded
and sorts the RDN set exactly like BC does. (Besides that it f**** up
the extensions sequence as it gets re-encoded mixed up in order).

I'm definitely NOT asking for this change, as BC is behaving perfectly
fine in discarding these certificates which I know now after jumping
deeper into the rabbit-hole.
I totally agree that this is not a BC problem and the card provider
should fix their stuff.
And if they will not, well, I guess I have to find some workaround.
Thanks for the suggestions on that area too.


Actually I created a pull request nevertheless, as I made two
improvements to the BC code on my journey, I hope you like and accept
them. :-) (https://github.com/bcgit/bc-java/pull/91)

Regards
Bjoern
Matthew Hall
2014-08-28 02:56:15 UTC
Permalink
Post by Björn Kautler
The reason why the Sun provider (and probably also Windows) do not
detect these invalidities is, that they do not re-encode the decoded
TBSCertificate, but take the signed data blob as it is stored in the
X509Certificate and validate it against the signature.
Many of these libs are avoiding re-encoding on purpose, so they can offer a
certain amount of "read-only" support for the broken certs... ASN.1 is a
really heinous encoding. OpenSSL had to add some compatibility code for this a
number of years ago.

Matthew.
Uri Blumenthal
2014-08-28 13:30:53 UTC
Permalink
All made good points. The question is - whether any support should be offered for the broken certs. If so, it might make sense to add code to accommodate, with some safeguards to avoid potential attacks via maliciously crafted mis-encoded fake certs…

P.S. ASN.1 is fine. Decades ago I wrote ASN.1 encoder/decoder (subset used in SNMP) as part of SNMPv{1,2,3} protocol stack, which (the protocol stack including ASN.1 processor) ran on all the IBM platforms of that time, from PS/2 and RS/6000 to AS/400 and Mainframe. Just requires some care, 'is all. :-)

P.P.S. I personally think that PER and ilk are much more heinous encodings than DER/ASN.1.
Post by Matthew Hall
Post by Björn Kautler
The reason why the Sun provider (and probably also Windows) do not
detect these invalidities is, that they do not re-encode the decoded
TBSCertificate, but take the signed data blob as it is stored in the
X509Certificate and validate it against the signature.
Many of these libs are avoiding re-encoding on purpose, so they can offer a
certain amount of "read-only" support for the broken certs... ASN.1 is a
really heinous encoding. OpenSSL had to add some compatibility code for this a
number of years ago.
Matthew.
--
Uri Blumenthal
uri-***@public.gmane.org

Loading...