33import java .io .IOException ;
44import java .math .BigInteger ;
55
6+ import org .bouncycastle .util .BigIntegers ;
7+
68/**
79 * a multiple precision integer
810 */
911public class MPInteger
1012 extends BCPGObject
1113{
12- BigInteger value = null ;
13-
14- public MPInteger (
15- BCPGInputStream in )
16- throws IOException
14+ private final BigInteger value ;
15+
16+ public MPInteger (BCPGInputStream in ) throws IOException
1717 {
18- int length = StreamUtil .read2OctetLength (in );
19- byte [] bytes = new byte [(length + 7 ) / 8 ];
20-
21- in .readFully (bytes );
22-
23- value = new BigInteger (1 , bytes );
18+ /*
19+ * TODO RFC 9580 3.2. When parsing an MPI in a version 6 Key, Signature, or Public Key Encrypted
20+ * Session Key (PKESK) packet, the implementation MUST check that the encoded length matches the
21+ * length starting from the most significant non-zero bit; if it doesn't match, reject the packet as
22+ * malformed.
23+ */
24+ boolean validateLength = false ;
25+
26+ this .value = readMPI (in , validateLength );
2427 }
25-
26- public MPInteger (
27- BigInteger value )
28+
29+ public MPInteger (BigInteger value )
2830 {
2931 if (value == null || value .signum () < 0 )
3032 {
@@ -33,27 +35,31 @@ public MPInteger(
3335
3436 this .value = value ;
3537 }
36-
38+
3739 public BigInteger getValue ()
3840 {
3941 return value ;
4042 }
41-
42- public void encode (
43- BCPGOutputStream out )
44- throws IOException
43+
44+ public void encode (BCPGOutputStream out ) throws IOException
4545 {
4646 StreamUtil .write2OctetLength (out , value .bitLength ());
47+ BigIntegers .writeUnsignedByteArray (out , value );
48+ }
4749
48- byte [] bytes = value .toByteArray ();
49-
50- if (bytes [0 ] == 0 )
51- {
52- out .write (bytes , 1 , bytes .length - 1 );
53- }
54- else
50+ private static BigInteger readMPI (BCPGInputStream in , boolean validateLength ) throws IOException
51+ {
52+ int bitLength = StreamUtil .read2OctetLength (in );
53+ int byteLength = (bitLength + 7 ) / 8 ;
54+ byte [] bytes = new byte [byteLength ];
55+ in .readFully (bytes );
56+ BigInteger n = new BigInteger (1 , bytes );
57+
58+ if (validateLength && n .bitLength () != bitLength )
5559 {
56- out . write ( bytes , 0 , bytes . length );
60+ throw new IOException ( "malformed MPI" );
5761 }
62+
63+ return n ;
5864 }
5965}
0 commit comments