Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.base/share/classes/sun/security/ssl/ECPointFormatsExtension.java
41159 views
1
/*
2
* Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation. Oracle designates this
8
* particular file as subject to the "Classpath" exception as provided
9
* by Oracle in the LICENSE file that accompanied this code.
10
*
11
* This code is distributed in the hope that it will be useful, but WITHOUT
12
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
* version 2 for more details (a copy is included in the LICENSE file that
15
* accompanied this code).
16
*
17
* You should have received a copy of the GNU General Public License version
18
* 2 along with this work; if not, write to the Free Software Foundation,
19
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20
*
21
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22
* or visit www.oracle.com if you need additional information or have any
23
* questions.
24
*/
25
26
package sun.security.ssl;
27
28
import java.io.IOException;
29
import java.nio.ByteBuffer;
30
import java.text.MessageFormat;
31
import java.util.Locale;
32
import javax.net.ssl.SSLProtocolException;
33
import static sun.security.ssl.SSLExtension.CH_EC_POINT_FORMATS;
34
import sun.security.ssl.SSLExtension.ExtensionConsumer;
35
import sun.security.ssl.SSLExtension.SSLExtensionSpec;
36
import sun.security.ssl.SSLHandshake.HandshakeMessage;
37
import sun.security.ssl.NamedGroup.NamedGroupSpec;
38
39
/**
40
* Pack of the "ec_point_formats" extensions [RFC 4492].
41
*/
42
final class ECPointFormatsExtension {
43
static final HandshakeProducer chNetworkProducer =
44
new CHECPointFormatsProducer();
45
static final ExtensionConsumer chOnLoadConsumer =
46
new CHECPointFormatsConsumer();
47
48
static final ExtensionConsumer shOnLoadConsumer =
49
new SHECPointFormatsConsumer();
50
51
static final SSLStringizer epfStringizer =
52
new ECPointFormatsStringizer();
53
54
/**
55
* The "ec_point_formats" extension.
56
*/
57
static class ECPointFormatsSpec implements SSLExtensionSpec {
58
static final ECPointFormatsSpec DEFAULT =
59
new ECPointFormatsSpec(new byte[] {ECPointFormat.UNCOMPRESSED.id});
60
61
final byte[] formats;
62
63
ECPointFormatsSpec(byte[] formats) {
64
this.formats = formats;
65
}
66
67
private ECPointFormatsSpec(HandshakeContext hc,
68
ByteBuffer m) throws IOException {
69
if (!m.hasRemaining()) {
70
throw hc.conContext.fatal(Alert.DECODE_ERROR,
71
new SSLProtocolException(
72
"Invalid ec_point_formats extension: " +
73
"insufficient data"));
74
}
75
76
this.formats = Record.getBytes8(m);
77
}
78
79
private boolean hasUncompressedFormat() {
80
for (byte format : formats) {
81
if (format == ECPointFormat.UNCOMPRESSED.id) {
82
return true;
83
}
84
}
85
86
return false;
87
}
88
89
@Override
90
public String toString() {
91
MessageFormat messageFormat = new MessageFormat(
92
"\"formats\": '['{0}']'", Locale.ENGLISH);
93
if (formats == null || formats.length == 0) {
94
Object[] messageFields = {
95
"<no EC point format specified>"
96
};
97
return messageFormat.format(messageFields);
98
} else {
99
StringBuilder builder = new StringBuilder(512);
100
boolean isFirst = true;
101
for (byte pf : formats) {
102
if (isFirst) {
103
isFirst = false;
104
} else {
105
builder.append(", ");
106
}
107
108
builder.append(ECPointFormat.nameOf(pf));
109
}
110
111
Object[] messageFields = {
112
builder.toString()
113
};
114
115
return messageFormat.format(messageFields);
116
}
117
}
118
}
119
120
private static final class ECPointFormatsStringizer implements SSLStringizer {
121
@Override
122
public String toString(HandshakeContext hc, ByteBuffer buffer) {
123
try {
124
return (new ECPointFormatsSpec(hc, buffer)).toString();
125
} catch (IOException ioe) {
126
// For debug logging only, so please swallow exceptions.
127
return ioe.getMessage();
128
}
129
}
130
}
131
132
private static enum ECPointFormat {
133
UNCOMPRESSED ((byte)0, "uncompressed"),
134
ANSIX962_COMPRESSED_PRIME ((byte)1, "ansiX962_compressed_prime"),
135
FMT_ANSIX962_COMPRESSED_CHAR2 ((byte)2, "ansiX962_compressed_char2");
136
137
final byte id;
138
final String name;
139
140
private ECPointFormat(byte id, String name) {
141
this.id = id;
142
this.name = name;
143
}
144
145
static String nameOf(int id) {
146
for (ECPointFormat pf: ECPointFormat.values()) {
147
if (pf.id == id) {
148
return pf.name;
149
}
150
}
151
return "UNDEFINED-EC-POINT-FORMAT(" + id + ")";
152
}
153
}
154
155
/**
156
* Network data producer of a "ec_point_formats" extension in
157
* the ClientHello handshake message.
158
*/
159
private static final
160
class CHECPointFormatsProducer implements HandshakeProducer {
161
// Prevent instantiation of this class.
162
private CHECPointFormatsProducer() {
163
// blank
164
}
165
166
@Override
167
public byte[] produce(ConnectionContext context,
168
HandshakeMessage message) throws IOException {
169
// The producing happens in client side only.
170
ClientHandshakeContext chc = (ClientHandshakeContext)context;
171
172
// Is it a supported and enabled extension?
173
if (!chc.sslConfig.isAvailable(CH_EC_POINT_FORMATS)) {
174
if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
175
SSLLogger.fine(
176
"Ignore unavailable ec_point_formats extension");
177
}
178
return null;
179
}
180
181
// Produce the extension.
182
//
183
// produce the extension only if EC cipher suite is activated.
184
if (NamedGroupSpec.NAMED_GROUP_ECDHE.isSupported(
185
chc.activeCipherSuites)) {
186
// We are using uncompressed ECPointFormat only at present.
187
byte[] extData = new byte[] {0x01, 0x00};
188
189
// Update the context.
190
chc.handshakeExtensions.put(
191
CH_EC_POINT_FORMATS, ECPointFormatsSpec.DEFAULT);
192
193
return extData;
194
}
195
196
if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
197
SSLLogger.fine(
198
"Need no ec_point_formats extension");
199
}
200
return null;
201
}
202
}
203
204
/**
205
* Network data consumer of a "ec_point_formats" extension in
206
* the ClientHello handshake message.
207
*/
208
private static final
209
class CHECPointFormatsConsumer implements ExtensionConsumer {
210
// Prevent instantiation of this class.
211
private CHECPointFormatsConsumer() {
212
// blank
213
}
214
215
@Override
216
public void consume(ConnectionContext context,
217
HandshakeMessage message, ByteBuffer buffer) throws IOException {
218
219
// The consuming happens in server side only.
220
ServerHandshakeContext shc = (ServerHandshakeContext)context;
221
222
// Is it a supported and enabled extension?
223
if (!shc.sslConfig.isAvailable(CH_EC_POINT_FORMATS)) {
224
if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
225
SSLLogger.fine(
226
"Ignore unavailable ec_point_formats extension");
227
}
228
return; // ignore the extension
229
}
230
231
// Parse the extension.
232
ECPointFormatsSpec spec = new ECPointFormatsSpec(shc, buffer);
233
234
// per RFC 4492, uncompressed points must always be supported.
235
if (!spec.hasUncompressedFormat()) {
236
throw shc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
237
"Invalid ec_point_formats extension data: " +
238
"peer does not support uncompressed points");
239
}
240
241
// Update the context.
242
shc.handshakeExtensions.put(CH_EC_POINT_FORMATS, spec);
243
244
// No impact on session resumption, as only uncompressed points
245
// are supported at present.
246
}
247
}
248
249
/**
250
* Network data consumer of a "ec_point_formats" extension in
251
* the ServerHello handshake message.
252
*/
253
private static final
254
class SHECPointFormatsConsumer implements ExtensionConsumer {
255
// Prevent instantiation of this class.
256
private SHECPointFormatsConsumer() {
257
// blank
258
}
259
260
@Override
261
public void consume(ConnectionContext context,
262
HandshakeMessage message, ByteBuffer buffer) throws IOException {
263
264
// The consuming happens in client side only.
265
ClientHandshakeContext chc = (ClientHandshakeContext)context;
266
267
// In response to "ec_point_formats" extension request only
268
ECPointFormatsSpec requestedSpec = (ECPointFormatsSpec)
269
chc.handshakeExtensions.get(CH_EC_POINT_FORMATS);
270
if (requestedSpec == null) {
271
throw chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
272
"Unexpected ec_point_formats extension in ServerHello");
273
}
274
275
// Parse the extension.
276
ECPointFormatsSpec spec = new ECPointFormatsSpec(chc, buffer);
277
278
// per RFC 4492, uncompressed points must always be supported.
279
if (!spec.hasUncompressedFormat()) {
280
throw chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
281
"Invalid ec_point_formats extension data: " +
282
"peer does not support uncompressed points");
283
}
284
285
// Update the context.
286
chc.handshakeExtensions.put(CH_EC_POINT_FORMATS, spec);
287
288
// No impact on session resumption, as only uncompressed points
289
// are supported at present.
290
}
291
}
292
}
293
294