Code Monkey home page Code Monkey logo

bc-java's Introduction

The Bouncy Castle Crypto Package For Java

Build Status

The Bouncy Castle Crypto package is a Java implementation of cryptographic algorithms, it was developed by the Legion of the Bouncy Castle, a registered Australian Charity, with a little help! The Legion, and the latest goings on with this package, can be found at https://www.bouncycastle.org.

The Legion also gratefully acknowledges the contributions made to this package by others (see here for the current list). If you would like to contribute to our efforts please feel free to get in touch with us or visit our donations page, sponsor some specific work, or purchase a support contract through Crypto Workshop (now part of Keyfactor).

The package is organised so that it contains a light-weight API suitable for use in any environment (including the newly released J2ME) with the additional infrastructure to conform the algorithms to the JCE framework.

Except where otherwise stated, this software is distributed under a license based on the MIT X Consortium license. To view the license, see here. The OpenPGP library also includes a modified BZIP2 library which is licensed under the Apache Software License, Version 2.0.

Note: this source tree is not the FIPS version of the APIs - if you are interested in our FIPS version please contact us directly at [email protected].

Environmental Variables

Before invoking gradlew you need to ensure the following environmental variables are defined and point to valid JAVA_HOMEs for each JVM version:

export BC_JDK8=/path/to/java8
export BC_JDK11=/path/to/java11
export BC_JDK17=/path/to/java17
export BC_JDK21=/path/to/java21

Building

The project now uses gradlew which can be invoked for example:

# from the root of the project

# Ensure JAVA_HOME points to JDK 17 or higher JAVA_HOME


./gradlew clean build

The gradle script will endeavour to verify their existence but not the correctness of their value.

Multi-release jars and testing

Some subprojects produce multi-release jars and these jars are tested in different jvm versions. Default testing on these projects is done on java 1.8 and there are specific test tasks for other versions.

  1. test11 test on java 11 JVM
  2. test17 test on java 17 JVM
  3. test21 test on java 21 JVM

To run all of them:

./gradlew clean build test11 test17 test21

Code Organisation

The clean room JCE, for use with JDK 1.1 to JDK 1.3 is in the jce/src/main/java directory. From JDK 1.4 and later the JCE ships with the JVM, the source for later JDKs follows the progress that was made in the later versions of the JCE. If you are using a later version of the JDK which comes with a JCE install please do not include the jce directory as a source file as it will clash with the JCE API installed with your JDK.

The core module provides all the functionality in the ligthweight APIs.

The prov module provides all the JCA/JCE provider functionality.

The util module is the home for code which is used by other modules that does not need to be in prov. At the moment this is largely ASN.1 classes for the PKIX module.

The pkix module is the home for code for X.509 certificate generation and the APIs for standards that rely on ASN.1 such as CMS, TSP, PKCS#12, OCSP, CRMF, and CMP.

The mail module provides an S/MIME API built on top of CMS.

The pg module is the home for code used to support OpenPGP.

The tls module is the home for code used to a general TLS API and JSSE Provider.

The build scripts that come with the full distribution allow creation of the different releases by using the different source trees while excluding classes that are not appropriate and copying in the required compatibility classes from the directories containing compatibility classes appropriate for the distribution.

If you want to try create a build for yourself, using your own environment, the best way to do it is to start with the build for the distribution you are interested in, make sure that builds, and then modify your build scripts to do the required exclusions and file copies for your setup, otherwise you are likely to get class not found exceptions. The final caveat to this is that as the j2me distribution includes some compatibility classes starting in the java package, you need to use an obfuscator to change the package names before attempting to import a midlet using the BC API.

Important: You will also need to check out the bc-test-data repository at the same level as the bc-java repository if you want to run the tests.

Examples and Tests

To view some examples, look at the test programs in the packages:

  • org.bouncycastle.crypto.test

  • org.bouncycastle.jce.provider.test

  • org.bouncycastle.cms.test

  • org.bouncycastle.mail.smime.test

  • org.bouncycastle.openpgp.test

  • org.bouncycastle.tsp.test

There are also some specific example programs for dealing with SMIME and OpenPGP. They can be found in:

  • org.bouncycastle.mail.smime.examples

  • org.bouncycastle.openpgp.examples

Mailing Lists

For those who are interested, there are 2 mailing lists for participation in this project. To subscribe use the links below and include the word subscribe in the message body. (To unsubscribe, replace subscribe with unsubscribe in the message body)

  • [email protected]
    This mailing list is for new release announcements only, general subscribers cannot post to it.
  • [email protected]
    This mailing list is for discussion of development of the package. This includes bugs, comments, requests for enhancements, questions about use or operation.

NOTE: You need to be subscribed to send mail to the above mailing list.

Feedback and Contributions

If you want to provide feedback directly to the members of The Legion then please use [email protected], if you want to help this project survive please consider donating.

