Skip to content

Conversation

@vanitasvitae
Copy link
Contributor

Hey!

I did run junit-jazzer agains some PGPainless functions and uncovered some bugs in the bcpg codebase.

The commits in this PR harmonize the way malformed or strange packets are handled, by preventing runtime exceptions, such as IndexOutOfBounds, NegativeArraySize, IllegalArgumentExceptions and OutOfMemory errors.

I'm only just getting started with fuzzing, but I can highly recommend it!

This is a dedicated exception type that is thrown for malformed OpenPGP packets
…edPacketException for malformed packets with unexpected kdf parameter length
…ng subpacket parsing as MalformedPacketException
…rmed fingerprint lengths as MalformedPacketException
…known AEAD algorithm as MalformedPacketException
…nction in ECDHPublicBCPGKey) as MalformedPacketException
@ligefeiBouncycastle ligefeiBouncycastle self-requested a review July 13, 2025 23:59
@ligefeiBouncycastle
Copy link
Collaborator

Hi @vanitasvitae,
Thanks for your valuable PR in hardening the PGP packet handling against malformed inputs. Your fuzzing work is much appreciated.

Regarding the UserAttributeSubpacketInputStream.MAX_LEN setting (currently 5MB):

  • We should revisit this limit – a prior fix in the C# library (PR #638) encountered a similar issue where packet lengths could theoretically reach 4,082,119,084 bytes (~3.8GB). The resolution there set the max to 2³⁰ bytes (1,073,741,824 bytes)

@vanitasvitae
Copy link
Contributor Author

Personally I think 2^30 is still unreasonable (or at least unrealistic :D), but its still an improvement over the current 2^64 :D

Is it okay, if I leave it as a public static int such that applications can overwrite this value if needed?
Is there a configuration mechanism I could perhaps reuse? I think I saw something done with Properties at some other place in the code?

@ligefeiBouncycastle
Copy link
Collaborator

ligefeiBouncycastle commented Jul 15, 2025

While 2³⁰ bytes (~1GB) still feels excessive for real-world use cases, it’s a practical upper bound and certainly more sane than the 2⁶⁴ max.

I updated the logic in UserAttributeSubpacketInputStream.readPacket() to check StreamUtil.flag_eof before evaluating bodyLen, since a true flag_eof may validly result in a bodyLen of -1. This avoids potential false positives when handling EOF-flagged packets.

Thank you.

@peterdettman
Copy link
Collaborator

Please do not add mutable statics. If some limit is warranted here, use org.bouncycastle.util.Properties class for configuration.

However limit checking should begin at the top/outermost level with a constraint on the total size of the input. Low-level classes could be optimized to spot that their length is greater than the remaining limit. It looks like SignatureSubpacketInputStream started to head in that direction.

v3 and earlier OpenPGP keys can only use RSA as key algorithm.
This commit changes the behavior of BC to throw a PGPException instead of a ClassCastException when
encountering a malformed key.
…ESK/SEIPD/OED

packet combinations and rethrow as MalformedPacketException
@vanitasvitae vanitasvitae force-pushed the fuzzHardening branch 2 times, most recently from 83f35f7 to ade1c0c Compare August 25, 2025 20:27
Copy link
Contributor

@dghgit dghgit Sep 14, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible to catch and rethrow inside PGPEncryptedDataList? It would be "less surprising" amongst other things if that could be done.

Also, I've left PGPTrust as it is, wasn't quite sure what was going on. Have added the others.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bobyLen checks should be after flag checks, have moved.

@dghgit dghgit self-assigned this Sep 14, 2025
hubot pushed a commit that referenced this pull request Sep 14, 2025
mj-vivavis added a commit to mj-vivavis/bc-java that referenced this pull request Nov 10, 2025
* 1.82: (1360 commits)
  partial addition of Java25 support
  removed overlap check (unsafe)
  minor compatibility fixes.
  minor compatibility fixes. updated to 1.82.
  Pqc hqc update v5
  removed unnecessary public "internal" method.
  updated from PR list
  updated with current 1.82 PRs and bug fixes
  added PQC sigs
  further clean up of old algorithm names
  added named PREHASH algorithms - relates to github bcgit#2162 cleaned up algorithm list for composites.
  Added publish.gradle stub
  added purpose check, marked deprecated method
  corrected CertPath issue - relates to github bcgit#2152
  set name of artifact to bc-<version>-bom
  fixed probable null pointer issue - relates to github bcgit#1907
  merge of github bcgit#2123 with minor corrections
  error prone fix.
  added parameter setting to allow for pre-hash calculation - relates to github bcgit#2162
  removed use of deprecated class
  ...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants