Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/sun/security/ssl/ECPointFormatsExtension.java
38830 views
1
/*
2
* Copyright (c) 2015, 2018, 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.SupportedGroupsExtension.NamedGroupType;
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(ByteBuffer m) throws IOException {
68
if (!m.hasRemaining()) {
69
throw new SSLProtocolException(
70
"Invalid ec_point_formats extension: " +
71
"insufficient data");
72
}
73
74
this.formats = Record.getBytes8(m);
75
}
76
77
private boolean hasUncompressedFormat() {
78
for (byte format : formats) {
79
if (format == ECPointFormat.UNCOMPRESSED.id) {
80
return true;
81
}
82
}
83
84
return false;
85
}
86
87
@Override
88
public String toString() {
89
MessageFormat messageFormat = new MessageFormat(
90
"\"formats\": '['{0}']'", Locale.ENGLISH);
91
if (formats == null || formats.length == 0) {
92
Object[] messageFields = {
93
"<no EC point format specified>"
94
};
95
return messageFormat.format(messageFields);
96
} else {
97
StringBuilder builder = new StringBuilder(512);
98
boolean isFirst = true;
99
for (byte pf : formats) {
100
if (isFirst) {
101
isFirst = false;
102
} else {
103
builder.append(", ");
104
}
105
106
builder.append(ECPointFormat.nameOf(pf));
107
}
108
109
Object[] messageFields = {
110
builder.toString()
111
};
112
113
return messageFormat.format(messageFields);
114
}
115
}
116
}
117
118
private static final class ECPointFormatsStringizer implements SSLStringizer {
119
@Override
120
public String toString(ByteBuffer buffer) {
121
try {
122
return (new ECPointFormatsSpec(buffer)).toString();
123
} catch (IOException ioe) {
124
// For debug logging only, so please swallow exceptions.
125
return ioe.getMessage();
126
}
127
}
128
}
129
130
private static enum ECPointFormat {
131
UNCOMPRESSED ((byte)0, "uncompressed"),
132
ANSIX962_COMPRESSED_PRIME ((byte)1, "ansiX962_compressed_prime"),
133
FMT_ANSIX962_COMPRESSED_CHAR2 ((byte)2, "ansiX962_compressed_char2");
134
135
final byte id;
136
final String name;
137
138
private ECPointFormat(byte id, String name) {
139
this.id = id;
140
this.name = name;
141
}
142
143
static String nameOf(int id) {
144
for (ECPointFormat pf: ECPointFormat.values()) {
145
if (pf.id == id) {
146
return pf.name;
147
}
148
}
149
return "UNDEFINED-EC-POINT-FORMAT(" + id + ")";
150
}
151
}
152
153
/**
154
* Network data producer of a "ec_point_formats" extension in
155
* the ClientHello handshake message.
156
*/
157
private static final
158
class CHECPointFormatsProducer implements HandshakeProducer {
159
// Prevent instantiation of this class.
160
private CHECPointFormatsProducer() {
161
// blank
162
}
163
164
@Override
165
public byte[] produce(ConnectionContext context,
166
HandshakeMessage message) throws IOException {
167
// The producing happens in client side only.
168
ClientHandshakeContext chc = (ClientHandshakeContext)context;
169
170
// Is it a supported and enabled extension?
171
if (!chc.sslConfig.isAvailable(CH_EC_POINT_FORMATS)) {
172
if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
173
SSLLogger.fine(
174
"Ignore unavailable ec_point_formats extension");
175
}
176
return null;
177
}
178
179
// Produce the extension.
180
//
181
// produce the extension only if EC cipher suite is activated.
182
if (NamedGroupType.NAMED_GROUP_ECDHE.isSupported(
183
chc.activeCipherSuites)) {
184
// We are using uncompressed ECPointFormat only at present.
185
byte[] extData = new byte[] {0x01, 0x00};
186
187
// Update the context.
188
chc.handshakeExtensions.put(
189
CH_EC_POINT_FORMATS, ECPointFormatsSpec.DEFAULT);
190
191
return extData;
192
}
193
194
if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
195
SSLLogger.fine(
196
"Need no ec_point_formats extension");
197
}
198
return null;
199
}
200
}
201
202
/**
203
* Network data consumer of a "ec_point_formats" extension in
204
* the ClientHello handshake message.
205
*/
206
private static final
207
class CHECPointFormatsConsumer implements ExtensionConsumer {
208
// Prevent instantiation of this class.
209
private CHECPointFormatsConsumer() {
210
// blank
211
}
212
213
@Override
214
public void consume(ConnectionContext context,
215
HandshakeMessage message, ByteBuffer buffer) throws IOException {
216
217
// The consuming happens in server side only.
218
ServerHandshakeContext shc = (ServerHandshakeContext)context;
219
220
// Is it a supported and enabled extension?
221
if (!shc.sslConfig.isAvailable(CH_EC_POINT_FORMATS)) {
222
if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
223
SSLLogger.fine(
224
"Ignore unavailable ec_point_formats extension");
225
}
226
return; // ignore the extension
227
}
228
229
// Parse the extension.
230
ECPointFormatsSpec spec;
231
try {
232
spec = new ECPointFormatsSpec(buffer);
233
} catch (IOException ioe) {
234
throw shc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, ioe);
235
}
236
237
// per RFC 4492, uncompressed points must always be supported.
238
if (!spec.hasUncompressedFormat()) {
239
throw shc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
240
"Invalid ec_point_formats extension data: " +
241
"peer does not support uncompressed points");
242
}
243
244
// Update the context.
245
shc.handshakeExtensions.put(CH_EC_POINT_FORMATS, spec);
246
247
// No impact on session resumption, as only uncompressed points
248
// are supported at present.
249
}
250
}
251
252
/**
253
* Network data consumer of a "ec_point_formats" extension in
254
* the ServerHello handshake message.
255
*/
256
private static final
257
class SHECPointFormatsConsumer implements ExtensionConsumer {
258
// Prevent instantiation of this class.
259
private SHECPointFormatsConsumer() {
260
// blank
261
}
262
263
@Override
264
public void consume(ConnectionContext context,
265
HandshakeMessage message, ByteBuffer buffer) throws IOException {
266
267
// The consuming happens in client side only.
268
ClientHandshakeContext chc = (ClientHandshakeContext)context;
269
270
// In response to "ec_point_formats" extension request only
271
ECPointFormatsSpec requestedSpec = (ECPointFormatsSpec)
272
chc.handshakeExtensions.get(CH_EC_POINT_FORMATS);
273
if (requestedSpec == null) {
274
throw chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
275
"Unexpected ec_point_formats extension in ServerHello");
276
}
277
278
// Parse the extension.
279
ECPointFormatsSpec spec;
280
try {
281
spec = new ECPointFormatsSpec(buffer);
282
} catch (IOException ioe) {
283
throw chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, ioe);
284
}
285
286
// per RFC 4492, uncompressed points must always be supported.
287
if (!spec.hasUncompressedFormat()) {
288
throw chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
289
"Invalid ec_point_formats extension data: " +
290
"peer does not support uncompressed points");
291
}
292
293
// Update the context.
294
chc.handshakeExtensions.put(CH_EC_POINT_FORMATS, spec);
295
296
// No impact on session resumption, as only uncompressed points
297
// are supported at present.
298
}
299
}
300
}
301
302