For bug reporting/requests you can report issues here on github, or via feedback-crypto if required. We will accept pull requests based on this repository as well, but only on the basis that any code included may be distributed under the Bouncy Castle License.

Finally

Enjoy!

bc-java's People

Contributors

a--v--k avatar artem-smotrakov avatar bifurcation avatar bjpbakker avatar brandonweeks avatar cipherboy avatar dbusche avatar dghgit avatar dheldt avatar flix- avatar franziskuskiefer avatar gnu-user avatar honzaik avatar jwcranford avatar kaoh avatar karolinhem avatar ligefeibouncycastle avatar meganwoods avatar mikesafonov avatar mwcw avatar oh2mqk avatar peterdettman avatar rtyley avatar timw avatar tonywasher avatar trisia avatar vanitasvitae avatar xipki avatar yuhh0328 avatar zzmarquis avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

bc-java's Issues

Certificate factory initialization without provider registered causes new provider

We have noticed since updating to BC 1.5.4 that CertificateFactory now causes new providers to be created if none is registered. This is due to the creation of a new BCJcaJceHelper on every factory instance in 4eecbee.

We use BC to implement an OpenSSL-lookalike API for JRuby. Because of the nasty Security.addProvider dance, and the potential for classloader leaks if we don't unregister, we have tried to avoid registering BC as a provider except when opted into by the user. That has worked ok for us, accessing BC directly as much as possible, but the above change requires that a provider be registered, or every BCJcaJceHelper will construct a new provider.

See jruby/jruby-openssl#94 for the bug on our end.

I'm not sure what the fix is. If a provider is really needed to create a CertificateFactory, and there's no way to pass the provider through the SPI construction process, then there may be no way to avoid it.

If possible, though, it would be great to fix this or come up with an alternative to 4eecbee, since we really don't want to have to use the JDK's crufty registration logic.

Building bcpkix and bcprov sources using Maven

Hello,

I am interested in compiling the source files for bcpkix-jdk15on-1.51-sources and bcprov-jdk15on-1.51-sources myself. I found the corresponding JAR files from these two locations:
http://repo1.maven.org/maven2/org/bouncycastle/bcpkix-jdk15on/1.51/
http://repo1.maven.org/maven2/org/bouncycastle/bcprov-jdk15on/1.51/

What is the best way to compile these source files? I am fairly new to using Maven, but I noticed that the libraries have associated pom.xml files. Would building with these POM files in Eclipse be sufficient for compiling the source files?

Thanks,
Aditya

org.bouncycastle.openpgp.examples.ClearSignedFileProcessor.verifyFile() does not write output in case of a single line clear text section.

Verifying a single line message like the one below using ClearSignedFileProcessor.verifyFile() doesn't save the clear text to the out output stream. This is because the call to readInputLine() [ClearSignedFileProcessor.java:128] switches the ArmoredInputStream's clearText variable to false when it detects the dash on the succeeding line thus the if statement [ClearSignedFileProcessor.java:131] is false and the ByteArrayOutputStream is never saved to disk.

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

This is a test payload!
-----BEGIN PGP SIGNATURE-----
Version: BCPG v1.52

iQFcBAEBAgBGBQJV2zJmPxxPbGEgVGhlYW5kZXIgKENlcnQgZm9yIHVuaXQgdGVz
dGluZykgPG9sYS50aGVhbmRlckBuYXNkYXEuY29tPgAKCRCa4AVZRxMEL7oQCACS
grNJiNRxv8nO42okU9oUJlP1oIebPenTynUzgEtSoLCZ2zjOVQYpC6w6UgRjzcIG
JD/1rv0upTmsi5sgRTEaOp+wkFJ93waYjFCgXTGJM2LfkDo+YZHMDROlekacwire
N3m/cOhTB0hc9pmzd/Vg8NLonXfeVl2LZepkN9nTxMmIodE615OaMa6AhWkVIBuK
iiIAFpN0JKCqtf84rr/vew134Za6qA6AkoG10TDyzes9gIndCqo6GIfBClAsyY3q
TQR5x58liLRdlsX4vhvIdJ0wj8cA5adapN30wEj3MMvNGbAtAgvdXeJ7fPy2tQJo
vOkzOVQo9JWZ/s7hcuTy
=RCyW
-----END PGP SIGNATURE-----

For multi-line clear text verifyFile() works as expected.

missing javadoc

While using bouncy castle in some projects I have discovered that many methods are missing meaningful javadoc documentation. For me javadoc is a valuable and important tool while developing. So using these classes was difficult for me. I am interested in providing pull requests providing additional javadoc documentation.
Would that be ok with you?

At .gitattributes kill all text auto conversions

Some files at the BC source tree have CRLF endings, others have LF, and
probably some plain CR ("DOS", "UNIX", and "MAC" styles); git dares to
presume to know what format I want all my source codes to use.
The result is that it does then claim that because it did autoconversion
during pull, there is now some difference in between the workspace, and
master repository. Only way to restore sanity, and avoid hair loss is
to disable that feature entirely.
(No conversion happens during clone, but do happen during pull.)

