11package org .bouncycastle .gpg .keybox ;
22
33import java .io .IOException ;
4- import java .util .ArrayList ;
5- import java .util .List ;
64
75/**
86 * A PGP blob holds key material.
@@ -13,163 +11,19 @@ public class CertificateBlob
1311 private CertificateBlob (int base , long length ,
1412 BlobType type ,
1513 int version ,
16- int blobFlags ,
17- int keyNumber ,
18- List <KeyInformation > keyInformation ,
19- byte [] serialNumber ,
20- int numberOfUserIDs ,
21- List <UserID > userIds ,
22- int numberOfSignatures ,
23- List <Long > expirationTime ,
24- int assignedOwnerTrust ,
25- int allValidity ,
26- long recheckAfter ,
27- long newestTimestamp ,
28- long blobCreatedAt ,
29- byte [] keyBytes ,
30- byte [] reserveBytes ,
31- byte [] sha1Checksum )
14+ KeyBlobContent content )
3215 {
33- super (base , length , type , version , blobFlags , keyNumber ,
34- keyInformation , serialNumber , numberOfUserIDs , userIds , numberOfSignatures ,
35- expirationTime , assignedOwnerTrust , allValidity , recheckAfter , newestTimestamp , blobCreatedAt ,
36- keyBytes , reserveBytes , sha1Checksum );
16+ super (base , length , type , version , content );
3717 }
3818
3919
4020 static Blob parseContent (int base , long length , BlobType type , int version , KeyBoxByteBuffer buffer , BlobVerifier blobVerifier )
4121 throws IOException
4222 {
4323
44- //
45- // u32 Length of this blob (including these 4 bytes)
46- // byte Blob type
47- // 2 = OpenPGP
48- // 3 = X509
49- // byte Version number of this blob type
50- // 1 = The only defined value
51- //
24+ KeyBlobContent content = KeyBlobContent .parse (base , length , buffer , blobVerifier );
5225
53-
54- //
55- // Take checksum first.
56- //
57- verifyDigest (base , length , buffer , blobVerifier );
58-
59-
60- int blobFlags = buffer .u16 (); // u16 Blob flags
61- long keyBlockOffset = buffer .u32 (); // u32 offset to the OpenPGP keyblock or X509 DER encoded certificate
62- long keyBlockLength = buffer .u32 (); // u32 and its length
63-
64- int keyNumber = buffer .u16 (); // u16 number of keys (at least 1!) [X509: always 1]
65-
66-
67- // This value defines the length of the space reserved for the AdditionalKeyInformation
68- int keyInformationStructureSize = buffer .u16 (); // u16 size of additional key information
69-
70- //
71- // Load the additional key information.
72- //
73- List <KeyInformation > keyInformation = new ArrayList <KeyInformation >();
74-
75- for (int t = keyNumber - 1 ; t >= 0 ; t --)
76- {
77- keyInformation .add (KeyInformation .getInstance (buffer , keyInformationStructureSize , base ));
78- }
79-
80- int sizeOfSerialNumber = buffer .u16 (); // size of serialnumber(may be zero)
81-
82- byte [] serialNumber = buffer .bN (sizeOfSerialNumber );
83- // buffer.bN(serialNumber); // n u16 (see above) bytes of serial number
84-
85- int numberOfUserIDs = buffer .u16 (); // u16 number of user IDs
86- buffer .u16 (); // size of additional user ID information
87-
88- //
89- // User IDS.
90- //
91- List <UserID > userIds = new ArrayList <UserID >();
92- long totalUserIdLength = 0 ;
93- for (int t = numberOfUserIDs - 1 ; t >= 0 ; t --)
94- {
95- UserID userID = UserID .getInstance (buffer , base );
96- // Bound the cumulative user-ID data by the blob length: each entry copies an
97- // attacker-controlled slice of the blob, so an inflated user-ID count with each entry
98- // pointing at (almost) the whole blob would otherwise retain ~bufferSize^2 bytes.
99- totalUserIdLength += userID .getLengthOfUserId ();
100- if (totalUserIdLength > length )
101- {
102- throw new IllegalStateException ("userID data exceeds blob length" );
103- }
104- userIds .add (userID );
105- }
106-
107- int numberOfSignatures = buffer .u16 ();
108- buffer .u16 ();
109-
110-
111- List <Long > signatureExpirationTime = new ArrayList <Long >();
112- for (int t = numberOfSignatures - 1 ; t >= 0 ; t --)
113- {
114- signatureExpirationTime .add (buffer .u32 ());
115- }
116-
117- int assignedOwnerTrust = buffer .u8 (); // din.read();
118- int allValidity = buffer .u8 ();
119-
120- buffer .u16 (); // RFU
121- long recheckAfter = buffer .u32 ();
122- long newestTimestamp = buffer .u32 ();
123- long blobCreatedAt = buffer .u32 ();
124-
125- long sizeOfReservedSpace = buffer .u32 ();
126-
127- if (sizeOfReservedSpace > buffer .remaining ())
128- {
129- throw new IllegalStateException ("sizeOfReservedSpace exceeds content remaining in buffer" );
130- }
131-
132- // Arbitrary reserved space, that may hold X509 V3 certificate IDs.!
133- byte [] reserveData = buffer .bN ((int )sizeOfReservedSpace ); // Reserved space of size NRES for future use.
134- // buffer.bN(reserveData);
135-
136-
137- //
138- // Key block is loaded based from the start of the blob rather than
139- //
140-
141- byte [] keyData = buffer .rangeOf (
142- (int )(base + keyBlockOffset ),
143- (int )(base + keyBlockOffset + keyBlockLength )); // Defined near top of structure..
144-
145-
146- //
147- // Reserve space.
148- //
149- int dataSize = (int )(length - (buffer .position () - base ) - 20 );
150- byte [] data = buffer .bN (dataSize );
151-
152-
153- byte [] sha1Checksum = buffer .rangeOf ((int )(base + length - 20 ), (int )(base + length ));
154- buffer .consume (sha1Checksum .length );
155-
156- return new CertificateBlob (base , length ,
157- type ,
158- version ,
159- blobFlags ,
160- keyNumber ,
161- keyInformation ,
162- serialNumber ,
163- numberOfUserIDs ,
164- userIds ,
165- numberOfSignatures ,
166- signatureExpirationTime ,
167- assignedOwnerTrust ,
168- allValidity ,
169- recheckAfter ,
170- newestTimestamp ,
171- blobCreatedAt ,
172- keyData , reserveData , sha1Checksum );
26+ return new CertificateBlob (base , length , type , version , content );
17327 }
17428
17529 /**
0 commit comments