1 package org.bouncycastle.tls;
2 
3 import java.io.ByteArrayInputStream;
4 import java.io.ByteArrayOutputStream;
5 import java.io.IOException;
6 import java.util.Enumeration;
7 import java.util.Hashtable;
8 import java.util.Vector;
9 
10 import org.bouncycastle.asn1.ASN1Encoding;
11 import org.bouncycastle.asn1.ASN1ObjectIdentifier;
12 import org.bouncycastle.asn1.ASN1Primitive;
13 import org.bouncycastle.asn1.x500.X500Name;
14 import org.bouncycastle.util.Arrays;
15 import org.bouncycastle.util.Integers;
16 
17 public class TlsExtensionsUtils
18 {
19     public static final Integer EXT_application_layer_protocol_negotiation = Integers.valueOf(ExtensionType.application_layer_protocol_negotiation);
20     public static final Integer EXT_certificate_authorities = Integers.valueOf(ExtensionType.certificate_authorities);
21     public static final Integer EXT_client_certificate_type = Integers.valueOf(ExtensionType.client_certificate_type);
22     public static final Integer EXT_client_certificate_url = Integers.valueOf(ExtensionType.client_certificate_url);
23     public static final Integer EXT_cookie = Integers.valueOf(ExtensionType.cookie);
24     public static final Integer EXT_early_data = Integers.valueOf(ExtensionType.early_data);
25     public static final Integer EXT_ec_point_formats = Integers.valueOf(ExtensionType.ec_point_formats);
26     public static final Integer EXT_encrypt_then_mac = Integers.valueOf(ExtensionType.encrypt_then_mac);
27     public static final Integer EXT_extended_master_secret = Integers.valueOf(ExtensionType.extended_master_secret);
28     public static final Integer EXT_heartbeat = Integers.valueOf(ExtensionType.heartbeat);
29     public static final Integer EXT_key_share = Integers.valueOf(ExtensionType.key_share);
30     public static final Integer EXT_max_fragment_length = Integers.valueOf(ExtensionType.max_fragment_length);
31     public static final Integer EXT_oid_filters = Integers.valueOf(ExtensionType.oid_filters);
32     public static final Integer EXT_padding = Integers.valueOf(ExtensionType.padding);
33     public static final Integer EXT_post_handshake_auth = Integers.valueOf(ExtensionType.post_handshake_auth);
34     public static final Integer EXT_pre_shared_key = Integers.valueOf(ExtensionType.pre_shared_key);
35     public static final Integer EXT_psk_key_exchange_modes = Integers.valueOf(ExtensionType.psk_key_exchange_modes);
36     public static final Integer EXT_record_size_limit = Integers.valueOf(ExtensionType.record_size_limit);
37     public static final Integer EXT_server_certificate_type = Integers.valueOf(ExtensionType.server_certificate_type);
38     public static final Integer EXT_server_name = Integers.valueOf(ExtensionType.server_name);
39     public static final Integer EXT_signature_algorithms = Integers.valueOf(ExtensionType.signature_algorithms);
40     public static final Integer EXT_signature_algorithms_cert = Integers.valueOf(ExtensionType.signature_algorithms_cert);
41     public static final Integer EXT_status_request = Integers.valueOf(ExtensionType.status_request);
42     public static final Integer EXT_status_request_v2 = Integers.valueOf(ExtensionType.status_request_v2);
43     public static final Integer EXT_supported_groups = Integers.valueOf(ExtensionType.supported_groups);
44     public static final Integer EXT_supported_versions = Integers.valueOf(ExtensionType.supported_versions);
45     public static final Integer EXT_truncated_hmac = Integers.valueOf(ExtensionType.truncated_hmac);
46     public static final Integer EXT_trusted_ca_keys = Integers.valueOf(ExtensionType.trusted_ca_keys);
47 
ensureExtensionsInitialised(Hashtable extensions)48     public static Hashtable ensureExtensionsInitialised(Hashtable extensions)
49     {
50         return extensions == null ? new Hashtable() : extensions;
51     }
52 
53     /**
54      * @param protocolNameList a {@link Vector} of {@link ProtocolName}
55      */
addALPNExtensionClient(Hashtable extensions, Vector protocolNameList)56     public static void addALPNExtensionClient(Hashtable extensions, Vector protocolNameList) throws IOException
57     {
58         extensions.put(EXT_application_layer_protocol_negotiation, createALPNExtensionClient(protocolNameList));
59     }
60 
addALPNExtensionServer(Hashtable extensions, ProtocolName protocolName)61     public static void addALPNExtensionServer(Hashtable extensions, ProtocolName protocolName) throws IOException
62     {
63         extensions.put(EXT_application_layer_protocol_negotiation, createALPNExtensionServer(protocolName));
64     }
65 
addCertificateAuthoritiesExtension(Hashtable extensions, Vector authorities)66     public static void addCertificateAuthoritiesExtension(Hashtable extensions, Vector authorities) throws IOException
67     {
68         extensions.put(EXT_certificate_authorities, createCertificateAuthoritiesExtension(authorities));
69     }
70 
addClientCertificateTypeExtensionClient(Hashtable extensions, short[] certificateTypes)71     public static void addClientCertificateTypeExtensionClient(Hashtable extensions, short[] certificateTypes)
72         throws IOException
73     {
74         extensions.put(EXT_client_certificate_type, createCertificateTypeExtensionClient(certificateTypes));
75     }
76 
addClientCertificateTypeExtensionServer(Hashtable extensions, short certificateType)77     public static void addClientCertificateTypeExtensionServer(Hashtable extensions, short certificateType)
78         throws IOException
79     {
80         extensions.put(EXT_client_certificate_type, createCertificateTypeExtensionServer(certificateType));
81     }
82 
addClientCertificateURLExtension(Hashtable extensions)83     public static void addClientCertificateURLExtension(Hashtable extensions)
84     {
85         extensions.put(EXT_client_certificate_url, createClientCertificateURLExtension());
86     }
87 
addCookieExtension(Hashtable extensions, byte[] cookie)88     public static void addCookieExtension(Hashtable extensions, byte[] cookie) throws IOException
89     {
90         extensions.put(EXT_cookie, createCookieExtension(cookie));
91     }
92 
addEarlyDataIndication(Hashtable extensions)93     public static void addEarlyDataIndication(Hashtable extensions)
94     {
95         extensions.put(EXT_early_data, createEarlyDataIndication());
96     }
97 
addEarlyDataMaxSize(Hashtable extensions, long maxSize)98     public static void addEarlyDataMaxSize(Hashtable extensions, long maxSize) throws IOException
99     {
100         extensions.put(EXT_early_data, createEarlyDataMaxSize(maxSize));
101     }
102 
addEmptyExtensionData(Hashtable extensions, Integer extType)103     public static void addEmptyExtensionData(Hashtable extensions, Integer extType)
104     {
105         extensions.put(extType, createEmptyExtensionData());
106     }
107 
addEncryptThenMACExtension(Hashtable extensions)108     public static void addEncryptThenMACExtension(Hashtable extensions)
109     {
110         extensions.put(EXT_encrypt_then_mac, createEncryptThenMACExtension());
111     }
112 
addExtendedMasterSecretExtension(Hashtable extensions)113     public static void addExtendedMasterSecretExtension(Hashtable extensions)
114     {
115         extensions.put(EXT_extended_master_secret, createExtendedMasterSecretExtension());
116     }
117 
addHeartbeatExtension(Hashtable extensions, HeartbeatExtension heartbeatExtension)118     public static void addHeartbeatExtension(Hashtable extensions, HeartbeatExtension heartbeatExtension)
119         throws IOException
120     {
121         extensions.put(EXT_heartbeat, createHeartbeatExtension(heartbeatExtension));
122     }
123 
addKeyShareClientHello(Hashtable extensions, Vector clientShares)124     public static void addKeyShareClientHello(Hashtable extensions, Vector clientShares)
125         throws IOException
126     {
127         extensions.put(EXT_key_share, createKeyShareClientHello(clientShares));
128     }
129 
addKeyShareHelloRetryRequest(Hashtable extensions, int namedGroup)130     public static void addKeyShareHelloRetryRequest(Hashtable extensions, int namedGroup)
131         throws IOException
132     {
133         extensions.put(EXT_key_share, createKeyShareHelloRetryRequest(namedGroup));
134     }
135 
addKeyShareServerHello(Hashtable extensions, KeyShareEntry serverShare)136     public static void addKeyShareServerHello(Hashtable extensions, KeyShareEntry serverShare)
137         throws IOException
138     {
139         extensions.put(EXT_key_share, createKeyShareServerHello(serverShare));
140     }
141 
addMaxFragmentLengthExtension(Hashtable extensions, short maxFragmentLength)142     public static void addMaxFragmentLengthExtension(Hashtable extensions, short maxFragmentLength)
143         throws IOException
144     {
145         extensions.put(EXT_max_fragment_length, createMaxFragmentLengthExtension(maxFragmentLength));
146     }
147 
addOIDFiltersExtension(Hashtable extensions, Hashtable filters)148     public static void addOIDFiltersExtension(Hashtable extensions, Hashtable filters) throws IOException
149     {
150         extensions.put(EXT_oid_filters, createOIDFiltersExtension(filters));
151     }
152 
addPaddingExtension(Hashtable extensions, int dataLength)153     public static void addPaddingExtension(Hashtable extensions, int dataLength)
154         throws IOException
155     {
156         extensions.put(EXT_padding, createPaddingExtension(dataLength));
157     }
158 
addPostHandshakeAuthExtension(Hashtable extensions)159     public static void addPostHandshakeAuthExtension(Hashtable extensions)
160     {
161         extensions.put(EXT_post_handshake_auth, createPostHandshakeAuthExtension());
162     }
163 
addPreSharedKeyClientHello(Hashtable extensions, OfferedPsks offeredPsks)164     public static void addPreSharedKeyClientHello(Hashtable extensions, OfferedPsks offeredPsks)
165         throws IOException
166     {
167         extensions.put(EXT_pre_shared_key, createPreSharedKeyClientHello(offeredPsks));
168     }
169 
addPreSharedKeyServerHello(Hashtable extensions, int selectedIdentity)170     public static void addPreSharedKeyServerHello(Hashtable extensions, int selectedIdentity)
171         throws IOException
172     {
173         extensions.put(EXT_pre_shared_key, createPreSharedKeyServerHello(selectedIdentity));
174     }
175 
addPSKKeyExchangeModesExtension(Hashtable extensions, short[] modes)176     public static void addPSKKeyExchangeModesExtension(Hashtable extensions, short[] modes)
177         throws IOException
178     {
179         extensions.put(EXT_psk_key_exchange_modes, createPSKKeyExchangeModesExtension(modes));
180     }
181 
addRecordSizeLimitExtension(Hashtable extensions, int recordSizeLimit)182     public static void addRecordSizeLimitExtension(Hashtable extensions, int recordSizeLimit)
183         throws IOException
184     {
185         extensions.put(EXT_record_size_limit, createRecordSizeLimitExtension(recordSizeLimit));
186     }
187 
addServerCertificateTypeExtensionClient(Hashtable extensions, short[] certificateTypes)188     public static void addServerCertificateTypeExtensionClient(Hashtable extensions, short[] certificateTypes)
189         throws IOException
190     {
191         extensions.put(EXT_server_certificate_type, createCertificateTypeExtensionClient(certificateTypes));
192     }
193 
addServerCertificateTypeExtensionServer(Hashtable extensions, short certificateType)194     public static void addServerCertificateTypeExtensionServer(Hashtable extensions, short certificateType)
195         throws IOException
196     {
197         extensions.put(EXT_server_certificate_type, createCertificateTypeExtensionServer(certificateType));
198     }
199 
addServerNameExtensionClient(Hashtable extensions, Vector serverNameList)200     public static void addServerNameExtensionClient(Hashtable extensions, Vector serverNameList)
201         throws IOException
202     {
203         extensions.put(EXT_server_name, createServerNameExtensionClient(serverNameList));
204     }
205 
addServerNameExtensionServer(Hashtable extensions)206     public static void addServerNameExtensionServer(Hashtable extensions)
207         throws IOException
208     {
209         extensions.put(EXT_server_name, createServerNameExtensionServer());
210     }
211 
addSignatureAlgorithmsExtension(Hashtable extensions, Vector supportedSignatureAlgorithms)212     public static void addSignatureAlgorithmsExtension(Hashtable extensions, Vector supportedSignatureAlgorithms)
213         throws IOException
214     {
215         extensions.put(EXT_signature_algorithms, createSignatureAlgorithmsExtension(supportedSignatureAlgorithms));
216     }
217 
addSignatureAlgorithmsCertExtension(Hashtable extensions, Vector supportedSignatureAlgorithms)218     public static void addSignatureAlgorithmsCertExtension(Hashtable extensions, Vector supportedSignatureAlgorithms)
219         throws IOException
220     {
221         extensions.put(EXT_signature_algorithms_cert, createSignatureAlgorithmsCertExtension(supportedSignatureAlgorithms));
222     }
223 
addStatusRequestExtension(Hashtable extensions, CertificateStatusRequest statusRequest)224     public static void addStatusRequestExtension(Hashtable extensions, CertificateStatusRequest statusRequest)
225         throws IOException
226     {
227         extensions.put(EXT_status_request, createStatusRequestExtension(statusRequest));
228     }
229 
addStatusRequestV2Extension(Hashtable extensions, Vector statusRequestV2)230     public static void addStatusRequestV2Extension(Hashtable extensions, Vector statusRequestV2)
231         throws IOException
232     {
233         extensions.put(EXT_status_request_v2, createStatusRequestV2Extension(statusRequestV2));
234     }
235 
addSupportedGroupsExtension(Hashtable extensions, Vector namedGroups)236     public static void addSupportedGroupsExtension(Hashtable extensions, Vector namedGroups) throws IOException
237     {
238         extensions.put(EXT_supported_groups, createSupportedGroupsExtension(namedGroups));
239     }
240 
addSupportedPointFormatsExtension(Hashtable extensions, short[] ecPointFormats)241     public static void addSupportedPointFormatsExtension(Hashtable extensions, short[] ecPointFormats)
242         throws IOException
243     {
244         extensions.put(EXT_ec_point_formats, createSupportedPointFormatsExtension(ecPointFormats));
245     }
246 
addSupportedVersionsExtensionClient(Hashtable extensions, ProtocolVersion[] versions)247     public static void addSupportedVersionsExtensionClient(Hashtable extensions, ProtocolVersion[] versions) throws IOException
248     {
249         extensions.put(EXT_supported_versions, createSupportedVersionsExtensionClient(versions));
250     }
251 
addSupportedVersionsExtensionServer(Hashtable extensions, ProtocolVersion selectedVersion)252     public static void addSupportedVersionsExtensionServer(Hashtable extensions, ProtocolVersion selectedVersion) throws IOException
253     {
254         extensions.put(EXT_supported_versions, createSupportedVersionsExtensionServer(selectedVersion));
255     }
256 
addTruncatedHMacExtension(Hashtable extensions)257     public static void addTruncatedHMacExtension(Hashtable extensions)
258     {
259         extensions.put(EXT_truncated_hmac, createTruncatedHMacExtension());
260     }
261 
addTrustedCAKeysExtensionClient(Hashtable extensions, Vector trustedAuthoritiesList)262     public static void addTrustedCAKeysExtensionClient(Hashtable extensions, Vector trustedAuthoritiesList)
263         throws IOException
264     {
265         extensions.put(EXT_trusted_ca_keys, createTrustedCAKeysExtensionClient(trustedAuthoritiesList));
266     }
267 
addTrustedCAKeysExtensionServer(Hashtable extensions)268     public static void addTrustedCAKeysExtensionServer(Hashtable extensions)
269     {
270         extensions.put(EXT_trusted_ca_keys, createTrustedCAKeysExtensionServer());
271     }
272 
273     /**
274      * @return a {@link Vector} of {@link ProtocolName}
275      */
getALPNExtensionClient(Hashtable extensions)276     public static Vector getALPNExtensionClient(Hashtable extensions) throws IOException
277     {
278         byte[] extensionData = TlsUtils.getExtensionData(extensions, EXT_application_layer_protocol_negotiation);
279         return extensionData == null ? null : readALPNExtensionClient(extensionData);
280     }
281 
getALPNExtensionServer(Hashtable extensions)282     public static ProtocolName getALPNExtensionServer(Hashtable extensions) throws IOException
283     {
284         byte[] extensionData = TlsUtils.getExtensionData(extensions, EXT_application_layer_protocol_negotiation);
285         return extensionData == null ? null : readALPNExtensionServer(extensionData);
286     }
287 
getCertificateAuthoritiesExtension(Hashtable extensions)288     public static Vector getCertificateAuthoritiesExtension(Hashtable extensions) throws IOException
289     {
290         byte[] extensionData = TlsUtils.getExtensionData(extensions, EXT_certificate_authorities);
291         return extensionData == null ? null : readCertificateAuthoritiesExtension(extensionData);
292     }
293 
getClientCertificateTypeExtensionClient(Hashtable extensions)294     public static short[] getClientCertificateTypeExtensionClient(Hashtable extensions)
295         throws IOException
296     {
297         byte[] extensionData = TlsUtils.getExtensionData(extensions, EXT_client_certificate_type);
298         return extensionData == null ? null : readCertificateTypeExtensionClient(extensionData);
299     }
300 
getClientCertificateTypeExtensionServer(Hashtable extensions)301     public static short getClientCertificateTypeExtensionServer(Hashtable extensions)
302         throws IOException
303     {
304         byte[] extensionData = TlsUtils.getExtensionData(extensions, EXT_client_certificate_type);
305         return extensionData == null ? -1 : readCertificateTypeExtensionServer(extensionData);
306     }
307 
getCookieExtension(Hashtable extensions)308     public static byte[] getCookieExtension(Hashtable extensions)
309         throws IOException
310     {
311         byte[] extensionData = TlsUtils.getExtensionData(extensions, EXT_cookie);
312         return extensionData == null ? null : readCookieExtension(extensionData);
313     }
314 
getEarlyDataMaxSize(Hashtable extensions)315     public static long getEarlyDataMaxSize(Hashtable extensions) throws IOException
316     {
317         byte[] extensionData = TlsUtils.getExtensionData(extensions, EXT_early_data);
318         return extensionData == null ? -1L : readEarlyDataMaxSize(extensionData);
319     }
320 
getHeartbeatExtension(Hashtable extensions)321     public static HeartbeatExtension getHeartbeatExtension(Hashtable extensions)
322         throws IOException
323     {
324         byte[] extensionData = TlsUtils.getExtensionData(extensions, EXT_heartbeat);
325         return extensionData == null ? null : readHeartbeatExtension(extensionData);
326     }
327 
getKeyShareClientHello(Hashtable extensions)328     public static Vector getKeyShareClientHello(Hashtable extensions)
329         throws IOException
330     {
331         byte[] extensionData = TlsUtils.getExtensionData(extensions, EXT_key_share);
332         return extensionData == null ? null : readKeyShareClientHello(extensionData);
333     }
334 
getKeyShareHelloRetryRequest(Hashtable extensions)335     public static int getKeyShareHelloRetryRequest(Hashtable extensions)
336         throws IOException
337     {
338         byte[] extensionData = TlsUtils.getExtensionData(extensions, EXT_key_share);
339         return extensionData == null ? -1 : readKeyShareHelloRetryRequest(extensionData);
340     }
341 
getKeyShareServerHello(Hashtable extensions)342     public static KeyShareEntry getKeyShareServerHello(Hashtable extensions)
343         throws IOException
344     {
345         byte[] extensionData = TlsUtils.getExtensionData(extensions, EXT_key_share);
346         return extensionData == null ? null : readKeyShareServerHello(extensionData);
347     }
348 
getMaxFragmentLengthExtension(Hashtable extensions)349     public static short getMaxFragmentLengthExtension(Hashtable extensions)
350         throws IOException
351     {
352         byte[] extensionData = TlsUtils.getExtensionData(extensions, EXT_max_fragment_length);
353         return extensionData == null ? -1 : readMaxFragmentLengthExtension(extensionData);
354     }
355 
getOIDFiltersExtension(Hashtable extensions)356     public static Hashtable getOIDFiltersExtension(Hashtable extensions)
357         throws IOException
358     {
359         byte[] extensionData = TlsUtils.getExtensionData(extensions, EXT_oid_filters);
360         return extensionData == null ? null : readOIDFiltersExtension(extensionData);
361     }
362 
getPaddingExtension(Hashtable extensions)363     public static int getPaddingExtension(Hashtable extensions)
364         throws IOException
365     {
366         byte[] extensionData = TlsUtils.getExtensionData(extensions, EXT_padding);
367         return extensionData == null ? -1 : readPaddingExtension(extensionData);
368     }
369 
getPreSharedKeyClientHello(Hashtable extensions)370     public static OfferedPsks getPreSharedKeyClientHello(Hashtable extensions)
371         throws IOException
372     {
373         byte[] extensionData = TlsUtils.getExtensionData(extensions, EXT_pre_shared_key);
374         return extensionData == null ? null : readPreSharedKeyClientHello(extensionData);
375     }
376 
getPreSharedKeyServerHello(Hashtable extensions)377     public static int getPreSharedKeyServerHello(Hashtable extensions)
378         throws IOException
379     {
380         byte[] extensionData = TlsUtils.getExtensionData(extensions, EXT_pre_shared_key);
381         return extensionData == null ? -1 : readPreSharedKeyServerHello(extensionData);
382     }
383 
getPSKKeyExchangeModesExtension(Hashtable extensions)384     public static short[] getPSKKeyExchangeModesExtension(Hashtable extensions)
385         throws IOException
386     {
387         byte[] extensionData = TlsUtils.getExtensionData(extensions, EXT_psk_key_exchange_modes);
388         return extensionData == null ? null : readPSKKeyExchangeModesExtension(extensionData);
389     }
390 
getRecordSizeLimitExtension(Hashtable extensions)391     public static int getRecordSizeLimitExtension(Hashtable extensions)
392         throws IOException
393     {
394         byte[] extensionData = TlsUtils.getExtensionData(extensions, EXT_record_size_limit);
395         return extensionData == null ? -1 : readRecordSizeLimitExtension(extensionData);
396     }
397 
getServerCertificateTypeExtensionClient(Hashtable extensions)398     public static short[] getServerCertificateTypeExtensionClient(Hashtable extensions)
399         throws IOException
400     {
401         byte[] extensionData = TlsUtils.getExtensionData(extensions, EXT_server_certificate_type);
402         return extensionData == null ? null : readCertificateTypeExtensionClient(extensionData);
403     }
404 
getServerCertificateTypeExtensionServer(Hashtable extensions)405     public static short getServerCertificateTypeExtensionServer(Hashtable extensions)
406         throws IOException
407     {
408         byte[] extensionData = TlsUtils.getExtensionData(extensions, EXT_server_certificate_type);
409         return extensionData == null ? -1 : readCertificateTypeExtensionServer(extensionData);
410     }
411 
getServerNameExtensionClient(Hashtable extensions)412     public static Vector getServerNameExtensionClient(Hashtable extensions)
413         throws IOException
414     {
415         byte[] extensionData = TlsUtils.getExtensionData(extensions, EXT_server_name);
416         return extensionData == null ? null : readServerNameExtensionClient(extensionData);
417     }
418 
getSignatureAlgorithmsExtension(Hashtable extensions)419     public static Vector getSignatureAlgorithmsExtension(Hashtable extensions)
420         throws IOException
421     {
422         byte[] extensionData = TlsUtils.getExtensionData(extensions, EXT_signature_algorithms);
423         return extensionData == null ? null : readSignatureAlgorithmsExtension(extensionData);
424     }
425 
getSignatureAlgorithmsCertExtension(Hashtable extensions)426     public static Vector getSignatureAlgorithmsCertExtension(Hashtable extensions)
427         throws IOException
428     {
429         byte[] extensionData = TlsUtils.getExtensionData(extensions, EXT_signature_algorithms_cert);
430         return extensionData == null ? null : readSignatureAlgorithmsCertExtension(extensionData);
431     }
432 
getStatusRequestExtension(Hashtable extensions)433     public static CertificateStatusRequest getStatusRequestExtension(Hashtable extensions)
434         throws IOException
435     {
436         byte[] extensionData = TlsUtils.getExtensionData(extensions, EXT_status_request);
437         return extensionData == null ? null : readStatusRequestExtension(extensionData);
438     }
439 
getStatusRequestV2Extension(Hashtable extensions)440     public static Vector getStatusRequestV2Extension(Hashtable extensions)
441         throws IOException
442     {
443         byte[] extensionData = TlsUtils.getExtensionData(extensions, EXT_status_request_v2);
444         return extensionData == null ? null : readStatusRequestV2Extension(extensionData);
445     }
446 
getSupportedGroupsExtension(Hashtable extensions)447     public static int[] getSupportedGroupsExtension(Hashtable extensions) throws IOException
448     {
449         byte[] extensionData = TlsUtils.getExtensionData(extensions, EXT_supported_groups);
450         return extensionData == null ? null : readSupportedGroupsExtension(extensionData);
451     }
452 
getSupportedPointFormatsExtension(Hashtable extensions)453     public static short[] getSupportedPointFormatsExtension(Hashtable extensions) throws IOException
454     {
455         byte[] extensionData = TlsUtils.getExtensionData(extensions, EXT_ec_point_formats);
456         return extensionData == null ? null : readSupportedPointFormatsExtension(extensionData);
457     }
458 
getSupportedVersionsExtensionClient(Hashtable extensions)459     public static ProtocolVersion[] getSupportedVersionsExtensionClient(Hashtable extensions) throws IOException
460     {
461         byte[] extensionData = TlsUtils.getExtensionData(extensions, EXT_supported_versions);
462         return extensionData == null ? null : readSupportedVersionsExtensionClient(extensionData);
463     }
464 
getSupportedVersionsExtensionServer(Hashtable extensions)465     public static ProtocolVersion getSupportedVersionsExtensionServer(Hashtable extensions) throws IOException
466     {
467         byte[] extensionData = TlsUtils.getExtensionData(extensions, EXT_supported_versions);
468         return extensionData == null ? null : readSupportedVersionsExtensionServer(extensionData);
469     }
470 
getTrustedCAKeysExtensionClient(Hashtable extensions)471     public static Vector getTrustedCAKeysExtensionClient(Hashtable extensions)
472         throws IOException
473     {
474         byte[] extensionData = TlsUtils.getExtensionData(extensions, EXT_trusted_ca_keys);
475         return extensionData == null ? null : readTrustedCAKeysExtensionClient(extensionData);
476     }
477 
hasClientCertificateURLExtension(Hashtable extensions)478     public static boolean hasClientCertificateURLExtension(Hashtable extensions) throws IOException
479     {
480         byte[] extensionData = TlsUtils.getExtensionData(extensions, EXT_client_certificate_url);
481         return extensionData == null ? false : readClientCertificateURLExtension(extensionData);
482     }
483 
hasEarlyDataIndication(Hashtable extensions)484     public static boolean hasEarlyDataIndication(Hashtable extensions) throws IOException
485     {
486         byte[] extensionData = TlsUtils.getExtensionData(extensions, EXT_early_data);
487         return extensionData == null ? false : readEarlyDataIndication(extensionData);
488     }
489 
hasEncryptThenMACExtension(Hashtable extensions)490     public static boolean hasEncryptThenMACExtension(Hashtable extensions) throws IOException
491     {
492         byte[] extensionData = TlsUtils.getExtensionData(extensions, EXT_encrypt_then_mac);
493         return extensionData == null ? false : readEncryptThenMACExtension(extensionData);
494     }
495 
hasExtendedMasterSecretExtension(Hashtable extensions)496     public static boolean hasExtendedMasterSecretExtension(Hashtable extensions) throws IOException
497     {
498         byte[] extensionData = TlsUtils.getExtensionData(extensions, EXT_extended_master_secret);
499         return extensionData == null ? false : readExtendedMasterSecretExtension(extensionData);
500     }
501 
hasServerNameExtensionServer(Hashtable extensions)502     public static boolean hasServerNameExtensionServer(Hashtable extensions)
503         throws IOException
504     {
505         byte[] extensionData = TlsUtils.getExtensionData(extensions, EXT_server_name);
506         return extensionData == null ? false : readServerNameExtensionServer(extensionData);
507     }
508 
hasPostHandshakeAuthExtension(Hashtable extensions)509     public static boolean hasPostHandshakeAuthExtension(Hashtable extensions) throws IOException
510     {
511         byte[] extensionData = TlsUtils.getExtensionData(extensions, EXT_post_handshake_auth);
512         return extensionData == null ? false : readPostHandshakeAuthExtension(extensionData);
513     }
514 
hasTruncatedHMacExtension(Hashtable extensions)515     public static boolean hasTruncatedHMacExtension(Hashtable extensions) throws IOException
516     {
517         byte[] extensionData = TlsUtils.getExtensionData(extensions, EXT_truncated_hmac);
518         return extensionData == null ? false : readTruncatedHMacExtension(extensionData);
519     }
520 
hasTrustedCAKeysExtensionServer(Hashtable extensions)521     public static boolean hasTrustedCAKeysExtensionServer(Hashtable extensions) throws IOException
522     {
523         byte[] extensionData = TlsUtils.getExtensionData(extensions, EXT_trusted_ca_keys);
524         return extensionData == null ? false : readTrustedCAKeysExtensionServer(extensionData);
525     }
526 
527     /**
528      * @param protocolNameList a {@link Vector} of {@link ProtocolName}
529      */
createALPNExtensionClient(Vector protocolNameList)530     public static byte[] createALPNExtensionClient(Vector protocolNameList) throws IOException
531     {
532         if (protocolNameList == null || protocolNameList.size() < 1)
533         {
534             throw new TlsFatalAlert(AlertDescription.internal_error);
535         }
536 
537         ByteArrayOutputStream buf = new ByteArrayOutputStream();
538 
539         // Placeholder for length
540         TlsUtils.writeUint16(0, buf);
541 
542         for (int i = 0; i < protocolNameList.size(); ++i)
543         {
544             ProtocolName protocolName = (ProtocolName)protocolNameList.elementAt(i);
545 
546             protocolName.encode(buf);
547         }
548 
549         return patchOpaque16(buf);
550     }
551 
createALPNExtensionServer(ProtocolName protocolName)552     public static byte[] createALPNExtensionServer(ProtocolName protocolName) throws IOException
553     {
554         Vector protocol_name_list = new Vector();
555         protocol_name_list.addElement(protocolName);
556 
557         return createALPNExtensionClient(protocol_name_list);
558     }
559 
createCertificateAuthoritiesExtension(Vector authorities)560     public static byte[] createCertificateAuthoritiesExtension(Vector authorities) throws IOException
561     {
562         if (null == authorities || authorities.isEmpty())
563         {
564             throw new TlsFatalAlert(AlertDescription.internal_error);
565         }
566 
567         ByteArrayOutputStream buf = new ByteArrayOutputStream();
568 
569         // Placeholder for length
570         TlsUtils.writeUint16(0, buf);
571 
572         for (int i = 0; i < authorities.size(); ++i)
573         {
574             X500Name authority = (X500Name)authorities.elementAt(i);
575             byte[] derEncoding = authority.getEncoded(ASN1Encoding.DER);
576             TlsUtils.writeOpaque16(derEncoding, buf);
577         }
578 
579         return patchOpaque16(buf);
580     }
581 
createCertificateTypeExtensionClient(short[] certificateTypes)582     public static byte[] createCertificateTypeExtensionClient(short[] certificateTypes) throws IOException
583     {
584         if (TlsUtils.isNullOrEmpty(certificateTypes) || certificateTypes.length > 255)
585         {
586             throw new TlsFatalAlert(AlertDescription.internal_error);
587         }
588 
589         return TlsUtils.encodeUint8ArrayWithUint8Length(certificateTypes);
590     }
591 
createCertificateTypeExtensionServer(short certificateType)592     public static byte[] createCertificateTypeExtensionServer(short certificateType) throws IOException
593     {
594         return TlsUtils.encodeUint8(certificateType);
595     }
596 
createClientCertificateURLExtension()597     public static byte[] createClientCertificateURLExtension()
598     {
599         return createEmptyExtensionData();
600     }
601 
createCookieExtension(byte[] cookie)602     public static byte[] createCookieExtension(byte[] cookie) throws IOException
603     {
604         if (TlsUtils.isNullOrEmpty(cookie) || cookie.length >= (1 << 16))
605         {
606             throw new TlsFatalAlert(AlertDescription.internal_error);
607         }
608 
609         return TlsUtils.encodeOpaque16(cookie);
610     }
611 
createEarlyDataIndication()612     public static byte[] createEarlyDataIndication()
613     {
614         return createEmptyExtensionData();
615     }
616 
createEarlyDataMaxSize(long maxSize)617     public static byte[] createEarlyDataMaxSize(long maxSize) throws IOException
618     {
619         return TlsUtils.encodeUint32(maxSize);
620     }
621 
createEmptyExtensionData()622     public static byte[] createEmptyExtensionData()
623     {
624         return TlsUtils.EMPTY_BYTES;
625     }
626 
createEncryptThenMACExtension()627     public static byte[] createEncryptThenMACExtension()
628     {
629         return createEmptyExtensionData();
630     }
631 
createExtendedMasterSecretExtension()632     public static byte[] createExtendedMasterSecretExtension()
633     {
634         return createEmptyExtensionData();
635     }
636 
createHeartbeatExtension(HeartbeatExtension heartbeatExtension)637     public static byte[] createHeartbeatExtension(HeartbeatExtension heartbeatExtension)
638         throws IOException
639     {
640         if (heartbeatExtension == null)
641         {
642             throw new TlsFatalAlert(AlertDescription.internal_error);
643         }
644 
645         ByteArrayOutputStream buf = new ByteArrayOutputStream();
646 
647         heartbeatExtension.encode(buf);
648 
649         return buf.toByteArray();
650     }
651 
createKeyShareClientHello(Vector clientShares)652     public static byte[] createKeyShareClientHello(Vector clientShares)
653         throws IOException
654     {
655         if (clientShares == null || clientShares.isEmpty())
656         {
657             return TlsUtils.encodeUint16(0);
658         }
659 
660         ByteArrayOutputStream buf = new ByteArrayOutputStream();
661 
662         // Placeholder for length
663         TlsUtils.writeUint16(0, buf);
664 
665         for (int i = 0; i < clientShares.size(); ++i)
666         {
667             KeyShareEntry clientShare = (KeyShareEntry)clientShares.elementAt(i);
668 
669             clientShare.encode(buf);
670         }
671 
672         return patchOpaque16(buf);
673     }
674 
createKeyShareHelloRetryRequest(int namedGroup)675     public static byte[] createKeyShareHelloRetryRequest(int namedGroup)
676         throws IOException
677     {
678         return TlsUtils.encodeUint16(namedGroup);
679     }
680 
createKeyShareServerHello(KeyShareEntry serverShare)681     public static byte[] createKeyShareServerHello(KeyShareEntry serverShare)
682         throws IOException
683     {
684         if (serverShare == null)
685         {
686             throw new TlsFatalAlert(AlertDescription.internal_error);
687         }
688 
689         ByteArrayOutputStream buf = new ByteArrayOutputStream();
690 
691         serverShare.encode(buf);
692 
693         return buf.toByteArray();
694     }
695 
createMaxFragmentLengthExtension(short maxFragmentLength)696     public static byte[] createMaxFragmentLengthExtension(short maxFragmentLength)
697         throws IOException
698     {
699         return TlsUtils.encodeUint8(maxFragmentLength);
700     }
701 
createOIDFiltersExtension(Hashtable filters)702     public static byte[] createOIDFiltersExtension(Hashtable filters) throws IOException
703     {
704         ByteArrayOutputStream buf = new ByteArrayOutputStream();
705 
706         // Placeholder for length
707         TlsUtils.writeUint16(0, buf);
708 
709         if (null != filters)
710         {
711             Enumeration keys = filters.keys();
712             while (keys.hasMoreElements())
713             {
714                 ASN1ObjectIdentifier certificateExtensionOID = (ASN1ObjectIdentifier)keys.nextElement();
715                 byte[] certificateExtensionValues = (byte[])filters.get(certificateExtensionOID);
716 
717                 if (null == certificateExtensionOID || null == certificateExtensionValues)
718                 {
719                     throw new TlsFatalAlert(AlertDescription.internal_error);
720                 }
721 
722                 byte[] derEncoding = certificateExtensionOID.getEncoded(ASN1Encoding.DER);
723                 TlsUtils.writeOpaque8(derEncoding, buf);
724 
725                 TlsUtils.writeOpaque16(certificateExtensionValues, buf);
726             }
727         }
728 
729         return patchOpaque16(buf);
730     }
731 
createPaddingExtension(int dataLength)732     public static byte[] createPaddingExtension(int dataLength)
733         throws IOException
734     {
735         TlsUtils.checkUint16(dataLength);
736         return new byte[dataLength];
737     }
738 
createPostHandshakeAuthExtension()739     public static byte[] createPostHandshakeAuthExtension()
740     {
741         return createEmptyExtensionData();
742     }
743 
createPreSharedKeyClientHello(OfferedPsks offeredPsks)744     public static byte[] createPreSharedKeyClientHello(OfferedPsks offeredPsks) throws IOException
745     {
746         if (offeredPsks == null)
747         {
748             throw new TlsFatalAlert(AlertDescription.internal_error);
749         }
750 
751         ByteArrayOutputStream buf = new ByteArrayOutputStream();
752 
753         offeredPsks.encode(buf);
754 
755         return buf.toByteArray();
756     }
757 
createPreSharedKeyServerHello(int selectedIdentity)758     public static byte[] createPreSharedKeyServerHello(int selectedIdentity) throws IOException
759     {
760         return TlsUtils.encodeUint16(selectedIdentity);
761     }
762 
createPSKKeyExchangeModesExtension(short[] modes)763     public static byte[] createPSKKeyExchangeModesExtension(short[] modes) throws IOException
764     {
765         if (TlsUtils.isNullOrEmpty(modes) || modes.length > 255)
766         {
767             throw new TlsFatalAlert(AlertDescription.internal_error);
768         }
769 
770         return TlsUtils.encodeUint8ArrayWithUint8Length(modes);
771     }
772 
createRecordSizeLimitExtension(int recordSizeLimit)773     public static byte[] createRecordSizeLimitExtension(int recordSizeLimit)
774         throws IOException
775     {
776         if (recordSizeLimit < 64)
777         {
778             throw new TlsFatalAlert(AlertDescription.internal_error);
779         }
780 
781         return TlsUtils.encodeUint16(recordSizeLimit);
782     }
783 
createServerNameExtensionClient(Vector serverNameList)784     public static byte[] createServerNameExtensionClient(Vector serverNameList)
785         throws IOException
786     {
787         if (serverNameList == null)
788         {
789             throw new TlsFatalAlert(AlertDescription.internal_error);
790         }
791 
792         ByteArrayOutputStream buf = new ByteArrayOutputStream();
793 
794         new ServerNameList(serverNameList).encode(buf);
795 
796         return buf.toByteArray();
797     }
798 
createServerNameExtensionServer()799     public static byte[] createServerNameExtensionServer()
800     {
801         return createEmptyExtensionData();
802     }
803 
createSignatureAlgorithmsExtension(Vector supportedSignatureAlgorithms)804     public static byte[] createSignatureAlgorithmsExtension(Vector supportedSignatureAlgorithms)
805         throws IOException
806     {
807         ByteArrayOutputStream buf = new ByteArrayOutputStream();
808 
809         TlsUtils.encodeSupportedSignatureAlgorithms(supportedSignatureAlgorithms, buf);
810 
811         return buf.toByteArray();
812     }
813 
createSignatureAlgorithmsCertExtension(Vector supportedSignatureAlgorithms)814     public static byte[] createSignatureAlgorithmsCertExtension(Vector supportedSignatureAlgorithms)
815         throws IOException
816     {
817         return createSignatureAlgorithmsExtension(supportedSignatureAlgorithms);
818     }
819 
createStatusRequestExtension(CertificateStatusRequest statusRequest)820     public static byte[] createStatusRequestExtension(CertificateStatusRequest statusRequest)
821         throws IOException
822     {
823         if (statusRequest == null)
824         {
825             throw new TlsFatalAlert(AlertDescription.internal_error);
826         }
827 
828         ByteArrayOutputStream buf = new ByteArrayOutputStream();
829 
830         statusRequest.encode(buf);
831 
832         return buf.toByteArray();
833     }
834 
createStatusRequestV2Extension(Vector statusRequestV2)835     public static byte[] createStatusRequestV2Extension(Vector statusRequestV2)
836         throws IOException
837     {
838         if (statusRequestV2 == null || statusRequestV2.isEmpty())
839         {
840             throw new TlsFatalAlert(AlertDescription.internal_error);
841         }
842 
843         ByteArrayOutputStream buf = new ByteArrayOutputStream();
844 
845         // Placeholder for length
846         TlsUtils.writeUint16(0, buf);
847 
848         for (int i = 0; i < statusRequestV2.size(); ++i)
849         {
850             CertificateStatusRequestItemV2 entry = (CertificateStatusRequestItemV2)statusRequestV2.elementAt(i);
851             entry.encode(buf);
852         }
853 
854         return patchOpaque16(buf);
855     }
856 
createSupportedGroupsExtension(Vector namedGroups)857     public static byte[] createSupportedGroupsExtension(Vector namedGroups) throws IOException
858     {
859         if (namedGroups == null || namedGroups.isEmpty())
860         {
861             throw new TlsFatalAlert(AlertDescription.internal_error);
862         }
863 
864         int count = namedGroups.size();
865         int[] values = new int[count];
866         for (int i = 0; i < count; ++i)
867         {
868             values[i] = ((Integer)namedGroups.elementAt(i)).intValue();
869         }
870 
871         return TlsUtils.encodeUint16ArrayWithUint16Length(values);
872     }
873 
createSupportedPointFormatsExtension(short[] ecPointFormats)874     public static byte[] createSupportedPointFormatsExtension(short[] ecPointFormats) throws IOException
875     {
876         if (ecPointFormats == null || !Arrays.contains(ecPointFormats, ECPointFormat.uncompressed))
877         {
878             /*
879              * RFC 4492 5.1. If the Supported Point Formats Extension is indeed sent, it MUST
880              * contain the value 0 (uncompressed) as one of the items in the list of point formats.
881              */
882 
883             // NOTE: We add it at the start (highest preference)
884             ecPointFormats = Arrays.prepend(ecPointFormats, ECPointFormat.uncompressed);
885         }
886 
887         return TlsUtils.encodeUint8ArrayWithUint8Length(ecPointFormats);
888     }
889 
createSupportedVersionsExtensionClient(ProtocolVersion[] versions)890     public static byte[] createSupportedVersionsExtensionClient(ProtocolVersion[] versions) throws IOException
891     {
892         if (TlsUtils.isNullOrEmpty(versions) || versions.length > 127)
893         {
894             throw new TlsFatalAlert(AlertDescription.internal_error);
895         }
896 
897         int count = versions.length;
898         byte[] data = new byte[1 + count * 2];
899         TlsUtils.writeUint8(count * 2, data, 0);
900         for (int i = 0; i < count; ++i)
901         {
902             TlsUtils.writeVersion((ProtocolVersion)versions[i], data, 1 + i * 2);
903         }
904         return data;
905     }
906 
createSupportedVersionsExtensionServer(ProtocolVersion selectedVersion)907     public static byte[] createSupportedVersionsExtensionServer(ProtocolVersion selectedVersion) throws IOException
908     {
909         return TlsUtils.encodeVersion(selectedVersion);
910     }
911 
createTruncatedHMacExtension()912     public static byte[] createTruncatedHMacExtension()
913     {
914         return createEmptyExtensionData();
915     }
916 
createTrustedCAKeysExtensionClient(Vector trustedAuthoritiesList)917     public static byte[] createTrustedCAKeysExtensionClient(Vector trustedAuthoritiesList)
918         throws IOException
919     {
920         ByteArrayOutputStream buf = new ByteArrayOutputStream();
921 
922         // Placeholder for length
923         TlsUtils.writeUint16(0, buf);
924 
925         if (trustedAuthoritiesList != null)
926         {
927             for (int i = 0; i < trustedAuthoritiesList.size(); ++i)
928             {
929                 TrustedAuthority entry = (TrustedAuthority)trustedAuthoritiesList.elementAt(i);
930                 entry.encode(buf);
931             }
932         }
933 
934         return patchOpaque16(buf);
935     }
936 
createTrustedCAKeysExtensionServer()937     public static byte[] createTrustedCAKeysExtensionServer()
938     {
939         return createEmptyExtensionData();
940     }
941 
readEmptyExtensionData(byte[] extensionData)942     private static boolean readEmptyExtensionData(byte[] extensionData) throws IOException
943     {
944         if (extensionData == null)
945         {
946             throw new IllegalArgumentException("'extensionData' cannot be null");
947         }
948 
949         if (extensionData.length != 0)
950         {
951             throw new TlsFatalAlert(AlertDescription.illegal_parameter);
952         }
953 
954         return true;
955     }
956 
957     /**
958      * @return a {@link Vector} of {@link ProtocolName}
959      */
readALPNExtensionClient(byte[] extensionData)960     public static Vector readALPNExtensionClient(byte[] extensionData) throws IOException
961     {
962         if (extensionData == null)
963         {
964             throw new IllegalArgumentException("'extensionData' cannot be null");
965         }
966 
967         ByteArrayInputStream buf = new ByteArrayInputStream(extensionData);
968 
969         int length = TlsUtils.readUint16(buf);
970         if (length != (extensionData.length - 2))
971         {
972             throw new TlsFatalAlert(AlertDescription.decode_error);
973         }
974 
975         Vector protocol_name_list = new Vector();
976         while (buf.available() > 0)
977         {
978             ProtocolName protocolName = ProtocolName.parse(buf);
979 
980             protocol_name_list.addElement(protocolName);
981         }
982         return protocol_name_list;
983     }
984 
readALPNExtensionServer(byte[] extensionData)985     public static ProtocolName readALPNExtensionServer(byte[] extensionData) throws IOException
986     {
987         Vector protocol_name_list = readALPNExtensionClient(extensionData);
988         if (protocol_name_list.size() != 1)
989         {
990             throw new TlsFatalAlert(AlertDescription.decode_error);
991         }
992 
993         return (ProtocolName)protocol_name_list.elementAt(0);
994     }
995 
readCertificateAuthoritiesExtension(byte[] extensionData)996     public static Vector readCertificateAuthoritiesExtension(byte[] extensionData) throws IOException
997     {
998         if (extensionData == null)
999         {
1000             throw new IllegalArgumentException("'extensionData' cannot be null");
1001         }
1002         if (extensionData.length < 5)
1003         {
1004             throw new TlsFatalAlert(AlertDescription.decode_error);
1005         }
1006 
1007         ByteArrayInputStream buf = new ByteArrayInputStream(extensionData);
1008 
1009         int length = TlsUtils.readUint16(buf);
1010         if (length != (extensionData.length - 2))
1011         {
1012             throw new TlsFatalAlert(AlertDescription.decode_error);
1013         }
1014 
1015         Vector authorities = new Vector();
1016         while (buf.available() > 0)
1017         {
1018             byte[] derEncoding = TlsUtils.readOpaque16(buf, 1);
1019             ASN1Primitive asn1 = TlsUtils.readDERObject(derEncoding);
1020             authorities.addElement(X500Name.getInstance(asn1));
1021         }
1022         return authorities;
1023     }
1024 
readCertificateTypeExtensionClient(byte[] extensionData)1025     public static short[] readCertificateTypeExtensionClient(byte[] extensionData) throws IOException
1026     {
1027         short[] certificateTypes = TlsUtils.decodeUint8ArrayWithUint8Length(extensionData);
1028         if (certificateTypes.length < 1)
1029         {
1030             throw new TlsFatalAlert(AlertDescription.decode_error);
1031         }
1032         return certificateTypes;
1033     }
1034 
readCertificateTypeExtensionServer(byte[] extensionData)1035     public static short readCertificateTypeExtensionServer(byte[] extensionData) throws IOException
1036     {
1037         return TlsUtils.decodeUint8(extensionData);
1038     }
1039 
readClientCertificateURLExtension(byte[] extensionData)1040     public static boolean readClientCertificateURLExtension(byte[] extensionData) throws IOException
1041     {
1042         return readEmptyExtensionData(extensionData);
1043     }
1044 
readCookieExtension(byte[] extensionData)1045     public static byte[] readCookieExtension(byte[] extensionData) throws IOException
1046     {
1047         return TlsUtils.decodeOpaque16(extensionData, 1);
1048     }
1049 
readEarlyDataIndication(byte[] extensionData)1050     public static boolean readEarlyDataIndication(byte[] extensionData) throws IOException
1051     {
1052         return readEmptyExtensionData(extensionData);
1053     }
1054 
readEarlyDataMaxSize(byte[] extensionData)1055     public static long readEarlyDataMaxSize(byte[] extensionData) throws IOException
1056     {
1057         return TlsUtils.decodeUint32(extensionData);
1058     }
1059 
readEncryptThenMACExtension(byte[] extensionData)1060     public static boolean readEncryptThenMACExtension(byte[] extensionData) throws IOException
1061     {
1062         return readEmptyExtensionData(extensionData);
1063     }
1064 
readExtendedMasterSecretExtension(byte[] extensionData)1065     public static boolean readExtendedMasterSecretExtension(byte[] extensionData) throws IOException
1066     {
1067         return readEmptyExtensionData(extensionData);
1068     }
1069 
readHeartbeatExtension(byte[] extensionData)1070     public static HeartbeatExtension readHeartbeatExtension(byte[] extensionData)
1071         throws IOException
1072     {
1073         if (extensionData == null)
1074         {
1075             throw new IllegalArgumentException("'extensionData' cannot be null");
1076         }
1077 
1078         ByteArrayInputStream buf = new ByteArrayInputStream(extensionData);
1079 
1080         HeartbeatExtension heartbeatExtension = HeartbeatExtension.parse(buf);
1081 
1082         TlsProtocol.assertEmpty(buf);
1083 
1084         return heartbeatExtension;
1085     }
1086 
readKeyShareClientHello(byte[] extensionData)1087     public static Vector readKeyShareClientHello(byte[] extensionData)
1088         throws IOException
1089     {
1090         if (extensionData == null)
1091         {
1092             throw new IllegalArgumentException("'extensionData' cannot be null");
1093         }
1094 
1095         /*
1096          * TODO[tls13] Clients MUST NOT offer multiple KeyShareEntry values for the same group.
1097          * Clients MUST NOT offer any KeyShareEntry values for groups not listed in the client's
1098          * "supported_groups" extension. Servers MAY check for violations of these rules and abort
1099          * the handshake with an "illegal_parameter" alert if one is violated.
1100          */
1101 
1102         ByteArrayInputStream buf = new ByteArrayInputStream(extensionData);
1103 
1104         int length = TlsUtils.readUint16(buf);
1105         if (length != (extensionData.length - 2))
1106         {
1107             throw new TlsFatalAlert(AlertDescription.decode_error);
1108         }
1109 
1110         Vector clientShares = new Vector();
1111         while (buf.available() > 0)
1112         {
1113             KeyShareEntry clientShare = KeyShareEntry.parse(buf);
1114 
1115             clientShares.addElement(clientShare);
1116         }
1117         return clientShares;
1118     }
1119 
readKeyShareHelloRetryRequest(byte[] extensionData)1120     public static int readKeyShareHelloRetryRequest(byte[] extensionData)
1121         throws IOException
1122     {
1123         return TlsUtils.decodeUint16(extensionData);
1124     }
1125 
readKeyShareServerHello(byte[] extensionData)1126     public static KeyShareEntry readKeyShareServerHello(byte[] extensionData)
1127         throws IOException
1128     {
1129         if (extensionData == null)
1130         {
1131             throw new IllegalArgumentException("'extensionData' cannot be null");
1132         }
1133 
1134         ByteArrayInputStream buf = new ByteArrayInputStream(extensionData);
1135 
1136         KeyShareEntry serverShare = KeyShareEntry.parse(buf);
1137 
1138         TlsProtocol.assertEmpty(buf);
1139 
1140         return serverShare;
1141     }
1142 
readMaxFragmentLengthExtension(byte[] extensionData)1143     public static short readMaxFragmentLengthExtension(byte[] extensionData)
1144         throws IOException
1145     {
1146         return TlsUtils.decodeUint8(extensionData);
1147     }
1148 
readOIDFiltersExtension(byte[] extensionData)1149     public static Hashtable readOIDFiltersExtension(byte[] extensionData) throws IOException
1150     {
1151         if (extensionData == null)
1152         {
1153             throw new IllegalArgumentException("'extensionData' cannot be null");
1154         }
1155         if (extensionData.length < 2)
1156         {
1157             throw new TlsFatalAlert(AlertDescription.decode_error);
1158         }
1159 
1160         ByteArrayInputStream buf = new ByteArrayInputStream(extensionData);
1161 
1162         int length = TlsUtils.readUint16(buf);
1163         if (length != (extensionData.length - 2))
1164         {
1165             throw new TlsFatalAlert(AlertDescription.decode_error);
1166         }
1167 
1168         Hashtable filters = new Hashtable();
1169         while (buf.available() > 0)
1170         {
1171             byte[] derEncoding = TlsUtils.readOpaque8(buf, 1);
1172             ASN1Primitive asn1 = TlsUtils.readDERObject(derEncoding);
1173             ASN1ObjectIdentifier certificateExtensionOID = ASN1ObjectIdentifier.getInstance(asn1);
1174 
1175             if (filters.containsKey(certificateExtensionOID))
1176             {
1177                 throw new TlsFatalAlert(AlertDescription.illegal_parameter);
1178             }
1179 
1180             byte[] certificateExtensionValues = TlsUtils.readOpaque16(buf);
1181 
1182             filters.put(certificateExtensionOID, certificateExtensionValues);
1183         }
1184         return filters;
1185     }
1186 
readPaddingExtension(byte[] extensionData)1187     public static int readPaddingExtension(byte[] extensionData)
1188         throws IOException
1189     {
1190         if (extensionData == null)
1191         {
1192             throw new IllegalArgumentException("'extensionData' cannot be null");
1193         }
1194         int diff = 0;
1195         for (int i = 0; i < extensionData.length; ++i)
1196         {
1197             diff |= extensionData[i];
1198         }
1199         if (diff != 0)
1200         {
1201             throw new TlsFatalAlert(AlertDescription.illegal_parameter);
1202         }
1203         return extensionData.length;
1204     }
1205 
readPostHandshakeAuthExtension(byte[] extensionData)1206     public static boolean readPostHandshakeAuthExtension(byte[] extensionData) throws IOException
1207     {
1208         return readEmptyExtensionData(extensionData);
1209     }
1210 
readPreSharedKeyClientHello(byte[] extensionData)1211     public static OfferedPsks readPreSharedKeyClientHello(byte[] extensionData) throws IOException
1212     {
1213         if (extensionData == null)
1214         {
1215             throw new IllegalArgumentException("'extensionData' cannot be null");
1216         }
1217 
1218         ByteArrayInputStream buf = new ByteArrayInputStream(extensionData);
1219 
1220         OfferedPsks offeredPsks = OfferedPsks.parse(buf);
1221 
1222         TlsProtocol.assertEmpty(buf);
1223 
1224         return offeredPsks;
1225     }
1226 
readPreSharedKeyServerHello(byte[] extensionData)1227     public static int readPreSharedKeyServerHello(byte[] extensionData) throws IOException
1228     {
1229         return TlsUtils.decodeUint16(extensionData);
1230     }
1231 
readPSKKeyExchangeModesExtension(byte[] extensionData)1232     public static short[] readPSKKeyExchangeModesExtension(byte[] extensionData) throws IOException
1233     {
1234         short[] modes = TlsUtils.decodeUint8ArrayWithUint8Length(extensionData);
1235         if (modes.length < 1)
1236         {
1237             throw new TlsFatalAlert(AlertDescription.decode_error);
1238         }
1239         return modes;
1240     }
1241 
readRecordSizeLimitExtension(byte[] extensionData)1242     public static int readRecordSizeLimitExtension(byte[] extensionData)
1243         throws IOException
1244     {
1245         int recordSizeLimit = TlsUtils.decodeUint16(extensionData);
1246         if (recordSizeLimit < 64)
1247         {
1248             throw new TlsFatalAlert(AlertDescription.illegal_parameter);
1249         }
1250 
1251         return recordSizeLimit;
1252     }
1253 
readServerNameExtensionClient(byte[] extensionData)1254     public static Vector readServerNameExtensionClient(byte[] extensionData)
1255         throws IOException
1256     {
1257         if (extensionData == null)
1258         {
1259             throw new IllegalArgumentException("'extensionData' cannot be null");
1260         }
1261 
1262         ByteArrayInputStream buf = new ByteArrayInputStream(extensionData);
1263 
1264         ServerNameList serverNameList = ServerNameList.parse(buf);
1265 
1266         TlsProtocol.assertEmpty(buf);
1267 
1268         return serverNameList.getServerNameList();
1269     }
1270 
readServerNameExtensionServer(byte[] extensionData)1271     public static boolean readServerNameExtensionServer(byte[] extensionData) throws IOException
1272     {
1273         return readEmptyExtensionData(extensionData);
1274     }
1275 
readSignatureAlgorithmsExtension(byte[] extensionData)1276     public static Vector readSignatureAlgorithmsExtension(byte[] extensionData)
1277         throws IOException
1278     {
1279         if (extensionData == null)
1280         {
1281             throw new IllegalArgumentException("'extensionData' cannot be null");
1282         }
1283 
1284         ByteArrayInputStream buf = new ByteArrayInputStream(extensionData);
1285 
1286         Vector supported_signature_algorithms = TlsUtils.parseSupportedSignatureAlgorithms(buf);
1287 
1288         TlsProtocol.assertEmpty(buf);
1289 
1290         return supported_signature_algorithms;
1291     }
1292 
readSignatureAlgorithmsCertExtension(byte[] extensionData)1293     public static Vector readSignatureAlgorithmsCertExtension(byte[] extensionData)
1294         throws IOException
1295     {
1296         return readSignatureAlgorithmsExtension(extensionData);
1297     }
1298 
readStatusRequestExtension(byte[] extensionData)1299     public static CertificateStatusRequest readStatusRequestExtension(byte[] extensionData)
1300         throws IOException
1301     {
1302         if (extensionData == null)
1303         {
1304             throw new IllegalArgumentException("'extensionData' cannot be null");
1305         }
1306 
1307         ByteArrayInputStream buf = new ByteArrayInputStream(extensionData);
1308 
1309         CertificateStatusRequest statusRequest = CertificateStatusRequest.parse(buf);
1310 
1311         TlsProtocol.assertEmpty(buf);
1312 
1313         return statusRequest;
1314     }
1315 
readStatusRequestV2Extension(byte[] extensionData)1316     public static Vector readStatusRequestV2Extension(byte[] extensionData)
1317         throws IOException
1318     {
1319         if (extensionData == null)
1320         {
1321             throw new IllegalArgumentException("'extensionData' cannot be null");
1322         }
1323         if (extensionData.length < 3)
1324         {
1325             throw new TlsFatalAlert(AlertDescription.decode_error);
1326         }
1327 
1328         ByteArrayInputStream buf = new ByteArrayInputStream(extensionData);
1329 
1330         int length = TlsUtils.readUint16(buf);
1331         if (length != (extensionData.length - 2))
1332         {
1333             throw new TlsFatalAlert(AlertDescription.decode_error);
1334         }
1335 
1336         Vector statusRequestV2 = new Vector();
1337         while (buf.available() > 0)
1338         {
1339             CertificateStatusRequestItemV2 entry = CertificateStatusRequestItemV2.parse(buf);
1340             statusRequestV2.add(entry);
1341         }
1342         return statusRequestV2;
1343     }
1344 
readSupportedGroupsExtension(byte[] extensionData)1345     public static int[] readSupportedGroupsExtension(byte[] extensionData) throws IOException
1346     {
1347         if (extensionData == null)
1348         {
1349             throw new IllegalArgumentException("'extensionData' cannot be null");
1350         }
1351 
1352         ByteArrayInputStream buf = new ByteArrayInputStream(extensionData);
1353 
1354         int length = TlsUtils.readUint16(buf);
1355         if (length < 2 || (length & 1) != 0)
1356         {
1357             throw new TlsFatalAlert(AlertDescription.decode_error);
1358         }
1359 
1360         int[] namedGroups = TlsUtils.readUint16Array(length / 2, buf);
1361 
1362         TlsProtocol.assertEmpty(buf);
1363 
1364         return namedGroups;
1365     }
1366 
readSupportedPointFormatsExtension(byte[] extensionData)1367     public static short[] readSupportedPointFormatsExtension(byte[] extensionData) throws IOException
1368     {
1369         short[] ecPointFormats = TlsUtils.decodeUint8ArrayWithUint8Length(extensionData);
1370         if (!Arrays.contains(ecPointFormats, ECPointFormat.uncompressed))
1371         {
1372             /*
1373              * RFC 4492 5.1. If the Supported Point Formats Extension is indeed sent, it MUST
1374              * contain the value 0 (uncompressed) as one of the items in the list of point formats.
1375              */
1376             throw new TlsFatalAlert(AlertDescription.illegal_parameter);
1377         }
1378         return ecPointFormats;
1379     }
1380 
readSupportedVersionsExtensionClient(byte[] extensionData)1381     public static ProtocolVersion[] readSupportedVersionsExtensionClient(byte[] extensionData) throws IOException
1382     {
1383         if (extensionData == null)
1384         {
1385             throw new IllegalArgumentException("'extensionData' cannot be null");
1386         }
1387         if (extensionData.length < 3 || extensionData.length > 255 || (extensionData.length & 1) == 0)
1388         {
1389             throw new TlsFatalAlert(AlertDescription.decode_error);
1390         }
1391 
1392         int length = TlsUtils.readUint8(extensionData, 0);
1393         if (length != (extensionData.length - 1))
1394         {
1395             throw new TlsFatalAlert(AlertDescription.decode_error);
1396         }
1397 
1398         int count = length / 2;
1399         ProtocolVersion[] versions = new ProtocolVersion[count];
1400         for (int i = 0; i < count; ++i)
1401         {
1402             versions[i] = TlsUtils.readVersion(extensionData, 1 + i * 2);
1403         }
1404         return versions;
1405     }
1406 
readSupportedVersionsExtensionServer(byte[] extensionData)1407     public static ProtocolVersion readSupportedVersionsExtensionServer(byte[] extensionData) throws IOException
1408     {
1409         if (extensionData == null)
1410         {
1411             throw new IllegalArgumentException("'extensionData' cannot be null");
1412         }
1413         if (extensionData.length != 2)
1414         {
1415             throw new TlsFatalAlert(AlertDescription.decode_error);
1416         }
1417         return TlsUtils.readVersion(extensionData, 0);
1418     }
1419 
readTruncatedHMacExtension(byte[] extensionData)1420     public static boolean readTruncatedHMacExtension(byte[] extensionData) throws IOException
1421     {
1422         return readEmptyExtensionData(extensionData);
1423     }
1424 
readTrustedCAKeysExtensionClient(byte[] extensionData)1425     public static Vector readTrustedCAKeysExtensionClient(byte[] extensionData) throws IOException
1426     {
1427         if (extensionData == null)
1428         {
1429             throw new IllegalArgumentException("'extensionData' cannot be null");
1430         }
1431         if (extensionData.length < 2)
1432         {
1433             throw new TlsFatalAlert(AlertDescription.decode_error);
1434         }
1435 
1436         ByteArrayInputStream buf = new ByteArrayInputStream(extensionData);
1437 
1438         int length = TlsUtils.readUint16(buf);
1439         if (length != (extensionData.length - 2))
1440         {
1441             throw new TlsFatalAlert(AlertDescription.decode_error);
1442         }
1443 
1444         Vector trusted_authorities_list = new Vector();
1445         while (buf.available() > 0)
1446         {
1447             TrustedAuthority entry = TrustedAuthority.parse(buf);
1448             trusted_authorities_list.addElement(entry);
1449         }
1450         return trusted_authorities_list;
1451     }
1452 
readTrustedCAKeysExtensionServer(byte[] extensionData)1453     public static boolean readTrustedCAKeysExtensionServer(byte[] extensionData) throws IOException
1454     {
1455         return readEmptyExtensionData(extensionData);
1456     }
1457 
patchOpaque16(ByteArrayOutputStream buf)1458     private static byte[] patchOpaque16(ByteArrayOutputStream buf) throws IOException
1459     {
1460         int length = buf.size() - 2;
1461         TlsUtils.checkUint16(length);
1462         byte[] extensionData = buf.toByteArray();
1463         TlsUtils.writeUint16(length, extensionData, 0);
1464         return extensionData;
1465     }
1466 }
1467