How? Comment out (#) all lines with 'text' at the .gitattributes
Sure it will disable fancy diffing too, but sanity is more important.

I am writing this note, as apparently that file at the root of the bc-java source tree is coming from repository, and not created locally.

BC support set key attributes to private key on PKCS#12?

Hi, How to set the key attributes of private key. I can set Bag Attribtes by PKCS12BagAttributeCarrier but I don't find how to set the key attributes.

I can generate "configuration" so:
$> openssl pkcs12 -export -in newcert.pem -inkey newreq.pem -name "MY CERTIFICATE" -certfile demoCA/cacert.pem -out mycert.p12 -keysig

With the last parameter -keysig:

If you supply the keysig option a special attribute is set in the PKCS#12 file and the private key is imported as a signature key link

PKCS7 Data
Shrouded Keybag: pbeWithSHA1And3-KeyTripleDES-CBC, Iteration 1024
Bag Attributes
    friendlyName: 10010
    localKeyID: <...>
    Microsoft CSP Name: Microsoft Software Key Storage Provider  <--- (1)
Key Attributes: <No Attributes>    # <--- put HERE X509v3 Key Usage: 80
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:
-----BEGIN ENCRYPTED PRIVATE KEY-----
...
-----END ENCRYPTED PRIVATE KEY-----

Set the Bag Attribute:

PKCS12BagAttributeCarrier bagAttr = (PKCS12BagAttributeCarrier)privateKey;//pbeWithSHA1And3-KeyTripleDES-CBC
        bagAttr.setBagAttribute(
                MicrosoftObjectIdentifiers.microsoft.branch("17").branch("1"),// this OID corresponds to: 1.3.6.1.4.1.311.17.1
                new DERBMPString("Microsoft Software Key Storage Provider")); /*DERBMPString ("Microsoft Software Key Storage Provider")); */ 

I din't try:

X509v3CertificateBuilder builder =  new JcaX509v3CertificateBuilder(
                issuerDNName, 
                serial,
                startDate, 
                endDate, 
                tX500Name, 
                pubKey);
X509KeyUsage usage = new X509KeyUsage(X509KeyUsage.digitalSignature); 
builder.addExtension(Extension.keyUsage, false, usage); 

or

builder.addExtension(
                new ASN1ObjectIdentifier("2.5.29.15"),
                true,
                new X509KeyUsage(
                   X509KeyUsage.digitalSignature));

but Extension don't work because this is inside of certificate.

Thanks!

Weird ASN.1 data with CMSSignedDataGenerator

Hi,

In a standard PKCS7 signature, generated with BouncyCastle, the ASN.1 signature data seems not perfect.
Some Sequence objects length are always set with a 0x80 (undefined) value.

Everything else is correct, though. The length is well set for every other data type.
If I use the sun.security packages to wrap the Bouncy signature in a PKCS7, every length is well set (same data to sign and same signature certificate) :
http://img11.hostingpics.net/pics/479305bouncy.png (Boucy)
http://img15.hostingpics.net/pics/803744sun.png (sun.security)

OpenSSL seems to have a hard time reading a p7s generated without these valid lengths.
The verification is successful using Bouncy or Spongy libraries, but fails with OpenSSL.
The Iaik PKCS#7 wrapper get its lengths right too.

So I sign with Bouncy and wraps with Sun, it do the trick.
But this CMSSignedDataGenerator would be useful on Android, or any other Sun-free JVM.

[ASN.1] No support for writing PRIVATE tag

PRIVATE tags are are mapped into DERApplicationSpecific object so write ASN.1 bytes are differen

example
i have ASN.1 : C00474657374
ByteArrayInputStream asnPrivateTag = new ByteArrayInputStream(Hex.decode("C00474657374"));
ASN1Primitive asn1Primitive = new ASN1InputStream(asnPrivateTag).readObject();
ByteArrayOutputStream outputAsn = new ByteArrayOutputStream();
new ASN1OutputStream(outputAsn).writeObject(asn1Primitive);
After write to output stream i got ASN.1 : 400474657374

VMPCMAC update method code error

Code is:
public void update(byte[] in, int inOff, int len)
throws DataLengthException, IllegalStateException
{
if ((inOff + len) > in.length)
{
throw new DataLengthException("input buffer too short");
}

    for (int i = 0; i < len; i++)
    {
        update(in[i]);
    }
}

Note that
update(in[i]);
should be
update(in[inOff + i]);

(D)TLS certificate_verify signature never checked

TLSServerProtocol and DTLSServerProtocol process the certificate_verify message. They verify the signature generated by the client and should, in my understanding, throw an error if the signature is not correct.

Currently the return value of the verifyRawSignature call is not evaluate at all:

// Verify the CertificateVerify message contains a correct signature.
 try
 {
    // TODO For TLS 1.2, this needs to be the hash specified in the DigitallySigned
    byte[] certificateVerifyHash = getCurrentPRFHash(getContext(), prepareFinishHash, null);

     org.bouncycastle.asn1.x509.Certificate x509Cert = this.peerCertificate.getCertificateAt(0);
     SubjectPublicKeyInfo keyInfo = x509Cert.getSubjectPublicKeyInfo();
     AsymmetricKeyParameter publicKey = PublicKeyFactory.createKey(keyInfo);

     TlsSigner tlsSigner = TlsUtils.createTlsSigner(this.clientCertificateType);
     tlsSigner.init(getContext());
     tlsSigner.verifyRawSignature(clientCertificateVerify.getAlgorithm(),
         clientCertificateVerify.getSignature(), publicKey, certificateVerifyHash);
 }
 catch (Exception e)
 {
     throw new TlsFatalAlert(AlertDescription.decrypt_error);
 }

Will you ever make a Python version of BouncyCastle ?

Hello dear team,

The problem is simple: really, there's no great crypto lib in Python. I don't mean to be rude to anyone or make waves but they all have serious limitations. If you need a short example: try to find a lib with PKCS12 version of PBKDF.

The question is simple (and I guess not brand new): will you ever make a Python version of BouncyCastle or at least provide bindings ?

Cheers!

Possible error at example method

Trying ty compile method readSecretKey from this example class I get the following error:
Error: java: incompatible types: java.io.InputStream cannot be converted to java.lang.String
that relates to this line of code:
PGPSecretKey secKey = readSecretKey(keyIn);
I'm using this bouncy castle version org.bouncycastle:bcpg-jdk14:1.50
Is it possible there is a mistake in the code?

Non-blocking TlsProtocol accepts non-TLS data

With 1.54 I wrote a TLS server that offers received data directly to BC TLS protocol via TlsProtocol.offerInput(byte[]). I connected via Telnet and hit random keys on my keyboard. The connection was not terminated, though. It seems BC TLS protocol simply accepted all my non-TLS data.

I had a look at the code of BC TLS protocol. I guess the bytes I sent resulted in a negative number with TlsUtils.readUint16(byte[], int). Neither TlsUtils, nor TlsProtocol check the calculated record length to be reasonable.

I suggest there should be some kind of check the received input data matches the TLS standard.

Safe Curves

Hi all,

I wonder if anyone thought about implementing some of the safe curves for ECC (cf. http://safecurves.cr.yp.to/)? I noticed there's currently no Java implementation for any of them (despite WhisperSystems curve25519, which is GPLv3). If this is not on anyone's agenda, I might give it a try when I find some time.

Remove the order and cofactor from ECCurve.F2m

ECCurve.F2m includes the order n and cofactor h. These don't make sense without the base point G and are not part of ECurve.Fp. I'd suggest removing them from ECCurve.F2m and making sure that the code always uses the order and cofactor from ECDomainParameters.

TLSServerProtocol: NullPointerException when first read attempt fails

Happens in case of SSLv3 connections and if nothing or garbage is sent to the server socket.
java.lang.NullPointerException
at org.bouncycastle.crypto.tls.TlsUtils.writeVersion(TlsUtils.java:652)
at org.bouncycastle.crypto.tls.RecordStream.writeRecord(RecordStream.java:276)
at org.bouncycastle.crypto.tls.TlsProtocol.safeWriteRecord(TlsProtocol.java:484)
at org.bouncycastle.crypto.tls.TlsProtocol.raiseAlert(TlsProtocol.java:683)
at org.bouncycastle.crypto.tls.TlsProtocol.failWithError(TlsProtocol.java:629)
at org.bouncycastle.crypto.tls.TlsProtocol.safeReadRecord(TlsProtocol.java:457)
at org.bouncycastle.crypto.tls.TlsProtocol.completeHandshake(TlsProtocol.java:148)
at org.bouncycastle.crypto.tls.TlsServerProtocol.accept(TlsServerProtocol.java:63)
...

I'm using version 1.50.

Fatal alert should terminate DTLS connection

RFC 4346 - 7.2.2. Error Alerts

Error handling in the TLS Handshake protocol is very simple. When an
error is detected, the detecting party sends a message to the other
party. Upon transmission or receipt of a fatal alert message, both
parties immediately close the connection. Servers and clients MUST
forget any session-identifiers, keys, and secrets associated with a
failed connection. Thus, any connection terminated with a fatal
alert MUST NOT be resumed.

However, in DTLSRecordLayer.java receive() method:

            switch (type)
            {
            case ContentType.alert:
            {
                if (plaintext.length == 2)
                {
                    short alertLevel = plaintext[0];
                    short alertDescription = plaintext[1];

                    peer.notifyAlertReceived(alertLevel, alertDescription);

                    if (alertLevel == AlertLevel.fatal)
                    {
                        fail(alertDescription);
                        throw new TlsFatalAlert(alertDescription);
                    }

                    // TODO Can close_notify be a fatal alert?
                    if (alertDescription == AlertDescription.close_notify)
                    {
                        closeTransport();
                    }
                }

                continue;
            }

The call to fail() tries to send an alert back to the peer before calling closeTransport(). I think in the case of a generic fatal alert, it should just call closeTransport() immediately and clean up whatever other session state remains. I think it's only the special case of close_notify that needs a special "close handshake" as described in section 7.2.1.

Problem with CMAC

Your update method is flawed:
If len is equal to the cipher block size, the first block will not be processed, but is buffered and overwritten on the next block cycle.
To verify this, step through the public void update(byte[] in, int inOff, int len) method, using an array that is a multiple of the ciphers block size (ex. 64 bytes), using the block size (16 bytes) as the len argument to the method. Remember that each block must be processed by the cipher to the mac code. With your method, the first block is copied, then when the next block is processed, it is immediately overwritten, without ever having been run through the cipher.

Here are my own routines (C#) for these methods, you should be able to extrapolate correct methods:

    public void BlockUpdate(byte[] Input, int InOffset, int Length)
    {
        if ((InOffset + Length) > Input.Length)
            throw new CryptoMacException("CMAC:BlockUpdate", "The Input buffer is too short!", new ArgumentOutOfRangeException());

        if (_wrkOffset == _blockSize)
        {
            _cipherMode.Transform(_wrkBuffer, 0, _msgCode, 0);
            _wrkOffset = 0;
        }

        int diff = _blockSize - _wrkOffset;
        if (Length > diff)
        {
            Buffer.BlockCopy(Input, InOffset, _wrkBuffer, _wrkOffset, diff);
            _cipherMode.Transform(_wrkBuffer, 0, _msgCode, 0);
            _wrkOffset = 0;
            Length -= diff;
            InOffset += diff;

            while (Length > _blockSize)
            {
                _cipherMode.Transform(Input, InOffset, _msgCode, 0);
                Length -= _blockSize;
                InOffset += _blockSize;
            }
        }

        if (Length > 0)
        {
            Buffer.BlockCopy(Input, InOffset, _wrkBuffer, _wrkOffset, Length);
            _wrkOffset += Length;
        }
    }

    public int DoFinal(byte[] Output, int OutOffset)
    {
        if (Output.Length - OutOffset < _macSize)
            throw new CryptoMacException("CMAC:DoFinal", "The Output buffer is too short!", new ArgumentOutOfRangeException());

        if (_wrkOffset != _blockSize)
        {
            ISO7816 pad =  new ISO7816();
            pad.AddPadding(_wrkBuffer, _wrkOffset);
            for (int i = 0; i < _msgCode.Length; i++)
                _wrkBuffer[i] ^= _K2[i];
        }
        else
        {
            for (int i = 0; i < _msgCode.Length; i++)
                _wrkBuffer[i] ^= _K1[i];
        }

        _cipherMode.Transform(_wrkBuffer, 0, _msgCode, 0);
        Buffer.BlockCopy(_msgCode, 0, Output, OutOffset, _macSize);
        Reset();

        return _macSize;
    }

Duplicate classes in bcpg and bcprov

bcpg should not define these classes since they're also available in its dependency bcprov

[WARNING] bcprov-jdk15on-1.50.jar, bcpg-jdk15on-1.50.jar define 3 overlappping classes: 
[WARNING]   - org.bouncycastle.apache.bzip2.CBZip2InputStream
[WARNING]   - org.bouncycastle.apache.bzip2.CRC
[WARNING]   - org.bouncycastle.apache.bzip2.BZip2Constants

X509v3CertificateBuilder always uses UTCTime

I'm copying certificates with BC and all is fine except for one small detail: the way date type is chosen to be UTCTime for "current" times and GeneralizedTime otherwise.

The "input" certificates for me always use Generalized time. It would be nice if this could be overwritten somehow (or a new constructor added that would take asn1 representation instead of java Date.

Here's the code:
https://github.com/martinpaljak/esteidhacker/blob/master/src/esteidhacker/FakeEstEIDCA.java

Remove support for Dual_EC_DRBG

Dual_EC_DRBG is suspected by cryptography researchers to contain a backdoor. For example, NIST retracted support on 2014-04-21 and urged users to transition to a different PRNG.

It would be wise to remove Dual_EC_DRBG from BouncyCastle, if only to prevent accidental use of this mistrusted algorithm.

First DH keypair generation takes too long

Tested with bcprov-jdk15on versions 1.54 and 1.55b12 on MacOSx 10.10.5.

Here the code:

Security.addProvider(new BouncyCastleProvider());
KeyPairGenerator kpGen = KeyPairGenerator.getInstance("DH", "BC");
kpGen.initialize(1024, new SecureRandom());

for (int i = 0; i < 5; i++) {
long start = System.currentTimeMillis();
kpGen.generateKeyPair();
long end = System.currentTimeMillis();
System.out.println("round " + (i + 1) + ": " + (end - start) + " ms");
}

and the ouput

round 1: 56200 ms
round 2: 3 ms
round 3: 3 ms
round 4: 3 ms
round 5: 2 ms

Fatal alert does not interrupt handshake

This issue is related to #147 and #148 .

Some tests revealed that when a decrypt error happens here https://github.com/bcgit/bc-java/blob/master/core/src/main/java/org/bouncycastle/crypto/tls/DTLSRecordLayer.java#L217 a fatal alert is generated closing transport and throwing a TlsFatalAlert exception here https://github.com/bcgit/bc-java/blob/master/core/src/main/java/org/bouncycastle/crypto/tls/DTLSRecordLayer.java#L247 .

Since this exception seems to be ignored by DTLSReliableHandshake as verified here https://github.com/bcgit/bc-java/blob/master/core/src/main/java/org/bouncycastle/crypto/tls/DTLSReliableHandshake.java#L210 , only one of two nested loops (see #147) is interrupted, and the external loop goes on.

As described in #148 , once a fatal occurs this flow must be interrupted.

A PKCS7 SignedData can't be validated

I have a pkcs7 SignedData(see my attachment), it can't be validated by Bouncy Castle with follow code:

//load data from my attached file
FileInputStream file = new FileInputStream("SignedData.bin.txt");
ByteArrayOutputStream out = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int length;
while((length = file.read(buffer)) > 0)
{
  out.write(buffer, 0, length);
}
out.flush();
byte[] encapSigData = out.toByteArray();
out.close();

//validate the SignedData             
CMSSignedDataParser     sp = new CMSSignedDataParser(new JcaDigestCalculatorProviderBuilder().setProvider("BC").build(), encapSigData);

sp.getSignedContent().drain();

Store                   certStore = sp.getCertificates();
SignerInformationStore  signers = sp.getSignerInfos();

Collection              c = signers.getSigners();
Iterator                it = c.iterator();

while (it.hasNext())
{
  SignerInformation   signer = (SignerInformation)it.next();
  Collection          certCollection = certStore.getMatches(signer.getSID());

  Iterator        certIt = certCollection.iterator();
  X509CertificateHolder cert = (X509CertificateHolder)certIt.next();

  System.out.println("verify returns: " + signer.verify(new JcaSimpleSignerInfoVerifierBuilder().setProvider("BC").build(cert)));
}    

Exception occurred at CMSSignedDataParser constructor:

java.lang.ClassCastException: org.bouncycastle.asn1.DERSequenceParser cannot be cast to org.bouncycastle.asn1.ASN1OctetStringParser
at org.bouncycastle.cms.CMSSignedDataParser.<init>(Unknown Source)
at org.bouncycastle.cms.CMSSignedDataParser.<init>(Unknown Source)
at org.bouncycastle.cms.CMSSignedDataParser.<init>(Unknown Source)

After some analysis, I find that the content of contentInfo in SignedData is a Sequence. It seems that bouncycastle can't accept a Sequence to be the content.

More details in stackoverflow: http://stackoverflow.com/questions/34197756/validate-pkcs7-signeddata-by-bouncy-castle-in-java

SignedData.bin.txt

Inconsistency of ECIES-KEM SingleHashMode with respect to ISO/IEC 18033-2

There is an inconsistency in the semantics of the SingleHashMode parameter of ECIES-KEM with respect to the original ISO/IEC 18033-2 standard.

In the standard, when this parameter is active ("SingleHashMode = 1"), the encryption and decryption procedures don't include the ephemeral public key (denoted by C_0 in the standard) as part of the input to the KDF. This parameter is set to 0 for improved security.

However, the behavior in the BC implementation is the opposite. When SingleHashMode is active ("SingleHashMode == true"), the ephemeral public key (denoted by C in the BC implementation) is inputed to the KDF. In addition, the default value when this parameter is not specified in the constructor is false, which is equivalent to "SingleHashMode = 1" in the standard.

See:
https://github.com/bcgit/bc-java/blob/master/core/src/main/java/org/bouncycastle/crypto/kems/ECIESKeyEncapsulation.java#L231

Infinite loop in DTLSReliableHandshake receiveMessage() method

If recordLayer.receive() returns -1 (for example, if the underlying transport has been closed), the code never breaks out of the outer for and loops infinitely, eventually re-trying to infinity with a 1-minute retry period. The DTLS spec is unclear about what to do when the re-transmission ceiling is surpassed - presumably it should abort?

    for (;;)
    {
        int receiveLimit = recordLayer.getReceiveLimit();
        if (buf == null || buf.length < receiveLimit)
        {
            buf = new byte[receiveLimit];
        }

        // TODO Handle records containing multiple handshake messages

        try
        {
            for (; ; )
            {
                int received = recordLayer.receive(buf, 0, receiveLimit, readTimeoutMillis);
                if (received < 0)
                {
                    break;
                }

If breaking out of the outer for-loop and aborting is the correct thing to do, I'm happy to fix this and submit a pull request.

[junit] Test org.bouncycastle.cms.test.AllTests FAILED

Today's Github version of BC fails CMS and I18N tests. I'm concerned of the CMS failure.

  • Name: testOpenSSLVectors
  • Status: Error
  • Type: N/A
java.lang.NullPointerException
at java.io.Reader.<init>(Reader.java:78)
at java.io.InputStreamReader.<init>(InputStreamReader.java:72)
at org.bouncycastle.cms.test.NewEnvelopedDataTest.testOpenSSLVectors(Unknown Source)
at junit.extensions.TestDecorator.basicRun(TestDecorator.java:23)
at junit.extensions.TestSetup$1.protect(TestSetup.java:23)
at junit.extensions.TestSetup.run(TestSetup.java:27)

bc-fails-opensslvectors

Broken Logic in master:core/src/main/java/org/bouncycastle/crypto/engines/RFC5649WrapEngine.java

I just spent better half of a day trying to figure out why this doesn't work. Under unwrap(byte[] in, int inOff, int inLen) [Line 184-186] A comment actually does state // Otherwise, unwrap as per RFC 3394 but don't check IV the same way. But the code then proceeds to check the IV the same way.

There exists an engine to handle this RFC3394WrapEngine.java under the same package, please use that instead of continuing out of the else statement.

bc maven release is not debug-able

when creating the .jar, all debug infos has been removed. its impossible to debug any project which uses bc in netbeans, it says debug informations has been removed. source is installed with maven - never have seen this before in any other project, so i am pretty sure it must be some wierd pom/maven action which removes this information.

netbeans complains this:
Thread main stopped at org.bouncycastle.... -
compiled without debug info.

GF2mField.exp(0,0) incorrect result

The first lines of org.bouncycastle.pqc.math.linearalgebra.GF2mField.exp() are "if (a == 0) { return 0; }" but I believe the rule that k == 0 --> a^k == 1 for all a even applies when a == 0.

Perhaps there are few algorithms that would normally call exp with a==0 so it may rarely or never cause a problem, but it seems safest to make sure it's correct.

Originally caught while testing a different GF256 implementation by comparing it to GF2mField (Archistar/archistar-smc#23).

Provide Strings for CipherSuites (to match SSLSocketFactory requirements)

When one wants to create a custom SSLSocketFactory, two of the methods one must implement are:

    @Override
    public String[] getDefaultCipherSuites()
    {
    }

    @Override
    public String[] getSupportedCipherSuites()
    {
    }

Given that this is the default way to create a SSLSocketFactory in Java (and one needs to do so in order to do things like monitor SSL connections made by the program running on the JVM) it would be more convenient if CipherSuites.java included not only the ints that they do now, but the names as Strings.

Let me know what you think - I can send a PR if necessary.

(D)TLS 1.2 certificate_verify hashing algorithm not correctly determined

There is a TODO which states that the hashing algorithm needs to be taken from the DigitallySigned structure, but the way it is currently implemented it is not verifiable in any case using TLS1.2.
I attached the diff to make it DTLS1.2 compatible, but have not verified if the existing code is compatible with versions lower DTLS1.2

index c78cb95..8ac08c8 100644
--- a/core/src/main/java/org/bouncycastle/crypto/tls/DTLSServerProtocol.java
+++ b/core/src/main/java/org/bouncycastle/crypto/tls/DTLSServerProtocol.java
@@ -478,8 +478,14 @@ protected void processCertificateVerify(ServerHandshakeState state, byte[] body,
         // Verify the CertificateVerify message contains a correct signature.
         try
         {
-            // TODO For TLS 1.2, this needs to be the hash specified in the DigitallySigned
-            byte[] certificateVerifyHash = TlsProtocol.getCurrentPRFHash(state.serverContext, prepareFinishHash, null);
+           byte[] certificateVerifyHash;
+           
+            // TODO Cross check with specification
+           if(TlsUtils.isTLSv12(state.serverContext)){
+               certificateVerifyHash = prepareFinishHash.getFinalHash(clientCertificateVerify.algorithm.getHash());
+           } else {        
+               certificateVerifyHash = TlsProtocol.getCurrentPRFHash(state.serverContext, prepareFinishHash, null);
+           }

             org.bouncycastle.asn1.x509.Certificate x509Cert = state.clientCertificate.getCertificateAt(0);
             SubjectPublicKeyInfo keyInfo = x509Cert.getSubjectPublicKeyInfo();

ec.AlgorithmParametersSpi should handle ECNamedCurveSpec

The class org.bouncycastle.jcajce.provider.asymmetric.ec.AlgorithmParametersSpi not differing java.security.spec.ECParameterSpec and org.bouncycastle.jce.spec.ECNamedCurveSpec in the engineInit(AlgorithmParameterSpec algorithmParameterSpec).

Today it is

else if (algorithmParameterSpec instanceof ECParameterSpec)
{
curveName = null;
ecParameterSpec = (ECParameterSpec)algorithmParameterSpec;
}

I think it should be

else if (algorithmParameterSpec instanceof ECParameterSpec)
{
if (algorithmParameterSpec instanceof ECNamedCurveSpec) {
curveName = ((ECNamedCurveSpec) algorithmParameterSpec).getName();
} else {
curveName = null;
}
ecParameterSpec = (ECParameterSpec)algorithmParameterSpec;
}

Unexpected behavior in `getPublicKey()` when provider not loaded

I had an insidious bug which needed much debugging… creating a small program to reproduce it I finally discovered… well, I forgot to instantiate new BouncyCastleProvider.
I guess this is in the area of «well duh, you didn't properly initialize it, of course it doesn't work properly», but problem is, generating a certificate (or even loading it from DER) generates an almost-fully-functional X509CertificateObject except that getPublicKey() silently returns null.

This ultimately happens because BouncyCastleProvider.getPublicKey(spki) happily returns null for any unknown public key type which is always the case when not properly initialized, as keyInfoConverters is a static variable… but it is initialized in the constructor.

I think that, for clarity (and/or coherence), it should be changed to either be an instance variable initialized in the constructor or a static variable initialized at first usage (or even statically), which would probably generate a working X509CertificateObject or, maybe, change getPublicKey and getPrivateKey to throw new RuntimeEception("BouncyCastleProvider was never initialized") instead of silently returning null so that the error is easy to debug.

RSA KeyFactorySpi always produces BCRSAPrivateCrtKey

I ran into the same problem as this guy.

I tried to load an UBER KeyStore that contains a certificate and use that certificate's private key to sign a new certificate. This results in a "BigInteger divide by zero" exception because UBER always returns a BCRSAPrivateCrtKey when reading an RSA private key, even if none of the CRT values are set.

Abridged code:

KeyStore rootCAStore = KeyStore.getInstance("UBER");
rootCAStore.load(Files.newInputStream(rootCAPath), rootStorePassword);

PrivateKey rootCAPrivateKey = (PrivateKey) rootCAStore.getKey("root", rootStorePassword);

JcaX509v3CertificateBuilder certBuilder = ...
JcaContentSignerBuilder signerBuilder = new JcaContentSignerBuilder("SHA256withRSA").setProvider(BC);

X509CertificateHolder certHolder = certBuilder.build(signerBuilder.build(rootCAPrivateKey));

The exception occurs at the last line.

Non-blocking TLS and DTLS implementations

BouncyCastle's support for TLS and DTLS is currently limited to use with "old" blocking I/O. This makes it difficult (maybe impossible) to use BC with non-blocking NIO frameworks like Netty.

It would be very useful if BC provided a NIO API, ideally through an SSLEngine implementation.

Side note: it appears I'm not the first person looking for NIO support. See this e-mail on the BC dev mailing list.

Discrepancy to FIPS-186-4 for Shawe-Taylor Random Prime Generation

FIPS 186-4 C.6 Shawe-Taylor Random_Prime Routine states in step 14. that for the recursive call the INPUTSEED shall be used.
The Bouncycastle implementation uses the PRIMESEED in Routine implSTRandomPrime() in org.bouncycastle.math.Primes.java

https://github.com/bcgit/bc-java/blob/adecd89d33edf278a5c601af2de696f0a6f65251/core/src/main/java/org/bouncycastle/math/Primes.java
Line 503:
return new STOutput(BigInteger.valueOf(c64), primeSeed, primeGenCounter);

Could that be a mistake in the FIPS-186-4 Standard? (I believe it is) The primeSeed seems to be the better choice since it is altered for each recurive call. The path for primes < 32 Bits results in the same hashes using the input seed, therefore all generated 32 Bit primes are equal. This is potentially problematic for the quality of the final prime number

The test in the example of openpgp cannot pass.

bc-java/pg/src/test/java/org/bouncycastle/openpgp/examples/test/AllTests.java

testDSAElGamaleKeyGeneration() fails!!

commit: 9884183


org.bouncycastle.openpgp.PGPException: invalid key: Illegal key size or default parameters
at org.bouncycastle.openpgp.operator.jcajce.JcePBESecretKeyEncryptorBuilder$1.encryptKeyData(Unknown Source)
at org.bouncycastle.openpgp.operator.PBESecretKeyEncryptor.encryptKeyData(Unknown Source)
at org.bouncycastle.openpgp.PGPSecretKey.(Unknown Source)
at org.bouncycastle.openpgp.PGPSecretKey.(Unknown Source)
at org.bouncycastle.openpgp.PGPKeyRingGenerator.(Unknown Source)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.