Skip to content

The BcKeyBox class incorrectly treats EMPTY_BLOB as EOF #2343

Description

@Patrick-Harms

Environment

Bouncy Castle 1.84
Java 17
GnuPG 2.4.8

Problem

A valid Keybox file containing:

Header
OpenPGP
OpenPGP
OpenPGP
EMPTY_BLOB
OpenPGP

Returns only 3 KeyBlobs using the Bouncy Castle org.bouncycastle.gpg.keybox.bc.BcKeyBox class , e.g. a standalone test class:

Parsing Keybox file 'C:\Test\pubring.kbx' using Bouncy Castle library.
Creating BcKeyBox object from the Keybox file
BcKeyBox object created
FirstBlob Blob type 'FIRST_BLOB' (1)
FirstBlob Version '1'
FirstBlob Header flags '2'
FirstBlob File created at '1970/01/22 01:21:45.823'
FirstBlob Last maintenance run '1970/01/22 01:21:45.823'
FBcKeyBox object has '3' KeyBlob objects.
BcKeyBox KeyBlob[0] 'OPEN_PGP_BLOB' (2)
BcKeyBox BcKeyBox KeyBlob[0] is an OpenPGP BLOB type.
BcKeyBox BcKeyBox KeyBlob[0] Blob created at '1970/01/22 01:21:45.826'
BcKeyBox BcKeyBox KeyBlob[0] 1871 key bytes, 0 reserve bytes, 20 checksum bytes .
BcKeyBox BcKeyBox KeyBlob[0] has '1' userids.
BcKeyBox BcKeyBox KeyBlob[0]:Userid[0] 'Test User 1 Key 1 <TestUser1Key1@doesnotexist.com>' .
BcKeyBox BcKeyBox KeyBlob[0] has '2' keys.
BcKeyBox BcKeyBox KeyBlob[0]:KeyInformation[0] KeyId '13803E3BC2846892', Key Flags '0', Fingerprint '9CBA92833D8F336C70BACDEB13803E3BC2846892' .
BcKeyBox BcKeyBox KeyBlob[0]:KeyInformation[1] KeyId 'F316642B1748E04F', Key Flags '0', Fingerprint '584491449B1AE28DC4D30291F316642B1748E04F' .
BcKeyBox KeyBlob[1] 'OPEN_PGP_BLOB' (2)
BcKeyBox BcKeyBox KeyBlob[1] is an OpenPGP BLOB type.
BcKeyBox BcKeyBox KeyBlob[1] Blob created at '1970/01/22 01:21:45.839'
BcKeyBox BcKeyBox KeyBlob[1] 1871 key bytes, 0 reserve bytes, 20 checksum bytes .
BcKeyBox BcKeyBox KeyBlob[1] has '1' userids.
BcKeyBox BcKeyBox KeyBlob[1]:Userid[0] 'Test User 1 Key 2 <TestUser1Key2@doesnotexist.com>' .
BcKeyBox BcKeyBox KeyBlob[1] has '2' keys.
BcKeyBox BcKeyBox KeyBlob[1]:KeyInformation[0] KeyId '4F661F91439B942A', Key Flags '0', Fingerprint 'D3F787152D34606523642A1B4F661F91439B942A' .
BcKeyBox BcKeyBox KeyBlob[1]:KeyInformation[1] KeyId 'A797A52BDB50D8F1', Key Flags '0', Fingerprint 'E3DC0A7BF9BF1F9A975D67ECA797A52BDB50D8F1' .
BcKeyBox KeyBlob[2] 'OPEN_PGP_BLOB' (2)
BcKeyBox BcKeyBox KeyBlob[2] is an OpenPGP BLOB type.
BcKeyBox BcKeyBox KeyBlob[2] Blob created at '1970/01/22 01:21:45.851'
BcKeyBox BcKeyBox KeyBlob[2] 1871 key bytes, 0 reserve bytes, 20 checksum bytes .
BcKeyBox BcKeyBox KeyBlob[2] has '1' userids.
BcKeyBox BcKeyBox KeyBlob[2]:Userid[0] 'Test User 1 Key 3 <TestUser1Key3@doesnotexist.com>' .
BcKeyBox BcKeyBox KeyBlob[2] has '2' keys.
BcKeyBox BcKeyBox KeyBlob[2]:KeyInformation[0] KeyId 'D3E519BE61587D81', Key Flags '0', Fingerprint '2F31CC6AA2546363AEF553F0D3E519BE61587D81' .
BcKeyBox BcKeyBox KeyBlob[2]:KeyInformation[1] KeyId '853F8425B8968D2B', Key Flags '0', Fingerprint '640C69526B4207C5C4B4AE7A853F8425B8968D2B' .
Keybox file contains '3' KeyRings

Whereas gpg --list-keys returns four public keys:

c:\Test>gpg --list-keys
c:\Test>pubring.kbx
--------------------------------------------------------
pub   rsa2048 2026-07-06 [SCE] [expires: 2035-01-01]
      9CBA92833D8F336C70BACDEB13803E3BC2846892
uid           [ultimate] Test User 1 Key 1 <TestUser1Key1@doesnotexist.com>
sub   rsa3072 2026-07-06 [SEA] [expires: 2035-01-01]

pub   rsa2048 2026-07-06 [SCE] [expires: 2035-01-01]
      D3F787152D34606523642A1B4F661F91439B942A
uid           [ultimate] Test User 1 Key 2 <TestUser1Key2@doesnotexist.com>
sub   rsa3072 2026-07-06 [SEA] [expires: 2035-01-01]

pub   rsa2048 2026-07-06 [SCE] [expires: 2035-01-01]
      2F31CC6AA2546363AEF553F0D3E519BE61587D81
uid           [ultimate] Test User 1 Key 3 <TestUser1Key3@doesnotexist.com>
sub   rsa3072 2026-07-06 [SEA] [expires: 2035-01-01]

pub   rsa2048 2026-07-06 [SCE] [expires: 2035-01-01]
      110289B7771CCC91A8FB0A01C6B5E733322021EB
uid           [ unknown] Test User 2 Key 2 <TestUser2Key2@doesnotexist.com>
sub   rsa3072 2026-07-06 [SEA] [expires: 2035-01-01]

c:\Test>gpg --list-keys --with-colons | find /c "pub:"
4

Writing a second standalone test class, that reads it with raw Java read methods, returns this:

  0  offset=       0  length=      32  type=1 HEADER    version=1
  1  offset=      32  length=    2017  type=2 OPENPGP   version=1
  2  offset=    2049  length=    2017  type=2 OPENPGP   version=1
  3  offset=    4066  length=    2017  type=2 OPENPGP   version=1
  4  offset=    6083  length=    2017  type=0 EMPTY     version=1
  5  offset=    8100  length=    2017  type=2 OPENPGP   version=1

ChatGPT, has identified the issue in the Blob.getInstance() class/method, it treats EMPTY_BLOB like EOF:

case EMPTY_BLOB:
    break;

...

return null;

I have Zipped and attached the replicated issue test Keybox file.

pubring.zip

Can this please be fixed.

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions