Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_jdk
提交
3faae241
D
dragonwell8_jdk
项目概览
openanolis
/
dragonwell8_jdk
通知
4
Star
2
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
D
dragonwell8_jdk
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
3faae241
编写于
6月 21, 2017
作者:
I
igerasim
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
8182614: Backout JDK-8140436 from 8u161
Reviewed-by: xuelei
上级
25f17276
变更
17
隐藏空白更改
内联
并排
Showing
17 changed file
with
753 addition
and
1798 deletion
+753
-1798
src/share/classes/sun/security/ssl/CipherSuite.java
src/share/classes/sun/security/ssl/CipherSuite.java
+22
-23
src/share/classes/sun/security/ssl/CipherSuiteList.java
src/share/classes/sun/security/ssl/CipherSuiteList.java
+20
-26
src/share/classes/sun/security/ssl/ClientHandshaker.java
src/share/classes/sun/security/ssl/ClientHandshaker.java
+9
-29
src/share/classes/sun/security/ssl/DHCrypt.java
src/share/classes/sun/security/ssl/DHCrypt.java
+145
-10
src/share/classes/sun/security/ssl/ECDHCrypt.java
src/share/classes/sun/security/ssl/ECDHCrypt.java
+5
-5
src/share/classes/sun/security/ssl/EllipticCurvesExtension.java
...are/classes/sun/security/ssl/EllipticCurvesExtension.java
+397
-0
src/share/classes/sun/security/ssl/ExtensionType.java
src/share/classes/sun/security/ssl/ExtensionType.java
+17
-17
src/share/classes/sun/security/ssl/HandshakeMessage.java
src/share/classes/sun/security/ssl/HandshakeMessage.java
+16
-32
src/share/classes/sun/security/ssl/Handshaker.java
src/share/classes/sun/security/ssl/Handshaker.java
+72
-53
src/share/classes/sun/security/ssl/HelloExtensions.java
src/share/classes/sun/security/ssl/HelloExtensions.java
+4
-4
src/share/classes/sun/security/ssl/NamedGroup.java
src/share/classes/sun/security/ssl/NamedGroup.java
+0
-169
src/share/classes/sun/security/ssl/NamedGroupType.java
src/share/classes/sun/security/ssl/NamedGroupType.java
+0
-32
src/share/classes/sun/security/ssl/PredefinedDHParameterSpecs.java
.../classes/sun/security/ssl/PredefinedDHParameterSpecs.java
+0
-314
src/share/classes/sun/security/ssl/ServerHandshaker.java
src/share/classes/sun/security/ssl/ServerHandshaker.java
+33
-122
test/javax/net/ssl/templates/SSLSocketTemplate.java
test/javax/net/ssl/templates/SSLSocketTemplate.java
+0
-844
test/sun/security/ssl/com/sun/net/ssl/internal/ssl/DHKeyExchange/DHEKeySizing.java
.../sun/net/ssl/internal/ssl/DHKeyExchange/DHEKeySizing.java
+13
-24
test/sun/security/ssl/com/sun/net/ssl/internal/ssl/DHKeyExchange/UseStrongDHSizes.java
.../net/ssl/internal/ssl/DHKeyExchange/UseStrongDHSizes.java
+0
-94
未找到文件。
src/share/classes/sun/security/ssl/CipherSuite.java
浏览文件 @
3faae241
/*
* Copyright (c) 2002, 201
7
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2002, 201
6
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
...
...
@@ -42,7 +42,6 @@ import static sun.security.ssl.CipherSuite.KeyExchange.*;
import
static
sun
.
security
.
ssl
.
CipherSuite
.
PRF
.*;
import
static
sun
.
security
.
ssl
.
CipherSuite
.
CipherType
.*;
import
static
sun
.
security
.
ssl
.
JsseJce
.*;
import
static
sun
.
security
.
ssl
.
NamedGroupType
.*;
/**
* An SSL/TLS CipherSuite. Constants for the standard key exchange, cipher,
...
...
@@ -327,38 +326,38 @@ final class CipherSuite implements Comparable<CipherSuite> {
static
enum
KeyExchange
{
// key exchange algorithms
K_NULL
(
"NULL"
,
false
,
NAMED_GROUP_NONE
),
K_RSA
(
"RSA"
,
true
,
NAMED_GROUP_NONE
),
K_RSA_EXPORT
(
"RSA_EXPORT"
,
true
,
NAMED_GROUP_NONE
),
K_DH_RSA
(
"DH_RSA"
,
false
,
NAMED_GROUP_NONE
),
K_DH_DSS
(
"DH_DSS"
,
false
,
NAMED_GROUP_NONE
),
K_DHE_DSS
(
"DHE_DSS"
,
true
,
NAMED_GROUP_FFDHE
),
K_DHE_RSA
(
"DHE_RSA"
,
true
,
NAMED_GROUP_FFDHE
),
K_DH_ANON
(
"DH_anon"
,
true
,
NAMED_GROUP_FFDHE
),
K_ECDH_ECDSA
(
"ECDH_ECDSA"
,
ALLOW_ECC
,
NAMED_GROUP_ECDHE
),
K_ECDH_RSA
(
"ECDH_RSA"
,
ALLOW_ECC
,
NAMED_GROUP_ECDHE
),
K_ECDHE_ECDSA
(
"ECDHE_ECDSA"
,
ALLOW_ECC
,
NAMED_GROUP_ECDHE
),
K_ECDHE_RSA
(
"ECDHE_RSA"
,
ALLOW_ECC
,
NAMED_GROUP_ECDHE
),
K_ECDH_ANON
(
"ECDH_anon"
,
ALLOW_ECC
,
NAMED_GROUP_ECDHE
),
K_NULL
(
"NULL"
,
false
,
false
),
K_RSA
(
"RSA"
,
true
,
false
),
K_RSA_EXPORT
(
"RSA_EXPORT"
,
true
,
false
),
K_DH_RSA
(
"DH_RSA"
,
false
,
false
),
K_DH_DSS
(
"DH_DSS"
,
false
,
false
),
K_DHE_DSS
(
"DHE_DSS"
,
true
,
false
),
K_DHE_RSA
(
"DHE_RSA"
,
true
,
false
),
K_DH_ANON
(
"DH_anon"
,
true
,
false
),
K_ECDH_ECDSA
(
"ECDH_ECDSA"
,
ALLOW_ECC
,
true
),
K_ECDH_RSA
(
"ECDH_RSA"
,
ALLOW_ECC
,
true
),
K_ECDHE_ECDSA
(
"ECDHE_ECDSA"
,
ALLOW_ECC
,
true
),
K_ECDHE_RSA
(
"ECDHE_RSA"
,
ALLOW_ECC
,
true
),
K_ECDH_ANON
(
"ECDH_anon"
,
ALLOW_ECC
,
true
),
// Kerberos cipher suites
K_KRB5
(
"KRB5"
,
true
,
NAMED_GROUP_NONE
),
K_KRB5_EXPORT
(
"KRB5_EXPORT"
,
true
,
NAMED_GROUP_NONE
),
K_KRB5
(
"KRB5"
,
true
,
false
),
K_KRB5_EXPORT
(
"KRB5_EXPORT"
,
true
,
false
),
// renegotiation protection request signaling cipher suite
K_SCSV
(
"SCSV"
,
true
,
NAMED_GROUP_NONE
);
K_SCSV
(
"SCSV"
,
true
,
false
);
// name of the key exchange algorithm, e.g. DHE_DSS
final
String
name
;
final
boolean
allowed
;
final
NamedGroupType
groupType
;
final
boolean
isEC
;
private
final
boolean
alwaysAvailable
;
KeyExchange
(
String
name
,
boolean
allowed
,
NamedGroupType
groupType
)
{
KeyExchange
(
String
name
,
boolean
allowed
,
boolean
isEC
)
{
this
.
name
=
name
;
this
.
allowed
=
allowed
;
this
.
groupType
=
groupType
;
this
.
isEC
=
isEC
;
this
.
alwaysAvailable
=
allowed
&&
(!
name
.
startsWith
(
"EC"
))
&&
(!
name
.
startsWith
(
"KRB"
));
}
...
...
@@ -368,7 +367,7 @@ final class CipherSuite implements Comparable<CipherSuite> {
return
true
;
}
if
(
groupType
==
NAMED_GROUP_ECDHE
)
{
if
(
isEC
)
{
return
(
allowed
&&
JsseJce
.
isEcAvailable
());
}
else
if
(
name
.
startsWith
(
"KRB"
))
{
return
(
allowed
&&
JsseJce
.
isKerberosAvailable
());
...
...
src/share/classes/sun/security/ssl/CipherSuiteList.java
浏览文件 @
3faae241
/*
* Copyright (c) 2002, 201
7
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2002, 201
6
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
...
...
@@ -30,7 +30,6 @@ import java.io.*;
import
java.util.*
;
import
javax.net.ssl.SSLException
;
import
static
sun
.
security
.
ssl
.
NamedGroupType
.*;
/**
* A list of CipherSuites. Also maintains the lists of supported and
...
...
@@ -43,16 +42,15 @@ final class CipherSuiteList {
private
final
Collection
<
CipherSuite
>
cipherSuites
;
private
String
[]
suiteNames
;
private
final
EnumSet
<
NamedGroupType
>
groupsTypes
=
EnumSet
.
noneOf
(
NamedGroupType
.
class
);
// flag indicating whether this list contains any ECC ciphersuites.
// null if not yet checked.
private
volatile
Boolean
containsEC
;
// for use by buildAvailableCache() and
// Handshaker.getKickstartMessage() only
CipherSuiteList
(
Collection
<
CipherSuite
>
cipherSuites
)
{
this
.
cipherSuites
=
cipherSuites
;
for
(
CipherSuite
suite
:
cipherSuites
)
{
updateGroupTypes
(
suite
);
}
}
/**
...
...
@@ -61,7 +59,6 @@ final class CipherSuiteList {
CipherSuiteList
(
CipherSuite
suite
)
{
cipherSuites
=
new
ArrayList
<
CipherSuite
>(
1
);
cipherSuites
.
add
(
suite
);
updateGroupTypes
(
suite
);
}
/**
...
...
@@ -85,7 +82,6 @@ final class CipherSuiteList {
+
suiteName
+
" with currently installed providers"
);
}
cipherSuites
.
add
(
suite
);
updateGroupTypes
(
suite
);
}
}
...
...
@@ -101,20 +97,7 @@ final class CipherSuiteList {
}
cipherSuites
=
new
ArrayList
<
CipherSuite
>(
bytes
.
length
>>
1
);
for
(
int
i
=
0
;
i
<
bytes
.
length
;
i
+=
2
)
{
CipherSuite
suite
=
CipherSuite
.
valueOf
(
bytes
[
i
],
bytes
[
i
+
1
]);
cipherSuites
.
add
(
suite
);
updateGroupTypes
(
suite
);
}
}
// Please don't use this method except constructors.
private
void
updateGroupTypes
(
CipherSuite
cipherSuite
)
{
if
(
cipherSuite
.
keyExchange
!=
null
&&
(!
cipherSuite
.
exportable
))
{
NamedGroupType
groupType
=
cipherSuite
.
keyExchange
.
groupType
;
if
((
groupType
!=
NAMED_GROUP_NONE
)
&&
(!
groupsTypes
.
contains
(
groupType
)))
{
groupsTypes
.
add
(
groupType
);
}
cipherSuites
.
add
(
CipherSuite
.
valueOf
(
bytes
[
i
],
bytes
[
i
+
1
]));
}
}
...
...
@@ -125,9 +108,20 @@ final class CipherSuiteList {
return
cipherSuites
.
contains
(
suite
);
}
// Return whether this list contains cipher suites of a named group type.
boolean
contains
(
NamedGroupType
groupType
)
{
return
groupsTypes
.
contains
(
groupType
);
// Return whether this list contains any ECC ciphersuites
boolean
containsEC
()
{
if
(
containsEC
==
null
)
{
for
(
CipherSuite
c
:
cipherSuites
)
{
if
(
c
.
keyExchange
.
isEC
)
{
containsEC
=
true
;
return
true
;
}
}
containsEC
=
false
;
}
return
containsEC
;
}
/**
...
...
src/share/classes/sun/security/ssl/ClientHandshaker.java
浏览文件 @
3faae241
/*
* Copyright (c) 1996, 201
7
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 201
5
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
...
...
@@ -141,10 +141,6 @@ final class ClientHandshaker extends Handshaker {
private
final
static
boolean
allowUnsafeServerCertChange
=
Debug
.
getBooleanProperty
(
"jdk.tls.allowUnsafeServerCertChange"
,
false
);
// To switch off the supported_groups extension for DHE cipher suite.
private
static
final
boolean
enableFFDHE
=
Debug
.
getBooleanProperty
(
"jsse.enableFFDHE"
,
true
);
private
List
<
SNIServerName
>
requestedServerNames
=
Collections
.<
SNIServerName
>
emptyList
();
...
...
@@ -653,12 +649,10 @@ final class ClientHandshaker extends Handshaker {
ExtensionType
type
=
ext
.
type
;
if
(
type
==
ExtensionType
.
EXT_SERVER_NAME
)
{
serverNamesAccepted
=
true
;
}
else
if
((
type
!=
ExtensionType
.
EXT_
SUPPORTED_GROUP
S
)
}
else
if
((
type
!=
ExtensionType
.
EXT_
ELLIPTIC_CURVE
S
)
&&
(
type
!=
ExtensionType
.
EXT_EC_POINT_FORMATS
)
&&
(
type
!=
ExtensionType
.
EXT_SERVER_NAME
)
&&
(
type
!=
ExtensionType
.
EXT_RENEGOTIATION_INFO
))
{
// Note: Better to check client requested extensions rather
// than all supported extensions.
fatalSE
(
Alerts
.
alert_unsupported_extension
,
"Server sent an unsupported extension: "
+
type
);
}
...
...
@@ -707,17 +701,6 @@ final class ClientHandshaker extends Handshaker {
* our own D-H algorithm object so we can defer key calculations
* until after we've sent the client key exchange message (which
* gives client and server some useful parallelism).
*
* Note per section 3 of RFC 7919, if the server is not compatible with
* FFDHE specification, the client MAY decide to continue the connection
* if the selected DHE group is acceptable under local policy, or it MAY
* decide to terminate the connection with a fatal insufficient_security
* (71) alert. The algorithm constraints mechanism is JDK local policy
* used for additional DHE parameters checking. So this implementation
* does not check the server compatibility and just pass to the local
* algorithm constraints checking. The client will continue the
* connection if the server selected DHE group is acceptable by the
* specified algorithm constraints.
*/
private
void
serverKeyExchange
(
DH_ServerKeyExchange
mesg
)
throws
IOException
{
...
...
@@ -1396,17 +1379,14 @@ final class ClientHandshaker extends Handshaker {
sslContext
.
getSecureRandom
(),
maxProtocolVersion
,
sessionId
,
cipherSuites
);
// Add named groups extension for ECDHE and FFDHE if necessary.
SupportedGroupsExtension
sge
=
SupportedGroupsExtension
.
createExtension
(
algorithmConstraints
,
cipherSuites
,
enableFFDHE
);
if
(
sge
!=
null
)
{
clientHelloMessage
.
extensions
.
add
(
sge
);
// Add elliptic point format extensions
if
(
cipherSuites
.
contains
(
NamedGroupType
.
NAMED_GROUP_ECDHE
))
{
// add elliptic curves and point format extensions
if
(
cipherSuites
.
containsEC
())
{
EllipticCurvesExtension
ece
=
EllipticCurvesExtension
.
createExtension
(
algorithmConstraints
);
if
(
ece
!=
null
)
{
clientHelloMessage
.
extensions
.
add
(
ece
);
clientHelloMessage
.
extensions
.
add
(
EllipticPointFormatsExtension
.
DEFAULT
);
EllipticPointFormatsExtension
.
DEFAULT
);
}
}
...
...
src/share/classes/sun/security/ssl/DHCrypt.java
浏览文件 @
3faae241
/*
* Copyright (c) 1996, 201
7
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 201
5
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
...
...
@@ -26,8 +26,14 @@
package
sun.security.ssl
;
import
java.util.Map
;
import
java.util.HashMap
;
import
java.util.Collections
;
import
java.util.regex.Pattern
;
import
java.util.regex.Matcher
;
import
java.math.BigInteger
;
import
java.security.*
;
import
java.io.IOException
;
import
javax.net.ssl.SSLHandshakeException
;
import
javax.crypto.SecretKey
;
import
javax.crypto.KeyAgreement
;
...
...
@@ -95,7 +101,7 @@ final class DHCrypt {
*/
DHCrypt
(
int
keyLength
,
SecureRandom
random
)
{
this
(
keyLength
,
PredefinedDHParameterSpecs
.
definedParams
.
get
(
keyLength
),
random
);
ParametersHolder
.
definedParams
.
get
(
keyLength
),
random
);
}
/**
...
...
@@ -109,14 +115,6 @@ final class DHCrypt {
new
DHParameterSpec
(
modulus
,
base
),
random
);
}
/**
* Generate a Diffie-Hellman keypair using the named group.
*/
DHCrypt
(
NamedGroup
namedGroup
,
SecureRandom
random
)
{
this
(-
1
,
// The length (-1) is not used in the implementation.
SupportedGroupsExtension
.
getDHParameterSpec
(
namedGroup
),
random
);
}
/**
* Generate a Diffie-Hellman keypair using the specified size and
* parameters.
...
...
@@ -274,4 +272,141 @@ final class DHCrypt {
return
null
;
}
// lazy initialization holder class idiom for static default parameters
//
// See Effective Java Second Edition: Item 71.
private
static
class
ParametersHolder
{
private
final
static
boolean
debugIsOn
=
(
Debug
.
getInstance
(
"ssl"
)
!=
null
)
&&
Debug
.
isOn
(
"sslctx"
);
//
// Default DH ephemeral parameters
//
private
static
final
BigInteger
g2
=
BigInteger
.
valueOf
(
2
);
private
static
final
BigInteger
p512
=
new
BigInteger
(
// generated
"D87780E15FF50B4ABBE89870188B049406B5BEA98AB23A02"
+
"41D88EA75B7755E669C08093D3F0CA7FC3A5A25CF067DCB9"
+
"A43DD89D1D90921C6328884461E0B6D3"
,
16
);
private
static
final
BigInteger
p768
=
new
BigInteger
(
// RFC 2409
"FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"
+
"29024E088A67CC74020BBEA63B139B22514A08798E3404DD"
+
"EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245"
+
"E485B576625E7EC6F44C42E9A63A3620FFFFFFFFFFFFFFFF"
,
16
);
private
static
final
BigInteger
p1024
=
new
BigInteger
(
// RFC 2409
"FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"
+
"29024E088A67CC74020BBEA63B139B22514A08798E3404DD"
+
"EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245"
+
"E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED"
+
"EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381"
+
"FFFFFFFFFFFFFFFF"
,
16
);
private
static
final
BigInteger
p2048
=
new
BigInteger
(
// TLS FEDHE
"FFFFFFFFFFFFFFFFADF85458A2BB4A9AAFDC5620273D3CF1"
+
"D8B9C583CE2D3695A9E13641146433FBCC939DCE249B3EF9"
+
"7D2FE363630C75D8F681B202AEC4617AD3DF1ED5D5FD6561"
+
"2433F51F5F066ED0856365553DED1AF3B557135E7F57C935"
+
"984F0C70E0E68B77E2A689DAF3EFE8721DF158A136ADE735"
+
"30ACCA4F483A797ABC0AB182B324FB61D108A94BB2C8E3FB"
+
"B96ADAB760D7F4681D4F42A3DE394DF4AE56EDE76372BB19"
+
"0B07A7C8EE0A6D709E02FCE1CDF7E2ECC03404CD28342F61"
+
"9172FE9CE98583FF8E4F1232EEF28183C3FE3B1B4C6FAD73"
+
"3BB5FCBC2EC22005C58EF1837D1683B2C6F34A26C1B2EFFA"
+
"886B423861285C97FFFFFFFFFFFFFFFF"
,
16
);
private
static
final
BigInteger
[]
supportedPrimes
=
{
p512
,
p768
,
p1024
,
p2048
};
// a measure of the uncertainty that prime modulus p is not a prime
//
// see BigInteger.isProbablePrime(int certainty)
private
final
static
int
PRIME_CERTAINTY
=
120
;
// the known security property, jdk.tls.server.defaultDHEParameters
private
final
static
String
PROPERTY_NAME
=
"jdk.tls.server.defaultDHEParameters"
;
private
static
final
Pattern
spacesPattern
=
Pattern
.
compile
(
"\\s+"
);
private
final
static
Pattern
syntaxPattern
=
Pattern
.
compile
(
"(\\{[0-9A-Fa-f]+,[0-9A-Fa-f]+\\})"
+
"(,\\{[0-9A-Fa-f]+,[0-9A-Fa-f]+\\})*"
);
private
static
final
Pattern
paramsPattern
=
Pattern
.
compile
(
"\\{([0-9A-Fa-f]+),([0-9A-Fa-f]+)\\}"
);
// cache of predefined default DH ephemeral parameters
private
final
static
Map
<
Integer
,
DHParameterSpec
>
definedParams
;
static
{
String
property
=
AccessController
.
doPrivileged
(
new
PrivilegedAction
<
String
>()
{
public
String
run
()
{
return
Security
.
getProperty
(
PROPERTY_NAME
);
}
});
if
(
property
!=
null
&&
!
property
.
isEmpty
())
{
// remove double quote marks from beginning/end of the property
if
(
property
.
length
()
>=
2
&&
property
.
charAt
(
0
)
==
'"'
&&
property
.
charAt
(
property
.
length
()
-
1
)
==
'"'
)
{
property
=
property
.
substring
(
1
,
property
.
length
()
-
1
);
}
property
=
property
.
trim
();
}
if
(
property
!=
null
&&
!
property
.
isEmpty
())
{
Matcher
spacesMatcher
=
spacesPattern
.
matcher
(
property
);
property
=
spacesMatcher
.
replaceAll
(
""
);
if
(
debugIsOn
)
{
System
.
out
.
println
(
"The Security Property "
+
PROPERTY_NAME
+
": "
+
property
);
}
}
Map
<
Integer
,
DHParameterSpec
>
defaultParams
=
new
HashMap
<>();
if
(
property
!=
null
&&
!
property
.
isEmpty
())
{
Matcher
syntaxMatcher
=
syntaxPattern
.
matcher
(
property
);
if
(
syntaxMatcher
.
matches
())
{
Matcher
paramsFinder
=
paramsPattern
.
matcher
(
property
);
while
(
paramsFinder
.
find
())
{
String
primeModulus
=
paramsFinder
.
group
(
1
);
BigInteger
p
=
new
BigInteger
(
primeModulus
,
16
);
if
(!
p
.
isProbablePrime
(
PRIME_CERTAINTY
))
{
if
(
debugIsOn
)
{
System
.
out
.
println
(
"Prime modulus p in Security Property, "
+
PROPERTY_NAME
+
", is not a prime: "
+
primeModulus
);
}
continue
;
}
String
baseGenerator
=
paramsFinder
.
group
(
2
);
BigInteger
g
=
new
BigInteger
(
baseGenerator
,
16
);
DHParameterSpec
spec
=
new
DHParameterSpec
(
p
,
g
);
int
primeLen
=
p
.
bitLength
();
defaultParams
.
put
(
primeLen
,
spec
);
}
}
else
if
(
debugIsOn
)
{
System
.
out
.
println
(
"Invalid Security Property, "
+
PROPERTY_NAME
+
", definition"
);
}
}
for
(
BigInteger
p
:
supportedPrimes
)
{
int
primeLen
=
p
.
bitLength
();
defaultParams
.
putIfAbsent
(
primeLen
,
new
DHParameterSpec
(
p
,
g2
));
}
definedParams
=
Collections
.<
Integer
,
DHParameterSpec
>
unmodifiableMap
(
defaultParams
);
}
}
}
src/share/classes/sun/security/ssl/ECDHCrypt.java
浏览文件 @
3faae241
/*
* Copyright (c) 2006, 201
7
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2006, 201
6
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
...
...
@@ -56,17 +56,17 @@ final class ECDHCrypt {
}
// Called by ServerHandshaker for ephemeral ECDH
ECDHCrypt
(
NamedGroup
namedGroup
,
SecureRandom
random
)
{
ECDHCrypt
(
int
curveId
,
SecureRandom
random
)
{
try
{
KeyPairGenerator
kpg
=
JsseJce
.
getKeyPairGenerator
(
"EC"
);
ECGenParameterSpec
params
=
SupportedGroupsExtension
.
getECGenParamSpec
(
namedGroup
);
EllipticCurvesExtension
.
getECGenParamSpec
(
curveId
);
kpg
.
initialize
(
params
,
random
);
KeyPair
kp
=
kpg
.
generateKeyPair
();
privateKey
=
kp
.
getPrivate
();
publicKey
=
(
ECPublicKey
)
kp
.
getPublic
();
}
catch
(
GeneralSecurityException
e
)
{
throw
new
RuntimeException
(
"Could not generate
EC
DH keypair"
,
e
);
throw
new
RuntimeException
(
"Could not generate DH keypair"
,
e
);
}
}
...
...
@@ -79,7 +79,7 @@ final class ECDHCrypt {
privateKey
=
kp
.
getPrivate
();
publicKey
=
(
ECPublicKey
)
kp
.
getPublic
();
}
catch
(
GeneralSecurityException
e
)
{
throw
new
RuntimeException
(
"Could not generate
EC
DH keypair"
,
e
);
throw
new
RuntimeException
(
"Could not generate DH keypair"
,
e
);
}
}
...
...
src/share/classes/sun/security/ssl/
SupportedGroup
sExtension.java
→
src/share/classes/sun/security/ssl/
EllipticCurve
sExtension.java
浏览文件 @
3faae241
...
...
@@ -26,14 +26,13 @@
package
sun.security.ssl
;
import
java.io.IOException
;
import
java.security.spec.ECParameterSpec
;
import
java.security.spec.ECGenParameterSpec
;
import
java.security.spec.InvalidParameterSpecException
;
import
java.security.AlgorithmParameters
;
import
java.security.AlgorithmConstraints
;
import
java.security.CryptoPrimitive
;
import
java.security.AccessController
;
import
java.security.spec.AlgorithmParameterSpec
;
import
javax.crypto.spec.DHParameterSpec
;
import
java.util.EnumSet
;
import
java.util.HashMap
;
import
java.util.Map
;
...
...
@@ -42,13 +41,7 @@ import javax.net.ssl.SSLProtocolException;
import
sun.security.action.GetPropertyAction
;
//
// Note: Since RFC 7919, the extension's semantics are expanded from
// "Supported Elliptic Curves" to "Supported Groups". The enum datatype
// used in the extension has been renamed from NamedCurve to NamedGroup.
// Its semantics are likewise expanded from "named curve" to "named group".
//
final
class
SupportedGroupsExtension
extends
HelloExtension
{
final
class
EllipticCurvesExtension
extends
HelloExtension
{
/* Class and subclass dynamic debugging support */
private
static
final
Debug
debug
=
Debug
.
getInstance
(
"ssl"
);
...
...
@@ -56,26 +49,93 @@ final class SupportedGroupsExtension extends HelloExtension {
private
static
final
int
ARBITRARY_PRIME
=
0xff01
;
private
static
final
int
ARBITRARY_CHAR2
=
0xff02
;
// cache to speed up the parameters construction
private
static
final
Map
<
NamedGroup
,
AlgorithmParameters
>
namedGroupParams
=
new
HashMap
<>();
// speed up the searching
private
static
final
Map
<
String
,
Integer
>
oidToIdMap
=
new
HashMap
<>();
private
static
final
Map
<
Integer
,
String
>
idToOidMap
=
new
HashMap
<>();
// speed up the parameters construction
private
static
final
Map
<
Integer
,
AlgorithmParameters
>
idToParams
=
new
HashMap
<>();
// the supported elliptic curves
private
static
final
int
[]
supportedCurveIds
;
// the curves of the extension
private
final
int
[]
curveIds
;
// See sun.security.util.CurveDB for the OIDs
private
static
enum
NamedEllipticCurve
{
T163_K1
(
1
,
"sect163k1"
,
"1.3.132.0.1"
,
true
),
// NIST K-163
T163_R1
(
2
,
"sect163r1"
,
"1.3.132.0.2"
,
false
),
T163_R2
(
3
,
"sect163r2"
,
"1.3.132.0.15"
,
true
),
// NIST B-163
T193_R1
(
4
,
"sect193r1"
,
"1.3.132.0.24"
,
false
),
T193_R2
(
5
,
"sect193r2"
,
"1.3.132.0.25"
,
false
),
T233_K1
(
6
,
"sect233k1"
,
"1.3.132.0.26"
,
true
),
// NIST K-233
T233_R1
(
7
,
"sect233r1"
,
"1.3.132.0.27"
,
true
),
// NIST B-233
T239_K1
(
8
,
"sect239k1"
,
"1.3.132.0.3"
,
false
),
T283_K1
(
9
,
"sect283k1"
,
"1.3.132.0.16"
,
true
),
// NIST K-283
T283_R1
(
10
,
"sect283r1"
,
"1.3.132.0.17"
,
true
),
// NIST B-283
T409_K1
(
11
,
"sect409k1"
,
"1.3.132.0.36"
,
true
),
// NIST K-409
T409_R1
(
12
,
"sect409r1"
,
"1.3.132.0.37"
,
true
),
// NIST B-409
T571_K1
(
13
,
"sect571k1"
,
"1.3.132.0.38"
,
true
),
// NIST K-571
T571_R1
(
14
,
"sect571r1"
,
"1.3.132.0.39"
,
true
),
// NIST B-571
P160_K1
(
15
,
"secp160k1"
,
"1.3.132.0.9"
,
false
),
P160_R1
(
16
,
"secp160r1"
,
"1.3.132.0.8"
,
false
),
P160_R2
(
17
,
"secp160r2"
,
"1.3.132.0.30"
,
false
),
P192_K1
(
18
,
"secp192k1"
,
"1.3.132.0.31"
,
false
),
P192_R1
(
19
,
"secp192r1"
,
"1.2.840.10045.3.1.1"
,
true
),
// NIST P-192
P224_K1
(
20
,
"secp224k1"
,
"1.3.132.0.32"
,
false
),
P224_R1
(
21
,
"secp224r1"
,
"1.3.132.0.33"
,
true
),
// NIST P-224
P256_K1
(
22
,
"secp256k1"
,
"1.3.132.0.10"
,
false
),
P256_R1
(
23
,
"secp256r1"
,
"1.2.840.10045.3.1.7"
,
true
),
// NIST P-256
P384_R1
(
24
,
"secp384r1"
,
"1.3.132.0.34"
,
true
),
// NIST P-384
P521_R1
(
25
,
"secp521r1"
,
"1.3.132.0.35"
,
true
);
// NIST P-521
int
id
;
String
name
;
String
oid
;
boolean
isFips
;
NamedEllipticCurve
(
int
id
,
String
name
,
String
oid
,
boolean
isFips
)
{
this
.
id
=
id
;
this
.
name
=
name
;
this
.
oid
=
oid
;
this
.
isFips
=
isFips
;
if
(
oidToIdMap
.
put
(
oid
,
id
)
!=
null
||
idToOidMap
.
put
(
id
,
oid
)
!=
null
)
{
throw
new
RuntimeException
(
"Duplicate named elliptic curve definition: "
+
name
);
}
}
// the supported named groups
private
static
final
NamedGroup
[]
supportedNamedGroups
;
static
NamedEllipticCurve
getCurve
(
String
name
,
boolean
requireFips
)
{
for
(
NamedEllipticCurve
curve
:
NamedEllipticCurve
.
values
())
{
if
(
curve
.
name
.
equals
(
name
)
&&
(!
requireFips
||
curve
.
isFips
))
{
return
curve
;
}
}
// the named group presented in the extension
private
final
int
[]
requestedNamedGroupIds
;
return
null
;
}
}
static
{
boolean
requireFips
=
SunJSSE
.
isFIPS
();
// hack code to initialize NamedEllipticCurve
NamedEllipticCurve
nec
=
NamedEllipticCurve
.
getCurve
(
"secp256r1"
,
false
);
// The value of the System Property defines a list of enabled named
//
group
s in preference order, separated with comma. For example:
//
curve
s in preference order, separated with comma. For example:
//
// jdk.tls.namedGroups="secp521r1, secp256r1,
ffdhe2048
"
// jdk.tls.namedGroups="secp521r1, secp256r1,
secp384r1
"
//
// If the System Property is not defined or the value is empty, the
// default
group
s and preferences will be used.
// default
curve
s and preferences will be used.
String
property
=
AccessController
.
doPrivileged
(
new
GetPropertyAction
(
"jdk.tls.namedGroups"
));
if
(
property
!=
null
&&
property
.
length
()
!=
0
)
{
...
...
@@ -86,128 +146,79 @@ final class SupportedGroupsExtension extends HelloExtension {
}
}
ArrayList
<
NamedGroup
>
group
List
;
if
(
property
!=
null
&&
property
.
length
()
!=
0
)
{
// customized
group
s
String
[]
group
s
=
property
.
split
(
","
);
groupList
=
new
ArrayList
<>(
group
s
.
length
);
for
(
String
group
:
group
s
)
{
group
=
group
.
trim
();
if
(!
group
.
isEmpty
())
{
Named
Group
namedGroup
=
NamedGroup
.
nameOf
(
group
);
if
(
namedGroup
!=
null
&&
(!
requireFips
||
namedGroup
.
isFips
)
)
{
if
(
isAvailable
Group
(
namedGroup
))
{
groupList
.
add
(
namedGroup
);
ArrayList
<
Integer
>
id
List
;
if
(
property
!=
null
&&
property
.
length
()
!=
0
)
{
// customized
curve
s
String
[]
curve
s
=
property
.
split
(
","
);
idList
=
new
ArrayList
<>(
curve
s
.
length
);
for
(
String
curve
:
curve
s
)
{
curve
=
curve
.
trim
();
if
(!
curve
.
isEmpty
())
{
Named
EllipticCurve
namedCurve
=
NamedEllipticCurve
.
getCurve
(
curve
,
requireFips
);
if
(
namedCurve
!=
null
)
{
if
(
isAvailable
Curve
(
namedCurve
.
id
))
{
idList
.
add
(
namedCurve
.
id
);
}
}
// ignore unknown
group
s
}
// ignore unknown
curve
s
}
}
if
(
groupList
.
isEmpty
()
&&
JsseJce
.
isEcAvailable
())
{
if
(
idList
.
isEmpty
()
&&
JsseJce
.
isEcAvailable
())
{
throw
new
IllegalArgumentException
(
"System property jdk.tls.namedGroups("
+
property
+
") "
+
"contains no supported elliptic curves"
);
}
}
else
{
// default
group
s
NamedGroup
[]
group
s
;
}
else
{
// default
curve
s
int
[]
id
s
;
if
(
requireFips
)
{
groups
=
new
NamedGroup
[]
{
ids
=
new
int
[]
{
// only NIST curves in FIPS mode
NamedGroup
.
SECP256_R1
,
NamedGroup
.
SECP384_R1
,
NamedGroup
.
SECP521_R1
,
NamedGroup
.
SECT283_K1
,
NamedGroup
.
SECT283_R1
,
NamedGroup
.
SECT409_K1
,
NamedGroup
.
SECT409_R1
,
NamedGroup
.
SECT571_K1
,
NamedGroup
.
SECT571_R1
,
// FFDHE 2048
NamedGroup
.
FFDHE_2048
,
NamedGroup
.
FFDHE_3072
,
NamedGroup
.
FFDHE_4096
,
NamedGroup
.
FFDHE_6144
,
NamedGroup
.
FFDHE_8192
,
23
,
24
,
25
,
9
,
10
,
11
,
12
,
13
,
14
,
};
}
else
{
groups
=
new
NamedGroup
[]
{
ids
=
new
int
[]
{
// NIST curves first
NamedGroup
.
SECP256_R1
,
NamedGroup
.
SECP384_R1
,
NamedGroup
.
SECP521_R1
,
NamedGroup
.
SECT283_K1
,
NamedGroup
.
SECT283_R1
,
NamedGroup
.
SECT409_K1
,
NamedGroup
.
SECT409_R1
,
NamedGroup
.
SECT571_K1
,
NamedGroup
.
SECT571_R1
,
23
,
24
,
25
,
9
,
10
,
11
,
12
,
13
,
14
,
// non-NIST curves
NamedGroup
.
SECP256_K1
,
// FFDHE 2048
NamedGroup
.
FFDHE_2048
,
NamedGroup
.
FFDHE_3072
,
NamedGroup
.
FFDHE_4096
,
NamedGroup
.
FFDHE_6144
,
NamedGroup
.
FFDHE_8192
,
22
,
};
}
groupList
=
new
ArrayList
<>(
group
s
.
length
);
for
(
NamedGroup
group
:
group
s
)
{
if
(
isAvailable
Group
(
group
))
{
groupList
.
add
(
group
);
idList
=
new
ArrayList
<>(
id
s
.
length
);
for
(
int
curveId
:
id
s
)
{
if
(
isAvailable
Curve
(
curveId
))
{
idList
.
add
(
curveId
);
}
}
}
if
(
debug
!=
null
&&
group
List
.
isEmpty
())
{
if
(
debug
!=
null
&&
id
List
.
isEmpty
())
{
debug
.
println
(
"Initialized [jdk.tls.namedGroups|default] list contains "
+
"no available elliptic curves. "
+
(
property
!=
null
?
"("
+
property
+
")"
:
"[Default]"
));
}
supportedNamedGroups
=
new
NamedGroup
[
groupList
.
size
()];
int
i
=
0
;
for
(
NamedGroup
namedGroup
:
groupList
)
{
supportedNamedGroups
[
i
++]
=
namedGroup
;
}
}
// check whether the group is supported by the underlying providers
private
static
boolean
isAvailableGroup
(
NamedGroup
namedGroup
)
{
AlgorithmParameters
params
=
null
;
AlgorithmParameterSpec
spec
=
null
;
if
(
"EC"
.
equals
(
namedGroup
.
algorithm
))
{
if
(
namedGroup
.
oid
!=
null
)
{
try
{
params
=
JsseJce
.
getAlgorithmParameters
(
"EC"
);
spec
=
new
ECGenParameterSpec
(
namedGroup
.
oid
);
}
catch
(
Exception
e
)
{
return
false
;
}
}
}
else
if
(
"DiffieHellman"
.
equals
(
namedGroup
.
algorithm
))
{
try
{
params
=
JsseJce
.
getAlgorithmParameters
(
"DiffieHellman"
);
spec
=
getFFDHEDHParameterSpec
(
namedGroup
);
}
catch
(
Exception
e
)
{
return
false
;
supportedCurveIds
=
new
int
[
idList
.
size
()];
int
i
=
0
;
for
(
Integer
id
:
idList
)
{
supportedCurveIds
[
i
++]
=
id
;
}
}
if
((
params
!=
null
)
&&
(
spec
!=
null
))
{
// check whether the curve is supported by the underlying providers
private
static
boolean
isAvailableCurve
(
int
curveId
)
{
String
oid
=
idToOidMap
.
get
(
curveId
);
if
(
oid
!=
null
)
{
AlgorithmParameters
params
=
null
;
try
{
params
.
init
(
spec
);
params
=
JsseJce
.
getAlgorithmParameters
(
"EC"
);
params
.
init
(
new
ECGenParameterSpec
(
oid
));
}
catch
(
Exception
e
)
{
return
false
;
}
// cache the parameters
namedGroupParams
.
put
(
namedGroup
,
params
);
idToParams
.
put
(
curveId
,
params
);
return
true
;
}
...
...
@@ -215,191 +226,82 @@ final class SupportedGroupsExtension extends HelloExtension {
return
false
;
}
private
static
DHParameterSpec
getFFDHEDHParameterSpec
(
NamedGroup
namedGroup
)
{
DHParameterSpec
spec
=
null
;
switch
(
namedGroup
)
{
case
FFDHE_2048:
spec
=
PredefinedDHParameterSpecs
.
ffdheParams
.
get
(
2048
);
break
;
case
FFDHE_3072:
spec
=
PredefinedDHParameterSpecs
.
ffdheParams
.
get
(
3072
);
break
;
case
FFDHE_4096:
spec
=
PredefinedDHParameterSpecs
.
ffdheParams
.
get
(
4096
);
break
;
case
FFDHE_6144:
spec
=
PredefinedDHParameterSpecs
.
ffdheParams
.
get
(
6144
);
break
;
case
FFDHE_8192:
spec
=
PredefinedDHParameterSpecs
.
ffdheParams
.
get
(
8192
);
}
return
spec
;
}
private
static
DHParameterSpec
getPredefinedDHParameterSpec
(
NamedGroup
namedGroup
)
{
DHParameterSpec
spec
=
null
;
switch
(
namedGroup
)
{
case
FFDHE_2048:
spec
=
PredefinedDHParameterSpecs
.
definedParams
.
get
(
2048
);
break
;
case
FFDHE_3072:
spec
=
PredefinedDHParameterSpecs
.
definedParams
.
get
(
3072
);
break
;
case
FFDHE_4096:
spec
=
PredefinedDHParameterSpecs
.
definedParams
.
get
(
4096
);
break
;
case
FFDHE_6144:
spec
=
PredefinedDHParameterSpecs
.
definedParams
.
get
(
6144
);
break
;
case
FFDHE_8192:
spec
=
PredefinedDHParameterSpecs
.
definedParams
.
get
(
8192
);
}
return
spec
;
}
private
SupportedGroupsExtension
(
int
[]
requestedNamedGroupIds
)
{
super
(
ExtensionType
.
EXT_SUPPORTED_GROUPS
);
this
.
requestedNamedGroupIds
=
requestedNamedGroupIds
;
private
EllipticCurvesExtension
(
int
[]
curveIds
)
{
super
(
ExtensionType
.
EXT_ELLIPTIC_CURVES
);
this
.
curveIds
=
curveIds
;
}
SupportedGroupsExtension
(
HandshakeInStream
s
,
int
len
)
throws
IOException
{
super
(
ExtensionType
.
EXT_SUPPORTED_GROUPS
);
EllipticCurvesExtension
(
HandshakeInStream
s
,
int
len
)
throws
IOException
{
super
(
ExtensionType
.
EXT_ELLIPTIC_CURVES
);
int
k
=
s
.
getInt16
();
if
(((
len
&
1
)
!=
0
)
||
(
k
==
0
)
||
(
k
+
2
!=
len
))
{
if
(((
len
&
1
)
!=
0
)
||
(
k
+
2
!=
len
))
{
throw
new
SSLProtocolException
(
"Invalid "
+
type
+
" extension"
);
}
// Note: unknown
named group
will be ignored later.
requestedNamedGroup
Ids
=
new
int
[
k
>>
1
];
for
(
int
i
=
0
;
i
<
requestedNamedGroup
Ids
.
length
;
i
++)
{
requestedNamedGroup
Ids
[
i
]
=
s
.
getInt16
();
// Note: unknown
curves
will be ignored later.
curve
Ids
=
new
int
[
k
>>
1
];
for
(
int
i
=
0
;
i
<
curve
Ids
.
length
;
i
++)
{
curve
Ids
[
i
]
=
s
.
getInt16
();
}
}
// Get a local preferred supported ECDHE group permitted by the constraints.
static
NamedGroup
getPreferredECGroup
(
AlgorithmConstraints
constraints
)
{
for
(
NamedGroup
namedGroup
:
supportedNamedGroups
)
{
if
((
namedGroup
.
type
==
NamedGroupType
.
NAMED_GROUP_ECDHE
)
&&
constraints
.
permits
(
EnumSet
.
of
(
CryptoPrimitive
.
KEY_AGREEMENT
),
namedGroup
.
algorithm
,
namedGroupParams
.
get
(
namedGroup
)))
{
return
namedGroup
;
}
}
return
null
;
// get the preferred active curve
static
int
getActiveCurves
(
AlgorithmConstraints
constraints
)
{
return
getPreferredCurve
(
supportedCurveIds
,
constraints
);
}
// Is there any supported group permitted by the constraints?
static
boolean
isActivatable
(
AlgorithmConstraints
constraints
,
NamedGroupType
type
)
{
boolean
hasFFDHEGroups
=
false
;
for
(
NamedGroup
namedGroup
:
supportedNamedGroups
)
{
if
(
namedGroup
.
type
==
type
)
{
if
(
constraints
.
permits
(
EnumSet
.
of
(
CryptoPrimitive
.
KEY_AGREEMENT
),
namedGroup
.
algorithm
,
namedGroupParams
.
get
(
namedGroup
)))
{
return
true
;
}
if
(!
hasFFDHEGroups
&&
(
type
==
NamedGroupType
.
NAMED_GROUP_FFDHE
))
{
hasFFDHEGroups
=
true
;
}
}
}
// For compatibility, if no FFDHE groups are defined, the non-FFDHE
// compatible mode (using DHE cipher suite without FFDHE extension)
// is allowed.
//
// Note that the constraints checking on DHE parameters will be
// performed during key exchanging in a handshake.
if
(!
hasFFDHEGroups
&&
(
type
==
NamedGroupType
.
NAMED_GROUP_FFDHE
))
{
return
true
;
}
return
false
;
static
boolean
hasActiveCurves
(
AlgorithmConstraints
constraints
)
{
return
getActiveCurves
(
constraints
)
>=
0
;
}
// Create the default supported groups extension.
static
SupportedGroupsExtension
createExtension
(
AlgorithmConstraints
constraints
,
CipherSuiteList
cipherSuites
,
boolean
enableFFDHE
)
{
ArrayList
<
Integer
>
groupList
=
new
ArrayList
<>(
supportedNamedGroups
.
length
);
for
(
NamedGroup
namedGroup
:
supportedNamedGroups
)
{
if
((!
enableFFDHE
)
&&
(
namedGroup
.
type
==
NamedGroupType
.
NAMED_GROUP_FFDHE
))
{
continue
;
}
if
(
cipherSuites
.
contains
(
namedGroup
.
type
)
&&
constraints
.
permits
(
EnumSet
.
of
(
CryptoPrimitive
.
KEY_AGREEMENT
),
namedGroup
.
algorithm
,
namedGroupParams
.
get
(
namedGroup
)))
{
static
EllipticCurvesExtension
createExtension
(
AlgorithmConstraints
constraints
)
{
groupList
.
add
(
namedGroup
.
id
);
ArrayList
<
Integer
>
idList
=
new
ArrayList
<>(
supportedCurveIds
.
length
);
for
(
int
curveId
:
supportedCurveIds
)
{
if
(
constraints
.
permits
(
EnumSet
.
of
(
CryptoPrimitive
.
KEY_AGREEMENT
),
"EC"
,
idToParams
.
get
(
curveId
)))
{
idList
.
add
(
curveId
);
}
}
if
(!
group
List
.
isEmpty
())
{
int
[]
ids
=
new
int
[
group
List
.
size
()];
if
(!
id
List
.
isEmpty
())
{
int
[]
ids
=
new
int
[
id
List
.
size
()];
int
i
=
0
;
for
(
Integer
id
:
group
List
)
{
for
(
Integer
id
:
id
List
)
{
ids
[
i
++]
=
id
;
}
return
new
SupportedGroup
sExtension
(
ids
);
return
new
EllipticCurve
sExtension
(
ids
);
}
return
null
;
}
// get the preferred activated named group
NamedGroup
getPreferredGroup
(
AlgorithmConstraints
constraints
,
NamedGroupType
type
)
{
for
(
int
groupId
:
requestedNamedGroupIds
)
{
NamedGroup
namedGroup
=
NamedGroup
.
valueOf
(
groupId
);
if
((
namedGroup
!=
null
)
&&
(
namedGroup
.
type
==
type
)
&&
SupportedGroupsExtension
.
supports
(
namedGroup
)
&&
constraints
.
permits
(
EnumSet
.
of
(
CryptoPrimitive
.
KEY_AGREEMENT
),
namedGroup
.
algorithm
,
namedGroupParams
.
get
(
namedGroup
)))
{
return
namedGroup
;
}
}
return
null
;
// get the preferred activated curve
int
getPreferredCurve
(
AlgorithmConstraints
constraints
)
{
return
getPreferredCurve
(
curveIds
,
constraints
);
}
boolean
hasFFDHEGroup
()
{
for
(
int
groupId
:
requestedNamedGroupIds
)
{
/*
* [RFC 7919] Codepoints in the "Supported Groups Registry"
* with a high byte of 0x01 (that is, between 256 and 511,
* inclusive) are set aside for FFDHE groups.
*/
if
((
groupId
>=
256
)
&&
(
groupId
<=
511
))
{
return
true
;
// get a preferred activated curve
private
static
int
getPreferredCurve
(
int
[]
curves
,
AlgorithmConstraints
constraints
)
{
for
(
int
curveId
:
curves
)
{
if
(
isSupported
(
curveId
)
&&
constraints
.
permits
(
EnumSet
.
of
(
CryptoPrimitive
.
KEY_AGREEMENT
),
"EC"
,
idToParams
.
get
(
curveId
)))
{
return
curveId
;
}
}
return
false
;
return
-
1
;
}
boolean
contains
(
int
index
)
{
for
(
int
groupId
:
requestedNamedGroup
Ids
)
{
if
(
index
==
group
Id
)
{
for
(
int
curveId
:
curve
Ids
)
{
if
(
index
==
curve
Id
)
{
return
true
;
}
}
...
...
@@ -408,50 +310,50 @@ final class SupportedGroupsExtension extends HelloExtension {
@Override
int
length
()
{
return
6
+
(
requestedNamedGroup
Ids
.
length
<<
1
);
return
6
+
(
curve
Ids
.
length
<<
1
);
}
@Override
void
send
(
HandshakeOutStream
s
)
throws
IOException
{
s
.
putInt16
(
type
.
id
);
int
k
=
requestedNamedGroup
Ids
.
length
<<
1
;
int
k
=
curve
Ids
.
length
<<
1
;
s
.
putInt16
(
k
+
2
);
s
.
putInt16
(
k
);
for
(
int
groupId
:
requestedNamedGroup
Ids
)
{
s
.
putInt16
(
group
Id
);
for
(
int
curveId
:
curve
Ids
)
{
s
.
putInt16
(
curve
Id
);
}
}
@Override
public
String
toString
()
{
StringBuilder
sb
=
new
StringBuilder
();
sb
.
append
(
"Extension "
+
type
+
",
group
names: {"
);
sb
.
append
(
"Extension "
+
type
+
",
curve
names: {"
);
boolean
first
=
true
;
for
(
int
groupId
:
requestedNamedGroup
Ids
)
{
for
(
int
curveId
:
curve
Ids
)
{
if
(
first
)
{
first
=
false
;
}
else
{
sb
.
append
(
", "
);
}
// first check if it is a known named group, then try other cases.
NamedGroup
namedGroup
=
NamedGroup
.
valueOf
(
groupId
);
if
(
namedGroup
!=
null
)
{
sb
.
append
(
namedGroup
.
name
);
}
else
if
(
groupId
==
ARBITRARY_PRIME
)
{
String
curveName
=
getCurveName
(
curveId
);
if
(
curveName
!=
null
)
{
sb
.
append
(
curveName
);
}
else
if
(
curveId
==
ARBITRARY_PRIME
)
{
sb
.
append
(
"arbitrary_explicit_prime_curves"
);
}
else
if
(
group
Id
==
ARBITRARY_CHAR2
)
{
}
else
if
(
curve
Id
==
ARBITRARY_CHAR2
)
{
sb
.
append
(
"arbitrary_explicit_char2_curves"
);
}
else
{
sb
.
append
(
"unknown
named group "
+
group
Id
);
sb
.
append
(
"unknown
curve "
+
curve
Id
);
}
}
sb
.
append
(
"}"
);
return
sb
.
toString
();
}
static
boolean
supports
(
NamedGroup
namedGroup
)
{
for
(
NamedGroup
group
:
supportedNamedGroups
)
{
if
(
namedGroup
.
id
==
group
.
id
)
{
// Test whether the given curve is supported.
static
boolean
isSupported
(
int
index
)
{
for
(
int
curveId
:
supportedCurveIds
)
{
if
(
index
==
curveId
)
{
return
true
;
}
}
...
...
@@ -459,31 +361,37 @@ final class SupportedGroupsExtension extends HelloExtension {
return
false
;
}
static
ECGenParameterSpec
getECGenParamSpec
(
NamedGroup
namedGroup
)
{
if
(
namedGroup
.
type
!=
NamedGroupType
.
NAMED_GROUP_ECDHE
)
{
throw
new
RuntimeException
(
"Not a named EC group: "
+
namedGroup
);
static
int
getCurveIndex
(
ECParameterSpec
params
)
{
String
oid
=
JsseJce
.
getNamedCurveOid
(
params
);
if
(
oid
==
null
)
{
return
-
1
;
}
Integer
n
=
oidToIdMap
.
get
(
oid
);
return
(
n
==
null
)
?
-
1
:
n
;
}
AlgorithmParameters
params
=
namedGroupParams
.
get
(
namedGroup
);
static
String
getCurveOid
(
int
index
)
{
return
idToOidMap
.
get
(
index
);
}
static
ECGenParameterSpec
getECGenParamSpec
(
int
index
)
{
AlgorithmParameters
params
=
idToParams
.
get
(
index
);
try
{
return
params
.
getParameterSpec
(
ECGenParameterSpec
.
class
);
}
catch
(
InvalidParameterSpecException
ipse
)
{
// should be unlikely
return
new
ECGenParameterSpec
(
namedGroup
.
oid
);
String
curveOid
=
getCurveOid
(
index
);
return
new
ECGenParameterSpec
(
curveOid
);
}
}
static
DHParameterSpec
getDHParameterSpec
(
NamedGroup
namedGroup
)
{
if
(
namedGroup
.
type
!=
NamedGroupType
.
NAMED_GROUP_FFDHE
)
{
throw
new
RuntimeException
(
"Not a named DH group: "
+
namedGroup
);
private
static
String
getCurveName
(
int
index
)
{
for
(
NamedEllipticCurve
namedCurve
:
NamedEllipticCurve
.
values
())
{
if
(
namedCurve
.
id
==
index
)
{
return
namedCurve
.
name
;
}
}
AlgorithmParameters
params
=
namedGroupParams
.
get
(
namedGroup
);
try
{
return
params
.
getParameterSpec
(
DHParameterSpec
.
class
);
}
catch
(
InvalidParameterSpecException
ipse
)
{
// should be unlikely
return
getPredefinedDHParameterSpec
(
namedGroup
);
}
return
null
;
}
}
src/share/classes/sun/security/ssl/ExtensionType.java
浏览文件 @
3faae241
/*
* Copyright (c) 2006, 201
7
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2006, 201
2
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
...
...
@@ -43,7 +43,7 @@ final class ExtensionType {
return
name
;
}
static
List
<
ExtensionType
>
knownExtensions
=
new
ArrayList
<
>(
13
);
static
List
<
ExtensionType
>
knownExtensions
=
new
ArrayList
<
ExtensionType
>(
9
);
static
ExtensionType
get
(
int
id
)
{
for
(
ExtensionType
ext
:
knownExtensions
)
{
...
...
@@ -61,42 +61,42 @@ final class ExtensionType {
}
// extensions defined in RFC 3546
static
final
ExtensionType
EXT_SERVER_NAME
=
final
static
ExtensionType
EXT_SERVER_NAME
=
e
(
0x0000
,
"server_name"
);
// IANA registry value: 0
static
final
ExtensionType
EXT_MAX_FRAGMENT_LENGTH
=
final
static
ExtensionType
EXT_MAX_FRAGMENT_LENGTH
=
e
(
0x0001
,
"max_fragment_length"
);
// IANA registry value: 1
static
final
ExtensionType
EXT_CLIENT_CERTIFICATE_URL
=
final
static
ExtensionType
EXT_CLIENT_CERTIFICATE_URL
=
e
(
0x0002
,
"client_certificate_url"
);
// IANA registry value: 2
static
final
ExtensionType
EXT_TRUSTED_CA_KEYS
=
final
static
ExtensionType
EXT_TRUSTED_CA_KEYS
=
e
(
0x0003
,
"trusted_ca_keys"
);
// IANA registry value: 3
static
final
ExtensionType
EXT_TRUNCATED_HMAC
=
final
static
ExtensionType
EXT_TRUNCATED_HMAC
=
e
(
0x0004
,
"truncated_hmac"
);
// IANA registry value: 4
static
final
ExtensionType
EXT_STATUS_REQUEST
=
final
static
ExtensionType
EXT_STATUS_REQUEST
=
e
(
0x0005
,
"status_request"
);
// IANA registry value: 5
// extensions defined in RFC 4681
static
final
ExtensionType
EXT_USER_MAPPING
=
final
static
ExtensionType
EXT_USER_MAPPING
=
e
(
0x0006
,
"user_mapping"
);
// IANA registry value: 6
// extensions defined in RFC 5081
static
final
ExtensionType
EXT_CERT_TYPE
=
final
static
ExtensionType
EXT_CERT_TYPE
=
e
(
0x0009
,
"cert_type"
);
// IANA registry value: 9
// extensions defined in RFC 4492 (ECC)
and RFC 7919 (FFDHE)
static
final
ExtensionType
EXT_SUPPORTED_GROUP
S
=
e
(
0x000A
,
"
supported_groups"
);
// IANA registry value: 10
static
final
ExtensionType
EXT_EC_POINT_FORMATS
=
// extensions defined in RFC 4492 (ECC)
final
static
ExtensionType
EXT_ELLIPTIC_CURVE
S
=
e
(
0x000A
,
"
elliptic_curves"
);
// IANA registry value: 10
final
static
ExtensionType
EXT_EC_POINT_FORMATS
=
e
(
0x000B
,
"ec_point_formats"
);
// IANA registry value: 11
// extensions defined in RFC 5054
static
final
ExtensionType
EXT_SRP
=
final
static
ExtensionType
EXT_SRP
=
e
(
0x000C
,
"srp"
);
// IANA registry value: 12
// extensions defined in RFC 5246
static
final
ExtensionType
EXT_SIGNATURE_ALGORITHMS
=
final
static
ExtensionType
EXT_SIGNATURE_ALGORITHMS
=
e
(
0x000D
,
"signature_algorithms"
);
// IANA registry value: 13
// extensions defined in RFC 5746
static
final
ExtensionType
EXT_RENEGOTIATION_INFO
=
final
static
ExtensionType
EXT_RENEGOTIATION_INFO
=
e
(
0xff01
,
"renegotiation_info"
);
// IANA registry value: 65281
}
src/share/classes/sun/security/ssl/HandshakeMessage.java
浏览文件 @
3faae241
/*
* Copyright (c) 1996, 201
7
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 201
5
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
...
...
@@ -982,9 +982,8 @@ class ECDH_ServerKeyExchange extends ServerKeyExchange {
private
final
static
int
CURVE_EXPLICIT_CHAR2
=
2
;
private
final
static
int
CURVE_NAMED_CURVE
=
3
;
// id of the named group we are using
private
int
groupId
;
// id of the curve we are using
private
int
curveId
;
// encoded public point
private
byte
[]
pointBytes
;
...
...
@@ -1003,8 +1002,7 @@ class ECDH_ServerKeyExchange extends ServerKeyExchange {
ECDH_ServerKeyExchange
(
ECDHCrypt
obj
,
PrivateKey
privateKey
,
byte
[]
clntNonce
,
byte
[]
svrNonce
,
SecureRandom
sr
,
SignatureAndHashAlgorithm
signAlgorithm
,
ProtocolVersion
protocolVersion
)
throws
SSLHandshakeException
,
GeneralSecurityException
{
ProtocolVersion
protocolVersion
)
throws
GeneralSecurityException
{
this
.
protocolVersion
=
protocolVersion
;
...
...
@@ -1012,14 +1010,7 @@ class ECDH_ServerKeyExchange extends ServerKeyExchange {
ECParameterSpec
params
=
publicKey
.
getParams
();
ECPoint
point
=
publicKey
.
getW
();
pointBytes
=
JsseJce
.
encodePoint
(
point
,
params
.
getCurve
());
NamedGroup
namedGroup
=
NamedGroup
.
valueOf
(
params
);
if
((
namedGroup
==
null
)
||
(
namedGroup
.
oid
==
null
)
){
// unlikely
throw
new
SSLHandshakeException
(
"Unnamed EC parameter spec: "
+
params
);
}
groupId
=
namedGroup
.
id
;
curveId
=
EllipticCurvesExtension
.
getCurveIndex
(
params
);
if
(
privateKey
==
null
)
{
// ECDH_anon
...
...
@@ -1056,27 +1047,20 @@ class ECDH_ServerKeyExchange extends ServerKeyExchange {
// These parsing errors should never occur as we negotiated
// the supported curves during the exchange of the Hello messages.
if
(
curveType
==
CURVE_NAMED_CURVE
)
{
groupId
=
input
.
getInt16
();
NamedGroup
namedGroup
=
NamedGroup
.
valueOf
(
groupId
);
if
(
namedGroup
==
null
)
{
curveId
=
input
.
getInt16
();
if
(!
EllipticCurvesExtension
.
isSupported
(
curveId
))
{
throw
new
SSLHandshakeException
(
"Un
known named group ID: "
+
group
Id
);
"Un
supported curveId: "
+
curve
Id
);
}
if
(
!
SupportedGroupsExtension
.
supports
(
namedGroup
)
)
{
String
curveOid
=
EllipticCurvesExtension
.
getCurveOid
(
curveId
);
if
(
curveOid
==
null
)
{
throw
new
SSLHandshakeException
(
"Un
supported named group: "
+
namedGroup
);
"Un
known named curve: "
+
curveId
);
}
if
(
namedGroup
.
oid
==
null
)
{
throw
new
SSLHandshakeException
(
"Unknown named EC curve: "
+
namedGroup
);
}
parameters
=
JsseJce
.
getECParameterSpec
(
namedGroup
.
oid
);
parameters
=
JsseJce
.
getECParameterSpec
(
curveOid
);
if
(
parameters
==
null
)
{
throw
new
SSLHandshakeException
(
"
No supported EC parameter for named group: "
+
namedGroup
);
"
Unsupported curve: "
+
curveOid
);
}
}
else
{
throw
new
SSLHandshakeException
(
...
...
@@ -1159,8 +1143,8 @@ class ECDH_ServerKeyExchange extends ServerKeyExchange {
sig
.
update
(
svrNonce
);
sig
.
update
((
byte
)
CURVE_NAMED_CURVE
);
sig
.
update
((
byte
)(
group
Id
>>
8
));
sig
.
update
((
byte
)
group
Id
);
sig
.
update
((
byte
)(
curve
Id
>>
8
));
sig
.
update
((
byte
)
curve
Id
);
sig
.
update
((
byte
)
pointBytes
.
length
);
sig
.
update
(
pointBytes
);
}
...
...
@@ -1181,7 +1165,7 @@ class ECDH_ServerKeyExchange extends ServerKeyExchange {
@Override
void
send
(
HandshakeOutStream
s
)
throws
IOException
{
s
.
putInt8
(
CURVE_NAMED_CURVE
);
s
.
putInt16
(
group
Id
);
s
.
putInt16
(
curve
Id
);
s
.
putBytes8
(
pointBytes
);
if
(
signatureBytes
!=
null
)
{
...
...
src/share/classes/sun/security/ssl/Handshaker.java
浏览文件 @
3faae241
/*
* Copyright (c) 1996, 201
7
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 201
6
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
...
...
@@ -50,7 +50,6 @@ import sun.security.ssl.CipherSuite.*;
import
static
sun
.
security
.
ssl
.
CipherSuite
.
PRF
.*;
import
static
sun
.
security
.
ssl
.
CipherSuite
.
CipherType
.*;
import
static
sun
.
security
.
ssl
.
NamedGroupType
.*;
/**
* Handshaker ... processes handshake records from an SSL V3.0
...
...
@@ -637,14 +636,41 @@ abstract class Handshaker {
ArrayList
<
CipherSuite
>
suites
=
new
ArrayList
<>();
if
(!(
activeProtocols
.
collection
().
isEmpty
())
&&
activeProtocols
.
min
.
v
!=
ProtocolVersion
.
NONE
.
v
)
{
Map
<
NamedGroupType
,
Boolean
>
cachedStatus
=
new
EnumMap
<>(
NamedGroupType
.
class
)
;
boolean
checkedCurves
=
false
;
boolean
hasCurves
=
false
;
for
(
CipherSuite
suite
:
enabledCipherSuites
.
collection
())
{
if
(
suite
.
isAvailable
()
&&
(
suite
.
obsoleted
>
activeProtocols
.
min
.
v
&&
suite
.
supported
<=
activeProtocols
.
max
.
v
))
{
if
(
isActivatable
(
suite
,
cachedStatus
))
{
suites
.
add
(
suite
);
if
(
suite
.
obsoleted
>
activeProtocols
.
min
.
v
&&
suite
.
supported
<=
activeProtocols
.
max
.
v
)
{
if
(
algorithmConstraints
.
permits
(
EnumSet
.
of
(
CryptoPrimitive
.
KEY_AGREEMENT
),
suite
.
name
,
null
))
{
boolean
available
=
true
;
if
(
suite
.
keyExchange
.
isEC
)
{
if
(!
checkedCurves
)
{
hasCurves
=
EllipticCurvesExtension
.
hasActiveCurves
(
algorithmConstraints
);
checkedCurves
=
true
;
if
(!
hasCurves
&&
debug
!=
null
&&
Debug
.
isOn
(
"verbose"
))
{
System
.
out
.
println
(
"No available elliptic curves"
);
}
}
available
=
hasCurves
;
if
(!
available
&&
debug
!=
null
&&
Debug
.
isOn
(
"verbose"
))
{
System
.
out
.
println
(
"No active elliptic curves, ignore "
+
suite
);
}
}
if
(
available
)
{
suites
.
add
(
suite
);
}
}
}
else
if
(
debug
!=
null
&&
Debug
.
isOn
(
"verbose"
))
{
if
(
suite
.
obsoleted
<=
activeProtocols
.
min
.
v
)
{
...
...
@@ -702,15 +728,46 @@ abstract class Handshaker {
continue
;
}
boolean
found
=
false
;
Map
<
NamedGroupType
,
Boolean
>
cachedStatus
=
new
EnumMap
<>(
NamedGroupType
.
class
);
for
(
CipherSuite
suite
:
enabledCipherSuites
.
collection
())
{
if
(
suite
.
isAvailable
()
&&
suite
.
obsoleted
>
protocol
.
v
&&
suite
.
supported
<=
protocol
.
v
)
{
if
(
isActivatable
(
suite
,
cachedStatus
))
{
protocols
.
add
(
protocol
);
found
=
true
;
break
;
if
(
algorithmConstraints
.
permits
(
EnumSet
.
of
(
CryptoPrimitive
.
KEY_AGREEMENT
),
suite
.
name
,
null
))
{
boolean
available
=
true
;
if
(
suite
.
keyExchange
.
isEC
)
{
if
(!
checkedCurves
)
{
hasCurves
=
EllipticCurvesExtension
.
hasActiveCurves
(
algorithmConstraints
);
checkedCurves
=
true
;
if
(!
hasCurves
&&
debug
!=
null
&&
Debug
.
isOn
(
"verbose"
))
{
System
.
out
.
println
(
"No activated elliptic curves"
);
}
}
available
=
hasCurves
;
if
(!
available
&&
debug
!=
null
&&
Debug
.
isOn
(
"verbose"
))
{
System
.
out
.
println
(
"No active elliptic curves, ignore "
+
suite
+
" for "
+
protocol
);
}
}
if
(
available
)
{
protocols
.
add
(
protocol
);
found
=
true
;
break
;
}
}
else
if
(
debug
!=
null
&&
Debug
.
isOn
(
"verbose"
))
{
System
.
out
.
println
(
"Ignoring disabled cipher suite: "
+
suite
+
" for "
+
protocol
);
}
}
else
if
(
debug
!=
null
&&
Debug
.
isOn
(
"verbose"
))
{
System
.
out
.
println
(
...
...
@@ -718,7 +775,6 @@ abstract class Handshaker {
" for "
+
protocol
);
}
}
if
(!
found
&&
(
debug
!=
null
)
&&
Debug
.
isOn
(
"handshake"
))
{
System
.
out
.
println
(
"No available cipher suite for "
+
protocol
);
...
...
@@ -735,43 +791,6 @@ abstract class Handshaker {
return
activeProtocols
;
}
private
boolean
isActivatable
(
CipherSuite
suite
,
Map
<
NamedGroupType
,
Boolean
>
cachedStatus
)
{
if
(
algorithmConstraints
.
permits
(
EnumSet
.
of
(
CryptoPrimitive
.
KEY_AGREEMENT
),
suite
.
name
,
null
))
{
boolean
available
=
true
;
NamedGroupType
groupType
=
suite
.
keyExchange
.
groupType
;
if
(
groupType
!=
NAMED_GROUP_NONE
)
{
Boolean
checkedStatus
=
cachedStatus
.
get
(
groupType
);
if
(
checkedStatus
==
null
)
{
available
=
SupportedGroupsExtension
.
isActivatable
(
algorithmConstraints
,
groupType
);
cachedStatus
.
put
(
groupType
,
available
);
if
(!
available
&&
debug
!=
null
&&
Debug
.
isOn
(
"verbose"
))
{
System
.
out
.
println
(
"No activated named group"
);
}
}
else
{
available
=
checkedStatus
.
booleanValue
();
}
if
(!
available
&&
debug
!=
null
&&
Debug
.
isOn
(
"verbose"
))
{
System
.
out
.
println
(
"No active named group, ignore "
+
suite
);
}
return
available
;
}
else
{
return
true
;
}
}
else
if
(
debug
!=
null
&&
Debug
.
isOn
(
"verbose"
))
{
System
.
out
.
println
(
"Ignoring disabled cipher suite: "
+
suite
);
}
return
false
;
}
/**
* As long as handshaking has not activated, we can
* change whether session creations are allowed.
...
...
src/share/classes/sun/security/ssl/HelloExtensions.java
浏览文件 @
3faae241
/*
* Copyright (c) 2006, 201
7
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2006, 201
6
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
...
...
@@ -49,7 +49,7 @@ import javax.net.ssl.*;
* explicitly support.
* . ServerNameExtension: the server_name extension.
* . SignatureAlgorithmsExtension: the signature_algorithms extension.
* .
SupportedGroupsExtension: the supported group
s extension.
* .
EllipticCurvesExtension: the ECC supported curve
s extension.
* . EllipticPointFormatsExtension: the ECC supported point formats
* (compressed/uncompressed) extension.
*
...
...
@@ -78,8 +78,8 @@ final class HelloExtensions {
extension
=
new
ServerNameExtension
(
s
,
extlen
);
}
else
if
(
extType
==
ExtensionType
.
EXT_SIGNATURE_ALGORITHMS
)
{
extension
=
new
SignatureAlgorithmsExtension
(
s
,
extlen
);
}
else
if
(
extType
==
ExtensionType
.
EXT_
SUPPORTED_GROUP
S
)
{
extension
=
new
SupportedGroup
sExtension
(
s
,
extlen
);
}
else
if
(
extType
==
ExtensionType
.
EXT_
ELLIPTIC_CURVE
S
)
{
extension
=
new
EllipticCurve
sExtension
(
s
,
extlen
);
}
else
if
(
extType
==
ExtensionType
.
EXT_EC_POINT_FORMATS
)
{
extension
=
new
EllipticPointFormatsExtension
(
s
,
extlen
);
}
else
if
(
extType
==
ExtensionType
.
EXT_RENEGOTIATION_INFO
)
{
...
...
src/share/classes/sun/security/ssl/NamedGroup.java
已删除
100644 → 0
浏览文件 @
25f17276
/*
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package
sun.security.ssl
;
import
java.security.spec.ECParameterSpec
;
import
java.security.spec.ECGenParameterSpec
;
import
static
sun
.
security
.
ssl
.
NamedGroupType
.*;
enum
NamedGroup
{
// Elliptic Curves (RFC 4492)
//
// See sun.security.util.CurveDB for the OIDs
// NIST K-163
SECT163_K1
(
1
,
NAMED_GROUP_ECDHE
,
"sect163k1"
,
"1.3.132.0.1"
,
true
),
SECT163_R1
(
2
,
NAMED_GROUP_ECDHE
,
"sect163r1"
,
"1.3.132.0.2"
,
false
),
// NIST B-163
SECT163_R2
(
3
,
NAMED_GROUP_ECDHE
,
"sect163r2"
,
"1.3.132.0.15"
,
true
),
SECT193_R1
(
4
,
NAMED_GROUP_ECDHE
,
"sect193r1"
,
"1.3.132.0.24"
,
false
),
SECT193_R2
(
5
,
NAMED_GROUP_ECDHE
,
"sect193r2"
,
"1.3.132.0.25"
,
false
),
// NIST K-233
SECT233_K1
(
6
,
NAMED_GROUP_ECDHE
,
"sect233k1"
,
"1.3.132.0.26"
,
true
),
// NIST B-233
SECT233_R1
(
7
,
NAMED_GROUP_ECDHE
,
"sect233r1"
,
"1.3.132.0.27"
,
true
),
SECT239_K1
(
8
,
NAMED_GROUP_ECDHE
,
"sect239k1"
,
"1.3.132.0.3"
,
false
),
// NIST K-283
SECT283_K1
(
9
,
NAMED_GROUP_ECDHE
,
"sect283k1"
,
"1.3.132.0.16"
,
true
),
// NIST B-283
SECT283_R1
(
10
,
NAMED_GROUP_ECDHE
,
"sect283r1"
,
"1.3.132.0.17"
,
true
),
// NIST K-409
SECT409_K1
(
11
,
NAMED_GROUP_ECDHE
,
"sect409k1"
,
"1.3.132.0.36"
,
true
),
// NIST B-409
SECT409_R1
(
12
,
NAMED_GROUP_ECDHE
,
"sect409r1"
,
"1.3.132.0.37"
,
true
),
// NIST K-571
SECT571_K1
(
13
,
NAMED_GROUP_ECDHE
,
"sect571k1"
,
"1.3.132.0.38"
,
true
),
// NIST B-571
SECT571_R1
(
14
,
NAMED_GROUP_ECDHE
,
"sect571r1"
,
"1.3.132.0.39"
,
true
),
SECP160_K1
(
15
,
NAMED_GROUP_ECDHE
,
"secp160k1"
,
"1.3.132.0.9"
,
false
),
SECP160_R1
(
16
,
NAMED_GROUP_ECDHE
,
"secp160r1"
,
"1.3.132.0.8"
,
false
),
SECP160_R2
(
17
,
NAMED_GROUP_ECDHE
,
"secp160r2"
,
"1.3.132.0.30"
,
false
),
SECP192_K1
(
18
,
NAMED_GROUP_ECDHE
,
"secp192k1"
,
"1.3.132.0.31"
,
false
),
// NIST P-192
SECP192_R1
(
19
,
NAMED_GROUP_ECDHE
,
"secp192r1"
,
"1.2.840.10045.3.1.1"
,
true
),
SECP224_K1
(
20
,
NAMED_GROUP_ECDHE
,
"secp224k1"
,
"1.3.132.0.32"
,
false
),
// NIST P-224
SECP224_R1
(
21
,
NAMED_GROUP_ECDHE
,
"secp224r1"
,
"1.3.132.0.33"
,
true
),
SECP256_K1
(
22
,
NAMED_GROUP_ECDHE
,
"secp256k1"
,
"1.3.132.0.10"
,
false
),
// NIST P-256
SECP256_R1
(
23
,
NAMED_GROUP_ECDHE
,
"secp256r1"
,
"1.2.840.10045.3.1.7"
,
true
),
// NIST P-384
SECP384_R1
(
24
,
NAMED_GROUP_ECDHE
,
"secp384r1"
,
"1.3.132.0.34"
,
true
),
// NIST P-521
SECP521_R1
(
25
,
NAMED_GROUP_ECDHE
,
"secp521r1"
,
"1.3.132.0.35"
,
true
),
// Finite Field Diffie-Hellman Ephemeral Parameters (RFC 7919)
FFDHE_2048
(
256
,
NAMED_GROUP_FFDHE
,
"ffdhe2048"
,
true
),
FFDHE_3072
(
257
,
NAMED_GROUP_FFDHE
,
"ffdhe3072"
,
true
),
FFDHE_4096
(
258
,
NAMED_GROUP_FFDHE
,
"ffdhe4096"
,
true
),
FFDHE_6144
(
259
,
NAMED_GROUP_FFDHE
,
"ffdhe6144"
,
true
),
FFDHE_8192
(
260
,
NAMED_GROUP_FFDHE
,
"ffdhe8192"
,
true
);
int
id
;
NamedGroupType
type
;
String
name
;
String
oid
;
String
algorithm
;
boolean
isFips
;
// Constructor used for Elliptic Curve Groups (ECDHE)
NamedGroup
(
int
id
,
NamedGroupType
type
,
String
name
,
String
oid
,
boolean
isFips
)
{
this
.
id
=
id
;
this
.
type
=
type
;
this
.
name
=
name
;
this
.
oid
=
oid
;
this
.
algorithm
=
"EC"
;
this
.
isFips
=
isFips
;
}
// Constructor used for Finite Field Diffie-Hellman Groups (FFDHE)
NamedGroup
(
int
id
,
NamedGroupType
type
,
String
name
,
boolean
isFips
)
{
this
.
id
=
id
;
this
.
type
=
type
;
this
.
name
=
name
;
this
.
oid
=
null
;
this
.
algorithm
=
"DiffieHellman"
;
this
.
isFips
=
isFips
;
}
static
NamedGroup
valueOf
(
int
id
)
{
for
(
NamedGroup
group
:
NamedGroup
.
values
())
{
if
(
group
.
id
==
id
)
{
return
group
;
}
}
return
null
;
}
static
NamedGroup
nameOf
(
String
name
)
{
for
(
NamedGroup
group
:
NamedGroup
.
values
())
{
if
(
group
.
name
.
equals
(
name
))
{
return
group
;
}
}
return
null
;
}
static
NamedGroup
valueOf
(
ECParameterSpec
params
)
{
String
oid
=
JsseJce
.
getNamedCurveOid
(
params
);
if
((
oid
!=
null
)
&&
(!
oid
.
isEmpty
()))
{
for
(
NamedGroup
group
:
NamedGroup
.
values
())
{
if
(
oid
.
equals
(
group
.
oid
))
{
return
group
;
}
}
}
return
null
;
}
@Override
public
String
toString
()
{
return
this
.
name
;
}
}
src/share/classes/sun/security/ssl/NamedGroupType.java
已删除
100644 → 0
浏览文件 @
25f17276
/*
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package
sun.security.ssl
;
enum
NamedGroupType
{
NAMED_GROUP_ECDHE
,
// Elliptic Curve Groups (ECDHE)
NAMED_GROUP_FFDHE
,
// Finite Field Groups (DHE)
NAMED_GROUP_NONE
// No predefined named group
}
src/share/classes/sun/security/ssl/PredefinedDHParameterSpecs.java
已删除
100644 → 0
浏览文件 @
25f17276
/*
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package
sun.security.ssl
;
import
java.security.*
;
import
java.math.BigInteger
;
import
java.util.regex.Pattern
;
import
java.util.regex.Matcher
;
import
java.util.Map
;
import
java.util.HashMap
;
import
java.util.Collections
;
import
javax.crypto.spec.DHParameterSpec
;
/**
* Predefined default DH ephemeral parameters.
*/
final
class
PredefinedDHParameterSpecs
{
private
final
static
boolean
debugIsOn
=
(
Debug
.
getInstance
(
"ssl"
)
!=
null
)
&&
Debug
.
isOn
(
"sslctx"
);
//
// Default DH ephemeral parameters
//
private
static
final
BigInteger
p512
=
new
BigInteger
(
// generated
"D87780E15FF50B4ABBE89870188B049406B5BEA98AB23A02"
+
"41D88EA75B7755E669C08093D3F0CA7FC3A5A25CF067DCB9"
+
"A43DD89D1D90921C6328884461E0B6D3"
,
16
);
private
static
final
BigInteger
p768
=
new
BigInteger
(
// RFC 2409
"FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"
+
"29024E088A67CC74020BBEA63B139B22514A08798E3404DD"
+
"EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245"
+
"E485B576625E7EC6F44C42E9A63A3620FFFFFFFFFFFFFFFF"
,
16
);
private
static
final
BigInteger
p1024
=
new
BigInteger
(
// RFC 2409
"FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"
+
"29024E088A67CC74020BBEA63B139B22514A08798E3404DD"
+
"EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245"
+
"E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED"
+
"EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381"
+
"FFFFFFFFFFFFFFFF"
,
16
);
private
static
final
BigInteger
p1536
=
new
BigInteger
(
// RFC 3526
"FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"
+
"29024E088A67CC74020BBEA63B139B22514A08798E3404DD"
+
"EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245"
+
"E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED"
+
"EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D"
+
"C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F"
+
"83655D23DCA3AD961C62F356208552BB9ED529077096966D"
+
"670C354E4ABC9804F1746C08CA237327FFFFFFFFFFFFFFFF"
,
16
);
private
static
final
BigInteger
p2048
=
new
BigInteger
(
// TLS FFDHE
"FFFFFFFFFFFFFFFFADF85458A2BB4A9AAFDC5620273D3CF1"
+
"D8B9C583CE2D3695A9E13641146433FBCC939DCE249B3EF9"
+
"7D2FE363630C75D8F681B202AEC4617AD3DF1ED5D5FD6561"
+
"2433F51F5F066ED0856365553DED1AF3B557135E7F57C935"
+
"984F0C70E0E68B77E2A689DAF3EFE8721DF158A136ADE735"
+
"30ACCA4F483A797ABC0AB182B324FB61D108A94BB2C8E3FB"
+
"B96ADAB760D7F4681D4F42A3DE394DF4AE56EDE76372BB19"
+
"0B07A7C8EE0A6D709E02FCE1CDF7E2ECC03404CD28342F61"
+
"9172FE9CE98583FF8E4F1232EEF28183C3FE3B1B4C6FAD73"
+
"3BB5FCBC2EC22005C58EF1837D1683B2C6F34A26C1B2EFFA"
+
"886B423861285C97FFFFFFFFFFFFFFFF"
,
16
);
private
static
final
BigInteger
p3072
=
new
BigInteger
(
// TLS FFDHE
"FFFFFFFFFFFFFFFFADF85458A2BB4A9AAFDC5620273D3CF1"
+
"D8B9C583CE2D3695A9E13641146433FBCC939DCE249B3EF9"
+
"7D2FE363630C75D8F681B202AEC4617AD3DF1ED5D5FD6561"
+
"2433F51F5F066ED0856365553DED1AF3B557135E7F57C935"
+
"984F0C70E0E68B77E2A689DAF3EFE8721DF158A136ADE735"
+
"30ACCA4F483A797ABC0AB182B324FB61D108A94BB2C8E3FB"
+
"B96ADAB760D7F4681D4F42A3DE394DF4AE56EDE76372BB19"
+
"0B07A7C8EE0A6D709E02FCE1CDF7E2ECC03404CD28342F61"
+
"9172FE9CE98583FF8E4F1232EEF28183C3FE3B1B4C6FAD73"
+
"3BB5FCBC2EC22005C58EF1837D1683B2C6F34A26C1B2EFFA"
+
"886B4238611FCFDCDE355B3B6519035BBC34F4DEF99C0238"
+
"61B46FC9D6E6C9077AD91D2691F7F7EE598CB0FAC186D91C"
+
"AEFE130985139270B4130C93BC437944F4FD4452E2D74DD3"
+
"64F2E21E71F54BFF5CAE82AB9C9DF69EE86D2BC522363A0D"
+
"ABC521979B0DEADA1DBF9A42D5C4484E0ABCD06BFA53DDEF"
+
"3C1B20EE3FD59D7C25E41D2B66C62E37FFFFFFFFFFFFFFFF"
,
16
);
private
static
final
BigInteger
p4096
=
new
BigInteger
(
// TLS FFDHE
"FFFFFFFFFFFFFFFFADF85458A2BB4A9AAFDC5620273D3CF1"
+
"D8B9C583CE2D3695A9E13641146433FBCC939DCE249B3EF9"
+
"7D2FE363630C75D8F681B202AEC4617AD3DF1ED5D5FD6561"
+
"2433F51F5F066ED0856365553DED1AF3B557135E7F57C935"
+
"984F0C70E0E68B77E2A689DAF3EFE8721DF158A136ADE735"
+
"30ACCA4F483A797ABC0AB182B324FB61D108A94BB2C8E3FB"
+
"B96ADAB760D7F4681D4F42A3DE394DF4AE56EDE76372BB19"
+
"0B07A7C8EE0A6D709E02FCE1CDF7E2ECC03404CD28342F61"
+
"9172FE9CE98583FF8E4F1232EEF28183C3FE3B1B4C6FAD73"
+
"3BB5FCBC2EC22005C58EF1837D1683B2C6F34A26C1B2EFFA"
+
"886B4238611FCFDCDE355B3B6519035BBC34F4DEF99C0238"
+
"61B46FC9D6E6C9077AD91D2691F7F7EE598CB0FAC186D91C"
+
"AEFE130985139270B4130C93BC437944F4FD4452E2D74DD3"
+
"64F2E21E71F54BFF5CAE82AB9C9DF69EE86D2BC522363A0D"
+
"ABC521979B0DEADA1DBF9A42D5C4484E0ABCD06BFA53DDEF"
+
"3C1B20EE3FD59D7C25E41D2B669E1EF16E6F52C3164DF4FB"
+
"7930E9E4E58857B6AC7D5F42D69F6D187763CF1D55034004"
+
"87F55BA57E31CC7A7135C886EFB4318AED6A1E012D9E6832"
+
"A907600A918130C46DC778F971AD0038092999A333CB8B7A"
+
"1A1DB93D7140003C2A4ECEA9F98D0ACC0A8291CDCEC97DCF"
+
"8EC9B55A7F88A46B4DB5A851F44182E1C68A007E5E655F6A"
+
"FFFFFFFFFFFFFFFF"
,
16
);
private
static
final
BigInteger
p6144
=
new
BigInteger
(
// TLS FFDHE
"FFFFFFFFFFFFFFFFADF85458A2BB4A9AAFDC5620273D3CF1"
+
"D8B9C583CE2D3695A9E13641146433FBCC939DCE249B3EF9"
+
"7D2FE363630C75D8F681B202AEC4617AD3DF1ED5D5FD6561"
+
"2433F51F5F066ED0856365553DED1AF3B557135E7F57C935"
+
"984F0C70E0E68B77E2A689DAF3EFE8721DF158A136ADE735"
+
"30ACCA4F483A797ABC0AB182B324FB61D108A94BB2C8E3FB"
+
"B96ADAB760D7F4681D4F42A3DE394DF4AE56EDE76372BB19"
+
"0B07A7C8EE0A6D709E02FCE1CDF7E2ECC03404CD28342F61"
+
"9172FE9CE98583FF8E4F1232EEF28183C3FE3B1B4C6FAD73"
+
"3BB5FCBC2EC22005C58EF1837D1683B2C6F34A26C1B2EFFA"
+
"886B4238611FCFDCDE355B3B6519035BBC34F4DEF99C0238"
+
"61B46FC9D6E6C9077AD91D2691F7F7EE598CB0FAC186D91C"
+
"AEFE130985139270B4130C93BC437944F4FD4452E2D74DD3"
+
"64F2E21E71F54BFF5CAE82AB9C9DF69EE86D2BC522363A0D"
+
"ABC521979B0DEADA1DBF9A42D5C4484E0ABCD06BFA53DDEF"
+
"3C1B20EE3FD59D7C25E41D2B669E1EF16E6F52C3164DF4FB"
+
"7930E9E4E58857B6AC7D5F42D69F6D187763CF1D55034004"
+
"87F55BA57E31CC7A7135C886EFB4318AED6A1E012D9E6832"
+
"A907600A918130C46DC778F971AD0038092999A333CB8B7A"
+
"1A1DB93D7140003C2A4ECEA9F98D0ACC0A8291CDCEC97DCF"
+
"8EC9B55A7F88A46B4DB5A851F44182E1C68A007E5E0DD902"
+
"0BFD64B645036C7A4E677D2C38532A3A23BA4442CAF53EA6"
+
"3BB454329B7624C8917BDD64B1C0FD4CB38E8C334C701C3A"
+
"CDAD0657FCCFEC719B1F5C3E4E46041F388147FB4CFDB477"
+
"A52471F7A9A96910B855322EDB6340D8A00EF092350511E3"
+
"0ABEC1FFF9E3A26E7FB29F8C183023C3587E38DA0077D9B4"
+
"763E4E4B94B2BBC194C6651E77CAF992EEAAC0232A281BF6"
+
"B3A739C1226116820AE8DB5847A67CBEF9C9091B462D538C"
+
"D72B03746AE77F5E62292C311562A846505DC82DB854338A"
+
"E49F5235C95B91178CCF2DD5CACEF403EC9D1810C6272B04"
+
"5B3B71F9DC6B80D63FDD4A8E9ADB1E6962A69526D43161C1"
+
"A41D570D7938DAD4A40E329CD0E40E65FFFFFFFFFFFFFFFF"
,
16
);
private
static
final
BigInteger
p8192
=
new
BigInteger
(
// TLS FFDHE
"FFFFFFFFFFFFFFFFADF85458A2BB4A9AAFDC5620273D3CF1"
+
"D8B9C583CE2D3695A9E13641146433FBCC939DCE249B3EF9"
+
"7D2FE363630C75D8F681B202AEC4617AD3DF1ED5D5FD6561"
+
"2433F51F5F066ED0856365553DED1AF3B557135E7F57C935"
+
"984F0C70E0E68B77E2A689DAF3EFE8721DF158A136ADE735"
+
"30ACCA4F483A797ABC0AB182B324FB61D108A94BB2C8E3FB"
+
"B96ADAB760D7F4681D4F42A3DE394DF4AE56EDE76372BB19"
+
"0B07A7C8EE0A6D709E02FCE1CDF7E2ECC03404CD28342F61"
+
"9172FE9CE98583FF8E4F1232EEF28183C3FE3B1B4C6FAD73"
+
"3BB5FCBC2EC22005C58EF1837D1683B2C6F34A26C1B2EFFA"
+
"886B4238611FCFDCDE355B3B6519035BBC34F4DEF99C0238"
+
"61B46FC9D6E6C9077AD91D2691F7F7EE598CB0FAC186D91C"
+
"AEFE130985139270B4130C93BC437944F4FD4452E2D74DD3"
+
"64F2E21E71F54BFF5CAE82AB9C9DF69EE86D2BC522363A0D"
+
"ABC521979B0DEADA1DBF9A42D5C4484E0ABCD06BFA53DDEF"
+
"3C1B20EE3FD59D7C25E41D2B669E1EF16E6F52C3164DF4FB"
+
"7930E9E4E58857B6AC7D5F42D69F6D187763CF1D55034004"
+
"87F55BA57E31CC7A7135C886EFB4318AED6A1E012D9E6832"
+
"A907600A918130C46DC778F971AD0038092999A333CB8B7A"
+
"1A1DB93D7140003C2A4ECEA9F98D0ACC0A8291CDCEC97DCF"
+
"8EC9B55A7F88A46B4DB5A851F44182E1C68A007E5E0DD902"
+
"0BFD64B645036C7A4E677D2C38532A3A23BA4442CAF53EA6"
+
"3BB454329B7624C8917BDD64B1C0FD4CB38E8C334C701C3A"
+
"CDAD0657FCCFEC719B1F5C3E4E46041F388147FB4CFDB477"
+
"A52471F7A9A96910B855322EDB6340D8A00EF092350511E3"
+
"0ABEC1FFF9E3A26E7FB29F8C183023C3587E38DA0077D9B4"
+
"763E4E4B94B2BBC194C6651E77CAF992EEAAC0232A281BF6"
+
"B3A739C1226116820AE8DB5847A67CBEF9C9091B462D538C"
+
"D72B03746AE77F5E62292C311562A846505DC82DB854338A"
+
"E49F5235C95B91178CCF2DD5CACEF403EC9D1810C6272B04"
+
"5B3B71F9DC6B80D63FDD4A8E9ADB1E6962A69526D43161C1"
+
"A41D570D7938DAD4A40E329CCFF46AAA36AD004CF600C838"
+
"1E425A31D951AE64FDB23FCEC9509D43687FEB69EDD1CC5E"
+
"0B8CC3BDF64B10EF86B63142A3AB8829555B2F747C932665"
+
"CB2C0F1CC01BD70229388839D2AF05E454504AC78B758282"
+
"2846C0BA35C35F5C59160CC046FD8251541FC68C9C86B022"
+
"BB7099876A460E7451A8A93109703FEE1C217E6C3826E52C"
+
"51AA691E0E423CFC99E9E31650C1217B624816CDAD9A95F9"
+
"D5B8019488D9C0A0A1FE3075A577E23183F81D4A3F2FA457"
+
"1EFC8CE0BA8A4FE8B6855DFE72B0A66EDED2FBABFBE58A30"
+
"FAFABE1C5D71A87E2F741EF8C1FE86FEA6BBFDE530677F0D"
+
"97D11D49F7A8443D0822E506A9F4614E011E2A94838FF88C"
+
"D68C8BB7C5C6424CFFFFFFFFFFFFFFFF"
,
16
);
private
static
final
BigInteger
[]
supportedPrimes
=
{
p512
,
p768
,
p1024
,
p1536
,
p2048
,
p3072
,
p4096
,
p6144
,
p8192
};
private
static
final
BigInteger
[]
ffdhePrimes
=
{
p2048
,
p3072
,
p4096
,
p6144
,
p8192
};
// a measure of the uncertainty that prime modulus p is not a prime
//
// see BigInteger.isProbablePrime(int certainty)
private
final
static
int
PRIME_CERTAINTY
=
120
;
// the known security property, jdk.tls.server.defaultDHEParameters
private
final
static
String
PROPERTY_NAME
=
"jdk.tls.server.defaultDHEParameters"
;
private
static
final
Pattern
spacesPattern
=
Pattern
.
compile
(
"\\s+"
);
private
final
static
Pattern
syntaxPattern
=
Pattern
.
compile
(
"(\\{[0-9A-Fa-f]+,[0-9A-Fa-f]+\\})"
+
"(,\\{[0-9A-Fa-f]+,[0-9A-Fa-f]+\\})*"
);
private
static
final
Pattern
paramsPattern
=
Pattern
.
compile
(
"\\{([0-9A-Fa-f]+),([0-9A-Fa-f]+)\\}"
);
// cache of predefined default DH ephemeral parameters
final
static
Map
<
Integer
,
DHParameterSpec
>
definedParams
;
// cache of Finite Field DH Ephemeral parameters (RFC 7919/FFDHE)
final
static
Map
<
Integer
,
DHParameterSpec
>
ffdheParams
;
static
{
String
property
=
AccessController
.
doPrivileged
(
new
PrivilegedAction
<
String
>()
{
public
String
run
()
{
return
Security
.
getProperty
(
PROPERTY_NAME
);
}
});
if
(
property
!=
null
&&
!
property
.
isEmpty
())
{
// remove double quote marks from beginning/end of the property
if
(
property
.
length
()
>=
2
&&
property
.
charAt
(
0
)
==
'"'
&&
property
.
charAt
(
property
.
length
()
-
1
)
==
'"'
)
{
property
=
property
.
substring
(
1
,
property
.
length
()
-
1
);
}
property
=
property
.
trim
();
}
if
(
property
!=
null
&&
!
property
.
isEmpty
())
{
Matcher
spacesMatcher
=
spacesPattern
.
matcher
(
property
);
property
=
spacesMatcher
.
replaceAll
(
""
);
if
(
debugIsOn
)
{
System
.
out
.
println
(
"The Security Property "
+
PROPERTY_NAME
+
": "
+
property
);
}
}
Map
<
Integer
,
DHParameterSpec
>
defaultParams
=
new
HashMap
<>();
if
(
property
!=
null
&&
!
property
.
isEmpty
())
{
Matcher
syntaxMatcher
=
syntaxPattern
.
matcher
(
property
);
if
(
syntaxMatcher
.
matches
())
{
Matcher
paramsFinder
=
paramsPattern
.
matcher
(
property
);
while
(
paramsFinder
.
find
())
{
String
primeModulus
=
paramsFinder
.
group
(
1
);
BigInteger
p
=
new
BigInteger
(
primeModulus
,
16
);
if
(!
p
.
isProbablePrime
(
PRIME_CERTAINTY
))
{
if
(
debugIsOn
)
{
System
.
out
.
println
(
"Prime modulus p in Security Property, "
+
PROPERTY_NAME
+
", is not a prime: "
+
primeModulus
);
}
continue
;
}
String
baseGenerator
=
paramsFinder
.
group
(
2
);
BigInteger
g
=
new
BigInteger
(
baseGenerator
,
16
);
DHParameterSpec
spec
=
new
DHParameterSpec
(
p
,
g
);
int
primeLen
=
p
.
bitLength
();
defaultParams
.
put
(
primeLen
,
spec
);
}
}
else
if
(
debugIsOn
)
{
System
.
out
.
println
(
"Invalid Security Property, "
+
PROPERTY_NAME
+
", definition"
);
}
}
Map
<
Integer
,
DHParameterSpec
>
tempFFDHEs
=
new
HashMap
<>();
for
(
BigInteger
p
:
ffdhePrimes
)
{
int
primeLen
=
p
.
bitLength
();
DHParameterSpec
dhps
=
new
DHParameterSpec
(
p
,
BigInteger
.
valueOf
(
2
));
tempFFDHEs
.
put
(
primeLen
,
dhps
);
defaultParams
.
putIfAbsent
(
primeLen
,
dhps
);
}
for
(
BigInteger
p
:
supportedPrimes
)
{
int
primeLen
=
p
.
bitLength
();
if
(
defaultParams
.
get
(
primeLen
)
==
null
)
{
defaultParams
.
put
(
primeLen
,
new
DHParameterSpec
(
p
,
BigInteger
.
valueOf
(
2
)));
}
}
ffdheParams
=
Collections
.<
Integer
,
DHParameterSpec
>
unmodifiableMap
(
tempFFDHEs
);
definedParams
=
Collections
.<
Integer
,
DHParameterSpec
>
unmodifiableMap
(
defaultParams
);
}
}
src/share/classes/sun/security/ssl/ServerHandshaker.java
浏览文件 @
3faae241
/*
* Copyright (c) 1996, 201
7
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 201
5
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
...
...
@@ -93,7 +93,7 @@ final class ServerHandshaker extends Handshaker {
private
ProtocolVersion
clientRequestedVersion
;
// client supported elliptic curves
private
SupportedGroupsExtension
requestedGroup
s
;
private
EllipticCurvesExtension
requestedCurve
s
;
// the preferable signature algorithm used by ServerKeyExchange message
SignatureAndHashAlgorithm
preferableSignatureAlgorithm
;
...
...
@@ -683,8 +683,8 @@ final class ServerHandshaker extends Handshaker {
throw
new
SSLException
(
"Client did not resume a session"
);
}
requested
Groups
=
(
SupportedGroup
sExtension
)
mesg
.
extensions
.
get
(
ExtensionType
.
EXT_SUPPORTED_GROUP
S
);
requested
Curves
=
(
EllipticCurve
sExtension
)
mesg
.
extensions
.
get
(
ExtensionType
.
EXT_ELLIPTIC_CURVE
S
);
// We only need to handle the "signature_algorithm" extension
// for full handshakes and TLS 1.2 or later.
...
...
@@ -1158,8 +1158,6 @@ final class ServerHandshaker extends Handshaker {
}
}
// The named group used for ECDHE and FFDHE.
NamedGroup
namedGroup
=
null
;
switch
(
keyExchange
)
{
case
K_RSA:
// need RSA certs for authentication
...
...
@@ -1185,37 +1183,6 @@ final class ServerHandshaker extends Handshaker {
}
break
;
case
K_DHE_RSA:
// Is ephemeral DH cipher suite usable for the connection?
//
// [RFC 7919] If a compatible TLS server receives a Supported
// Groups extension from a client that includes any FFDHE group
// (i.e., any codepoint between 256 and 511, inclusive, even if
// unknown to the server), and if none of the client-proposed
// FFDHE groups are known and acceptable to the server, then
// the server MUST NOT select an FFDHE cipher suite. In this
// case, the server SHOULD select an acceptable non-FFDHE cipher
// suite from the client's offered list. If the extension is
// present with FFDHE groups, none of the client's offered
// groups are acceptable by the server, and none of the client's
// proposed non-FFDHE cipher suites are acceptable to the server,
// the server MUST end the connection with a fatal TLS alert
// of type insufficient_security(71).
//
// Note: For compatibility, if an application is customized to
// use legacy sizes (512 bits for exportable cipher suites and
// 768 bits for others), or the cipher suite is exportable, the
// FFDHE extension will not be used.
if
((!
useLegacyEphemeralDHKeys
)
&&
(!
suite
.
exportable
)
&&
(
requestedGroups
!=
null
)
&&
requestedGroups
.
hasFFDHEGroup
())
{
namedGroup
=
requestedGroups
.
getPreferredGroup
(
algorithmConstraints
,
NamedGroupType
.
NAMED_GROUP_FFDHE
);
if
(
namedGroup
==
null
)
{
// no match found, cannot use this cipher suite.
return
false
;
}
}
// need RSA certs for authentication
if
(
setupPrivateKeyAndChain
(
"RSA"
)
==
false
)
{
return
false
;
...
...
@@ -1236,20 +1203,9 @@ final class ServerHandshaker extends Handshaker {
}
}
setupEphemeralDHKeys
(
namedGroup
,
suite
.
exportable
,
privateKey
);
setupEphemeralDHKeys
(
suite
.
exportable
,
privateKey
);
break
;
case
K_ECDHE_RSA:
// Is ECDHE cipher suite usable for the connection?
namedGroup
=
(
requestedGroups
!=
null
)
?
requestedGroups
.
getPreferredGroup
(
algorithmConstraints
,
NamedGroupType
.
NAMED_GROUP_ECDHE
)
:
SupportedGroupsExtension
.
getPreferredECGroup
(
algorithmConstraints
);
if
(
namedGroup
==
null
)
{
// no match found, cannot use this ciphersuite
return
false
;
}
// need RSA certs for authentication
if
(
setupPrivateKeyAndChain
(
"RSA"
)
==
false
)
{
return
false
;
...
...
@@ -1270,23 +1226,11 @@ final class ServerHandshaker extends Handshaker {
}
}
setupEphemeralECDHKeys
(
namedGroup
);
if
(
setupEphemeralECDHKeys
()
==
false
)
{
return
false
;
}
break
;
case
K_DHE_DSS:
// Is ephemeral DH cipher suite usable for the connection?
//
// See comment in K_DHE_RSA case.
if
((!
useLegacyEphemeralDHKeys
)
&&
(!
suite
.
exportable
)
&&
(
requestedGroups
!=
null
)
&&
requestedGroups
.
hasFFDHEGroup
())
{
namedGroup
=
requestedGroups
.
getPreferredGroup
(
algorithmConstraints
,
NamedGroupType
.
NAMED_GROUP_FFDHE
);
if
(
namedGroup
==
null
)
{
// no match found, cannot use this cipher suite.
return
false
;
}
}
// get preferable peer signature algorithm for server key exchange
if
(
protocolVersion
.
v
>=
ProtocolVersion
.
TLS12
.
v
)
{
preferableSignatureAlgorithm
=
...
...
@@ -1307,20 +1251,9 @@ final class ServerHandshaker extends Handshaker {
return
false
;
}
setupEphemeralDHKeys
(
namedGroup
,
suite
.
exportable
,
privateKey
);
setupEphemeralDHKeys
(
suite
.
exportable
,
privateKey
);
break
;
case
K_ECDHE_ECDSA:
// Is ECDHE cipher suite usable for the connection?
namedGroup
=
(
requestedGroups
!=
null
)
?
requestedGroups
.
getPreferredGroup
(
algorithmConstraints
,
NamedGroupType
.
NAMED_GROUP_ECDHE
)
:
SupportedGroupsExtension
.
getPreferredECGroup
(
algorithmConstraints
);
if
(
namedGroup
==
null
)
{
// no match found, cannot use this ciphersuite
return
false
;
}
// get preferable peer signature algorithm for server key exchange
if
(
protocolVersion
.
v
>=
ProtocolVersion
.
TLS12
.
v
)
{
preferableSignatureAlgorithm
=
...
...
@@ -1340,8 +1273,9 @@ final class ServerHandshaker extends Handshaker {
if
(
setupPrivateKeyAndChain
(
"EC"
)
==
false
)
{
return
false
;
}
setupEphemeralECDHKeys
(
namedGroup
);
if
(
setupEphemeralECDHKeys
()
==
false
)
{
return
false
;
}
break
;
case
K_ECDH_RSA:
// need EC cert
...
...
@@ -1365,36 +1299,14 @@ final class ServerHandshaker extends Handshaker {
}
break
;
case
K_DH_ANON:
// Is ephemeral DH cipher suite usable for the connection?
//
// See comment in K_DHE_RSA case.
if
((!
useLegacyEphemeralDHKeys
)
&&
(!
suite
.
exportable
)
&&
(
requestedGroups
!=
null
)
&&
requestedGroups
.
hasFFDHEGroup
())
{
namedGroup
=
requestedGroups
.
getPreferredGroup
(
algorithmConstraints
,
NamedGroupType
.
NAMED_GROUP_FFDHE
);
if
(
namedGroup
==
null
)
{
// no match found, cannot use this cipher suite.
return
false
;
}
}
// no certs needed for anonymous
setupEphemeralDHKeys
(
namedGroup
,
suite
.
exportable
,
null
);
setupEphemeralDHKeys
(
suite
.
exportable
,
null
);
break
;
case
K_ECDH_ANON:
// Is ECDHE cipher suite usable for the connection?
namedGroup
=
(
requestedGroups
!=
null
)
?
requestedGroups
.
getPreferredGroup
(
algorithmConstraints
,
NamedGroupType
.
NAMED_GROUP_ECDHE
)
:
SupportedGroupsExtension
.
getPreferredECGroup
(
algorithmConstraints
);
if
(
namedGroup
==
null
)
{
// no match found, cannot use this ciphersuite
// no certs needed for anonymous
if
(
setupEphemeralECDHKeys
()
==
false
)
{
return
false
;
}
// no certs needed for anonymous
setupEphemeralECDHKeys
(
namedGroup
);
break
;
default
:
// internal error, unknown key exchange
...
...
@@ -1438,15 +1350,7 @@ final class ServerHandshaker extends Handshaker {
* Acquire some "ephemeral" Diffie-Hellman keys for this handshake.
* We don't reuse these, for improved forward secrecy.
*/
private
void
setupEphemeralDHKeys
(
NamedGroup
namedGroup
,
boolean
export
,
Key
key
)
{
// Are the client and server willing to negotiate FFDHE groups?
if
((!
useLegacyEphemeralDHKeys
)
&&
(!
export
)
&&
(
namedGroup
!=
null
))
{
dh
=
new
DHCrypt
(
namedGroup
,
sslContext
.
getSecureRandom
());
return
;
}
// Otherwise, the client is not compatible with FFDHE extension.
private
void
setupEphemeralDHKeys
(
boolean
export
,
Key
key
)
{
/*
* 768 bits ephemeral DH private keys were used to be used in
* ServerKeyExchange except that exportable ciphers max out at 512
...
...
@@ -1512,11 +1416,20 @@ final class ServerHandshaker extends Handshaker {
dh
=
new
DHCrypt
(
keySize
,
sslContext
.
getSecureRandom
());
}
/**
* Setup the ephemeral ECDH parameters.
*/
private
void
setupEphemeralECDHKeys
(
NamedGroup
namedGroup
)
{
ecdh
=
new
ECDHCrypt
(
namedGroup
,
sslContext
.
getSecureRandom
());
// Setup the ephemeral ECDH parameters.
// If we cannot continue because we do not support any of the curves that
// the client requested, return false. Otherwise (all is well), return true.
private
boolean
setupEphemeralECDHKeys
()
{
int
index
=
(
requestedCurves
!=
null
)
?
requestedCurves
.
getPreferredCurve
(
algorithmConstraints
)
:
EllipticCurvesExtension
.
getActiveCurves
(
algorithmConstraints
);
if
(
index
<
0
)
{
// no match found, cannot use this ciphersuite
return
false
;
}
ecdh
=
new
ECDHCrypt
(
index
,
sslContext
.
getSecureRandom
());
return
true
;
}
private
void
setupStaticECDHKeys
()
{
...
...
@@ -1564,11 +1477,9 @@ final class ServerHandshaker extends Handshaker {
return
false
;
}
ECParameterSpec
params
=
((
ECPublicKey
)
publicKey
).
getParams
();
NamedGroup
namedGroup
=
NamedGroup
.
valueOf
(
params
);
if
((
namedGroup
==
null
)
||
(!
SupportedGroupsExtension
.
supports
(
namedGroup
))
||
((
requestedGroups
!=
null
)
&&
!
requestedGroups
.
contains
(
namedGroup
.
id
)))
{
int
id
=
EllipticCurvesExtension
.
getCurveIndex
(
params
);
if
((
id
<=
0
)
||
!
EllipticCurvesExtension
.
isSupported
(
id
)
||
((
requestedCurves
!=
null
)
&&
!
requestedCurves
.
contains
(
id
)))
{
return
false
;
}
}
...
...
test/javax/net/ssl/templates/SSLSocketTemplate.java
已删除
100644 → 0
浏览文件 @
25f17276
/*
* Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
//
// Please run in othervm mode. SunJSSE does not support dynamic system
// properties, no way to re-use system properties in samevm/agentvm mode.
//
/*
* @test
* @bug 8161106 8170329
* @modules jdk.crypto.ec
* @summary Improve SSLSocket test template
* @run main/othervm SSLSocketTemplate
*/
import
java.io.ByteArrayInputStream
;
import
java.io.InputStream
;
import
java.io.IOException
;
import
java.io.OutputStream
;
import
javax.net.ssl.KeyManagerFactory
;
import
javax.net.ssl.SSLContext
;
import
javax.net.ssl.SSLServerSocket
;
import
javax.net.ssl.SSLServerSocketFactory
;
import
javax.net.ssl.SSLSocket
;
import
javax.net.ssl.SSLSocketFactory
;
import
javax.net.ssl.TrustManagerFactory
;
import
java.net.InetSocketAddress
;
import
java.net.SocketTimeoutException
;
import
java.security.KeyStore
;
import
java.security.PrivateKey
;
import
java.security.KeyFactory
;
import
java.security.cert.Certificate
;
import
java.security.cert.CertificateFactory
;
import
java.security.spec.PKCS8EncodedKeySpec
;
import
java.util.Base64
;
import
java.util.concurrent.CountDownLatch
;
import
java.util.concurrent.TimeUnit
;
/**
* Template to help speed your client/server tests.
*
* Two examples that use this template:
* test/sun/security/ssl/ServerHandshaker/AnonCipherWithWantClientAuth.java
* test/sun/net/www/protocol/https/HttpsClient/ServerIdentityTest.java
*/
public
class
SSLSocketTemplate
{
/*
* ==================
* Run the test case.
*/
public
static
void
main
(
String
[]
args
)
throws
Exception
{
(
new
SSLSocketTemplate
()).
run
();
}
/*
* Run the test case.
*/
public
void
run
()
throws
Exception
{
bootup
();
}
/*
* Define the server side application of the test for the specified socket.
*/
protected
void
runServerApplication
(
SSLSocket
socket
)
throws
Exception
{
// here comes the test logic
InputStream
sslIS
=
socket
.
getInputStream
();
OutputStream
sslOS
=
socket
.
getOutputStream
();
sslIS
.
read
();
sslOS
.
write
(
85
);
sslOS
.
flush
();
}
/*
* Define the client side application of the test for the specified socket.
* This method is used if the returned value of
* isCustomizedClientConnection() is false.
*
* @param socket may be null is no client socket is generated.
*
* @see #isCustomizedClientConnection()
*/
protected
void
runClientApplication
(
SSLSocket
socket
)
throws
Exception
{
InputStream
sslIS
=
socket
.
getInputStream
();
OutputStream
sslOS
=
socket
.
getOutputStream
();
sslOS
.
write
(
280
);
sslOS
.
flush
();
sslIS
.
read
();
}
/*
* Define the client side application of the test for the specified
* server port. This method is used if the returned value of
* isCustomizedClientConnection() is true.
*
* Note that the client need to connect to the server port by itself
* for the actual message exchange.
*
* @see #isCustomizedClientConnection()
*/
protected
void
runClientApplication
(
int
serverPort
)
throws
Exception
{
// blank
}
/*
* Create an instance of SSLContext for client use.
*/
protected
SSLContext
createClientSSLContext
()
throws
Exception
{
return
createSSLContext
(
trustedCertStrs
,
endEntityCertStrs
,
endEntityPrivateKeys
,
endEntityPrivateKeyNames
,
getClientContextParameters
());
}
/*
* Create an instance of SSLContext for server use.
*/
protected
SSLContext
createServerSSLContext
()
throws
Exception
{
return
createSSLContext
(
trustedCertStrs
,
endEntityCertStrs
,
endEntityPrivateKeys
,
endEntityPrivateKeyNames
,
getServerContextParameters
());
}
/*
* The parameters used to configure SSLContext.
*/
protected
static
final
class
ContextParameters
{
final
String
contextProtocol
;
final
String
tmAlgorithm
;
final
String
kmAlgorithm
;
ContextParameters
(
String
contextProtocol
,
String
tmAlgorithm
,
String
kmAlgorithm
)
{
this
.
contextProtocol
=
contextProtocol
;
this
.
tmAlgorithm
=
tmAlgorithm
;
this
.
kmAlgorithm
=
kmAlgorithm
;
}
}
/*
* Get the client side parameters of SSLContext.
*/
protected
ContextParameters
getClientContextParameters
()
{
return
new
ContextParameters
(
"TLS"
,
"PKIX"
,
"NewSunX509"
);
}
/*
* Get the server side parameters of SSLContext.
*/
protected
ContextParameters
getServerContextParameters
()
{
return
new
ContextParameters
(
"TLS"
,
"PKIX"
,
"NewSunX509"
);
}
/*
* Does the client side use customized connection other than
* explicit Socket.connect(), for example, URL.openConnection()?
*/
protected
boolean
isCustomizedClientConnection
()
{
return
false
;
}
/*
* Configure the server side socket.
*/
protected
void
configureServerSocket
(
SSLServerSocket
socket
)
{
}
/*
* =============================================
* Define the client and server side operations.
*
* If the client or server is doing some kind of object creation
* that the other side depends on, and that thread prematurely
* exits, you may experience a hang. The test harness will
* terminate all hung threads after its timeout has expired,
* currently 3 minutes by default, but you might try to be
* smart about it....
*/
/*
* Is the server ready to serve?
*/
private
final
CountDownLatch
serverCondition
=
new
CountDownLatch
(
1
);
/*
* Is the client ready to handshake?
*/
private
final
CountDownLatch
clientCondition
=
new
CountDownLatch
(
1
);
/*
* What's the server port? Use any free port by default
*/
private
volatile
int
serverPort
=
0
;
/*
* Define the server side of the test.
*/
private
void
doServerSide
()
throws
Exception
{
// kick start the server side service
SSLContext
context
=
createServerSSLContext
();
SSLServerSocketFactory
sslssf
=
context
.
getServerSocketFactory
();
SSLServerSocket
sslServerSocket
=
(
SSLServerSocket
)
sslssf
.
createServerSocket
(
serverPort
);
configureServerSocket
(
sslServerSocket
);
serverPort
=
sslServerSocket
.
getLocalPort
();
// Signal the client, the server is ready to accept connection.
serverCondition
.
countDown
();
// Try to accept a connection in 30 seconds.
SSLSocket
sslSocket
;
try
{
sslServerSocket
.
setSoTimeout
(
30000
);
sslSocket
=
(
SSLSocket
)
sslServerSocket
.
accept
();
}
catch
(
SocketTimeoutException
ste
)
{
// Ignore the test case if no connection within 30 seconds.
System
.
out
.
println
(
"No incoming client connection in 30 seconds. "
+
"Ignore in server side."
);
return
;
}
finally
{
sslServerSocket
.
close
();
}
// handle the connection
try
{
// Is it the expected client connection?
//
// Naughty test cases or third party routines may try to
// connection to this server port unintentionally. In
// order to mitigate the impact of unexpected client
// connections and avoid intermittent failure, it should
// be checked that the accepted connection is really linked
// to the expected client.
boolean
clientIsReady
=
clientCondition
.
await
(
30L
,
TimeUnit
.
SECONDS
);
if
(
clientIsReady
)
{
// Run the application in server side.
runServerApplication
(
sslSocket
);
}
else
{
// Otherwise, ignore
// We don't actually care about plain socket connections
// for TLS communication testing generally. Just ignore
// the test if the accepted connection is not linked to
// the expected client or the client connection timeout
// in 30 seconds.
System
.
out
.
println
(
"The client is not the expected one or timeout. "
+
"Ignore in server side."
);
}
}
finally
{
sslSocket
.
close
();
}
}
/*
* Define the client side of the test.
*/
private
void
doClientSide
()
throws
Exception
{
// Wait for server to get started.
//
// The server side takes care of the issue if the server cannot
// get started in 90 seconds. The client side would just ignore
// the test case if the serer is not ready.
boolean
serverIsReady
=
serverCondition
.
await
(
90L
,
TimeUnit
.
SECONDS
);
if
(!
serverIsReady
)
{
System
.
out
.
println
(
"The server is not ready yet in 90 seconds. "
+
"Ignore in client side."
);
return
;
}
if
(
isCustomizedClientConnection
())
{
// Signal the server, the client is ready to communicate.
clientCondition
.
countDown
();
// Run the application in client side.
runClientApplication
(
serverPort
);
return
;
}
SSLContext
context
=
createClientSSLContext
();
SSLSocketFactory
sslsf
=
context
.
getSocketFactory
();
try
(
SSLSocket
sslSocket
=
(
SSLSocket
)
sslsf
.
createSocket
())
{
try
{
sslSocket
.
connect
(
new
InetSocketAddress
(
"localhost"
,
serverPort
),
15000
);
}
catch
(
IOException
ioe
)
{
// The server side may be impacted by naughty test cases or
// third party routines, and cannot accept connections.
//
// Just ignore the test if the connection cannot be
// established.
System
.
out
.
println
(
"Cannot make a connection in 15 seconds. "
+
"Ignore in client side."
);
return
;
}
// OK, here the client and server get connected.
// Signal the server, the client is ready to communicate.
clientCondition
.
countDown
();
// There is still a chance in theory that the server thread may
// wait client-ready timeout and then quit. The chance should
// be really rare so we don't consider it until it becomes a
// real problem.
// Run the application in client side.
runClientApplication
(
sslSocket
);
}
}
/*
* =============================================
* Stuffs to customize the SSLContext instances.
*/
/*
* =======================================
* Certificates and keys used in the test.
*/
// Trusted certificates.
private
final
static
String
[]
trustedCertStrs
=
{
// SHA256withECDSA, curve prime256v1
// Validity
// Not Before: Nov 25 04:19:51 2016 GMT
// Not After : Nov 5 04:19:51 2037 GMT
// Subject Key Identifier:
// CA:48:E8:00:C1:42:BD:59:9B:79:D9:B4:B4:CE:3F:68:0C:C8:C4:0C
"-----BEGIN CERTIFICATE-----\n"
+
"MIICHDCCAcGgAwIBAgIJAJtKs6ZEcVjxMAoGCCqGSM49BAMCMDsxCzAJBgNVBAYT\n"
+
"AlVTMQ0wCwYDVQQKEwRKYXZhMR0wGwYDVQQLExRTdW5KU1NFIFRlc3QgU2VyaXZj\n"
+
"ZTAeFw0xNjExMjUwNDE5NTFaFw0zNzExMDUwNDE5NTFaMDsxCzAJBgNVBAYTAlVT\n"
+
"MQ0wCwYDVQQKEwRKYXZhMR0wGwYDVQQLExRTdW5KU1NFIFRlc3QgU2VyaXZjZTBZ\n"
+
"MBMGByqGSM49AgEGCCqGSM49AwEHA0IABKMO/AFDHZia65RaqMIBX7WBdtzFj8fz\n"
+
"ggqMADLJhoszS6qfTUDYskETw3uHfB3KAOENsoKX446qFFPuVjxS1aejga0wgaow\n"
+
"HQYDVR0OBBYEFMpI6ADBQr1Zm3nZtLTOP2gMyMQMMGsGA1UdIwRkMGKAFMpI6ADB\n"
+
"Qr1Zm3nZtLTOP2gMyMQMoT+kPTA7MQswCQYDVQQGEwJVUzENMAsGA1UEChMESmF2\n"
+
"YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2WCCQCbSrOmRHFY8TAPBgNV\n"
+
"HRMBAf8EBTADAQH/MAsGA1UdDwQEAwIBBjAKBggqhkjOPQQDAgNJADBGAiEA5cJ/\n"
+
"jirBbXxzpZ6kdp/Zb/yrIBnr4jiPGJTLgRTb8s4CIQChUDfP1Zqg0qJVfqFNaL4V\n"
+
"a0EAeJHXGZnvCGGqHzoxkg==\n"
+
"-----END CERTIFICATE-----"
,
// SHA256withRSA, 2048 bits
// Validity
// Not Before: Nov 25 04:20:02 2016 GMT
// Not After : Nov 5 04:20:02 2037 GMT
// Subject Key Identifier:
// A2:DC:55:38:E4:47:7C:8B:D3:E0:CA:FA:AD:3A:C8:4A:DD:12:A0:8E
"-----BEGIN CERTIFICATE-----\n"
+
"MIIDpzCCAo+gAwIBAgIJAO586A+hYNXaMA0GCSqGSIb3DQEBCwUAMDsxCzAJBgNV\n"
+
"BAYTAlVTMQ0wCwYDVQQKEwRKYXZhMR0wGwYDVQQLExRTdW5KU1NFIFRlc3QgU2Vy\n"
+
"aXZjZTAeFw0xNjExMjUwNDIwMDJaFw0zNzExMDUwNDIwMDJaMDsxCzAJBgNVBAYT\n"
+
"AlVTMQ0wCwYDVQQKEwRKYXZhMR0wGwYDVQQLExRTdW5KU1NFIFRlc3QgU2VyaXZj\n"
+
"ZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMm3veDSU4zKXO0aAHos\n"
+
"cFRXGLBTe+MUJXAtlkNyx7VKaMZNt5wrUuqzyi/r0LFUdRfNCzZf3X8s8HPHQVii\n"
+
"29tK0y/yeTn4sJTATSmGaAysMJQpKQcfAQ79ItcEGQ721TFQZ3kOBdgp3t/yUYAP\n"
+
"K2tFze/QbIw72LE52SBnPPPTzyimNw7Ai2MLl4eQlyMkTs7JS07zIiAO5QYbS8s+\n"
+
"1NW0A3Y+d0B0q8wYEoHGq7QVjOKlSAksfO0tzi4l0Zu6Uf+J5kMAyZ4ZFgEJvGvw\n"
+
"y/OKJ+soRFH/5cy1SL8B6AWD1y7WXugeeHTHRW1eOjTxqfG1rZqTVd2lfOMER8y1\n"
+
"bXcCAwEAAaOBrTCBqjAdBgNVHQ4EFgQUotxVOORHfIvT4Mr6rTrISt0SoI4wawYD\n"
+
"VR0jBGQwYoAUotxVOORHfIvT4Mr6rTrISt0SoI6hP6Q9MDsxCzAJBgNVBAYTAlVT\n"
+
"MQ0wCwYDVQQKEwRKYXZhMR0wGwYDVQQLExRTdW5KU1NFIFRlc3QgU2VyaXZjZYIJ\n"
+
"AO586A+hYNXaMA8GA1UdEwEB/wQFMAMBAf8wCwYDVR0PBAQDAgEGMA0GCSqGSIb3\n"
+
"DQEBCwUAA4IBAQAtNZJSFeFU6Yid0WSCs2qLAVaTyHsUNSUPUFIIhFAKxdP4DFS0\n"
+
"+aeOFwdqizAU3kReAYULsfwEBgO51lPBSpB+9coUNQwu7cc8Q5Xqw/llRB0PrINS\n"
+
"pZl7PW6Ur2ExTBocnUT9A/nhm8iO4PFD/Ly11sf5OdZihhX69NJ2h3a3gcrLjIpO\n"
+
"L/ewTOgSi5xs+AGGQa+huN3YVL7dh+/rCUvMZVSBX5PloxWS5MMJi0Ui6YjwCFGO\n"
+
"J4G9m7pI+gJs/x1UG0AgplMF2UCFfiY1SAeE2nKAeOOXAXEwEjFy0ToVTmqXx7fg\n"
+
"m9YjhuePxlBrd2DF/YW0pc8gmLnrtm4rKPLz\n"
+
"-----END CERTIFICATE-----"
,
// SHA256withDSA, 2048 bits
// Validity
// Not Before: Nov 25 04:19:56 2016 GMT
// Not After : Nov 5 04:19:56 2037 GMT
// Subject Key Identifier:
// 19:46:10:43:24:6A:A5:14:BE:E2:92:01:79:F0:4C:5F:E1:AE:81:B5
"-----BEGIN CERTIFICATE-----\n"
+
"MIIFCzCCBLGgAwIBAgIJAOnEn6YZD/sAMAsGCWCGSAFlAwQDAjA7MQswCQYDVQQG\n"
+
"EwJVUzENMAsGA1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2\n"
+
"Y2UwHhcNMTYxMTI1MDQxOTU2WhcNMzcxMTA1MDQxOTU2WjA7MQswCQYDVQQGEwJV\n"
+
"UzENMAsGA1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2Uw\n"
+
"ggNGMIICOQYHKoZIzjgEATCCAiwCggEBAJa17ZYdIChv5yeYuPK3zXxgUEGGsdUD\n"
+
"AzfQUxtMryCtc3aNgWLxsN1/QYvp9v+hh4twnG20VemCEH9Qlx06Pxg74DwSOA83\n"
+
"SecO2y7cdgmrHpep9drxKbXVZafwBhbTSwhV+IDO7EO6+LaRvZuya/YOqNIE9ENx\n"
+
"FVk0NrNsDB6pfDEXZsCZALMN2mcl8KGn1q7vdzJQUEV7F6uLGP33znVfmQyWJH3Y\n"
+
"W09WVCFXHvDzZHGXDO2O2QwIU1B5AsXnOGeLnKgXzErCoNKwUbVFP0W0OVeJo4pc\n"
+
"ZfL/8TVELGG90AuuH1V3Gsq6PdzCDPw4Uv/v5m7/6kwXqBQxAJA7jhMCIQCORIGV\n"
+
"mHy5nBLRhIP4vC7vsTxb4CTApPVmZeL5gTIwtQKCAQB2VZLY22k2+IQM6deRGK3L\n"
+
"l7tPChGrKnGmTbtUThIza70Sp9DmTBiLzMEY+IgG8kYuT5STVxWjs0cxXCKZGMQW\n"
+
"tioMtiXPA2M3HA0/8E0mDLSmzb0RAd2xxnDyGsuqo1eVmx7PLjN3bn3EjhD/+j3d\n"
+
"Jx3ZVScMGyq7sVWppUvpudEXi+2etf6GUHjrcX27juo7u4zQ1ezC/HYG1H+jEFqG\n"
+
"hdQ6b7H+LBHZH9LegOyIZTMrzAY/TwIr77sXrNJWRoxmDErKB+8bRDybYhNJswlZ\n"
+
"m0N5YYUlPmepgbl6XzwCv0y0d81h3bayqIPLXEUtRAl9GuM0hNAlA1Y+qSn9xLFY\n"
+
"A4IBBQACggEAZgWC0uflwqQQP1GRU1tolmFZwyVtKre7SjYgCeQBrOa0Xnj/SLaD\n"
+
"g1HZ1oH0hccaR/45YouJiCretbbsQ77KouldGSGqTHJgRL75Y2z5uvxa60+YxZ0Z\n"
+
"v8xvZnj4seyOjgJLxSSYSPl5n/F70RaNiCLVz/kGe6OQ8KoAeQjdDTOHXCegO9KX\n"
+
"tvhM7EaYc8CII9OIR7S7PXJW0hgLKynZcu/Unh02aM0ABh/uLmw1+tvo8e8KTp98\n"
+
"NKYSVf6kV3/ya58n4h64UbIYL08JoKUM/5SFETcKAZTU0YKZbpWTM79oJMr8oYVk\n"
+
"P9jKitNsXq0Xkzt5dSO0kfu/kM7zpnaFsqOBrTCBqjAdBgNVHQ4EFgQUGUYQQyRq\n"
+
"pRS+4pIBefBMX+GugbUwawYDVR0jBGQwYoAUGUYQQyRqpRS+4pIBefBMX+GugbWh\n"
+
"P6Q9MDsxCzAJBgNVBAYTAlVTMQ0wCwYDVQQKEwRKYXZhMR0wGwYDVQQLExRTdW5K\n"
+
"U1NFIFRlc3QgU2VyaXZjZYIJAOnEn6YZD/sAMA8GA1UdEwEB/wQFMAMBAf8wCwYD\n"
+
"VR0PBAQDAgEGMAsGCWCGSAFlAwQDAgNHADBEAiAwBafz5RRR9nc4cCYoYuBlT/D9\n"
+
"9eayhkjhBY/zYunypwIgNp/JnFR88/T4hh36QfSKBGXId9RBCM6uaOkOKnEGkps=\n"
+
"-----END CERTIFICATE-----"
};
// End entity certificate.
private
final
static
String
[]
endEntityCertStrs
=
{
// SHA256withECDSA, curve prime256v1
// Validity
// Not Before: Nov 25 04:19:51 2016 GMT
// Not After : Aug 12 04:19:51 2036 GMT
// Authority Key Identifier:
// CA:48:E8:00:C1:42:BD:59:9B:79:D9:B4:B4:CE:3F:68:0C:C8:C4:0C
"-----BEGIN CERTIFICATE-----\n"
+
"MIIB1zCCAXygAwIBAgIJAPFq2QL/nUNZMAoGCCqGSM49BAMCMDsxCzAJBgNVBAYT\n"
+
"AlVTMQ0wCwYDVQQKEwRKYXZhMR0wGwYDVQQLExRTdW5KU1NFIFRlc3QgU2VyaXZj\n"
+
"ZTAeFw0xNjExMjUwNDE5NTFaFw0zNjA4MTIwNDE5NTFaMFUxCzAJBgNVBAYTAlVT\n"
+
"MQ0wCwYDVQQKDARKYXZhMR0wGwYDVQQLDBRTdW5KU1NFIFRlc3QgU2VyaXZjZTEY\n"
+
"MBYGA1UEAwwPUmVncmVzc2lvbiBUZXN0MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcD\n"
+
"QgAE4yvRGVvy9iVATyuHPJVdX6+lh/GLm/sRJ5qLT/3PVFOoNIvlEVNiARo7xhyj\n"
+
"2p6bnf32gNg5Ye+QCw20VUv9E6NPME0wCwYDVR0PBAQDAgPoMB0GA1UdDgQWBBSO\n"
+
"hHlHZQp9hyBfSGTSQWeszqMXejAfBgNVHSMEGDAWgBTKSOgAwUK9WZt52bS0zj9o\n"
+
"DMjEDDAKBggqhkjOPQQDAgNJADBGAiEAu3t6cvFglBAZfkhZlEwB04ZjUFqyfiRj\n"
+
"4Hr275E4ZoQCIQDUEonJHlmA19J6oobfR5lYsmoqPm1r0DPm/IiNNKGKKA==\n"
+
"-----END CERTIFICATE-----"
,
// SHA256withRSA, 2048 bits
// Validity
// Not Before: Nov 25 04:20:02 2016 GMT
// Not After : Aug 12 04:20:02 2036 GMT
// Authority Key Identifier:
// A2:DC:55:38:E4:47:7C:8B:D3:E0:CA:FA:AD:3A:C8:4A:DD:12:A0:8E
"-----BEGIN CERTIFICATE-----\n"
+
"MIIDdjCCAl6gAwIBAgIJAJDcIGOlAmBmMA0GCSqGSIb3DQEBCwUAMDsxCzAJBgNV\n"
+
"BAYTAlVTMQ0wCwYDVQQKEwRKYXZhMR0wGwYDVQQLExRTdW5KU1NFIFRlc3QgU2Vy\n"
+
"aXZjZTAeFw0xNjExMjUwNDIwMDJaFw0zNjA4MTIwNDIwMDJaMFUxCzAJBgNVBAYT\n"
+
"AlVTMQ0wCwYDVQQKDARKYXZhMR0wGwYDVQQLDBRTdW5KU1NFIFRlc3QgU2VyaXZj\n"
+
"ZTEYMBYGA1UEAwwPUmVncmVzc2lvbiBUZXN0MIIBIjANBgkqhkiG9w0BAQEFAAOC\n"
+
"AQ8AMIIBCgKCAQEAp0dHrifTg2aY0sH03f2JjK2fW4DL6gLDKq0YirsNE07z54LF\n"
+
"IeeDio49XwPjB7OpbUTC1hf/YKZ7XiRWyPa1rYozZ88emhZt+cpkyKz+nmW4avlA\n"
+
"WnrV+gx4+bU9T+WuBWdAraBcq27Y1I26yfCEtC8k3+O0sdlHbhasF+BUDmX/n4+n\n"
+
"ifJdbNm5eSDx8eFYHFTdjhAud3An2X6QD9WWSoJpPdDi4utHhFAlxW6osjJxsAPv\n"
+
"zo8YsqmpCMjZcEks4ZsqiZKKiWUWUAjCcbMerDPDX29fyeo348uztvJsmNRzfcwl\n"
+
"FtwxpYdxuZqwHi2QoNaQTGXjjbZFmjn7qEkjXwIDAQABo2MwYTALBgNVHQ8EBAMC\n"
+
"A+gwHQYDVR0OBBYEFP+henfufE6Znr60lRkmayadVdxnMB8GA1UdIwQYMBaAFKLc\n"
+
"VTjkR3yL0+DK+q06yErdEqCOMBIGA1UdEQEB/wQIMAaHBH8AAAEwDQYJKoZIhvcN\n"
+
"AQELBQADggEBAK56pV2XoAIkrHFTCkWtYX518nuvkzN6a6BqPKALQlmlbJnq/lhV\n"
+
"tPQx79b0j7tow28l2ze/3M0hRb5Ft/d/7mITZNMR+0owk4U51AU2NacRt7fpoxu5\n"
+
"wX3hTa4VgX2+BAXeoWF+Yzy6Jj5gAVmSLzBnkTUH0d+EyL1pp+DFE3QdvZqf3+nP\n"
+
"zkxz15h3iW8FwI+7/19MX2j2XB/sG8mJpqoszWw8lM4qCa2eWyCbqSHhPi+/+rGg\n"
+
"dDG5uzZeOC845GEH2T3tHDA+F3WwcZG/W+4RR6ZaaHlqPKKMcwFL73YbsqdCiKBv\n"
+
"p6sXrhIiP0oXImRBRLDlidj5TIOLfAtNM9A=\n"
+
"-----END CERTIFICATE-----"
,
// SHA256withDSA, 2048 bits
// Validity
// Not Before: Nov 25 04:19:56 2016 GMT
// Not After : Aug 12 04:19:56 2036 GMT
// Authority Key Identifier:
// 19:46:10:43:24:6A:A5:14:BE:E2:92:01:79:F0:4C:5F:E1:AE:81:B5
"-----BEGIN CERTIFICATE-----\n"
+
"MIIE2jCCBICgAwIBAgIJAONcI1oba9V9MAsGCWCGSAFlAwQDAjA7MQswCQYDVQQG\n"
+
"EwJVUzENMAsGA1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2\n"
+
"Y2UwHhcNMTYxMTI1MDQxOTU2WhcNMzYwODEyMDQxOTU2WjBVMQswCQYDVQQGEwJV\n"
+
"UzENMAsGA1UECgwESmF2YTEdMBsGA1UECwwUU3VuSlNTRSBUZXN0IFNlcml2Y2Ux\n"
+
"GDAWBgNVBAMMD1JlZ3Jlc3Npb24gVGVzdDCCA0YwggI5BgcqhkjOOAQBMIICLAKC\n"
+
"AQEAlrXtlh0gKG/nJ5i48rfNfGBQQYax1QMDN9BTG0yvIK1zdo2BYvGw3X9Bi+n2\n"
+
"/6GHi3CcbbRV6YIQf1CXHTo/GDvgPBI4DzdJ5w7bLtx2Casel6n12vEptdVlp/AG\n"
+
"FtNLCFX4gM7sQ7r4tpG9m7Jr9g6o0gT0Q3EVWTQ2s2wMHql8MRdmwJkAsw3aZyXw\n"
+
"oafWru93MlBQRXsXq4sY/ffOdV+ZDJYkfdhbT1ZUIVce8PNkcZcM7Y7ZDAhTUHkC\n"
+
"xec4Z4ucqBfMSsKg0rBRtUU/RbQ5V4mjilxl8v/xNUQsYb3QC64fVXcayro93MIM\n"
+
"/DhS/+/mbv/qTBeoFDEAkDuOEwIhAI5EgZWYfLmcEtGEg/i8Lu+xPFvgJMCk9WZl\n"
+
"4vmBMjC1AoIBAHZVktjbaTb4hAzp15EYrcuXu08KEasqcaZNu1ROEjNrvRKn0OZM\n"
+
"GIvMwRj4iAbyRi5PlJNXFaOzRzFcIpkYxBa2Kgy2Jc8DYzccDT/wTSYMtKbNvREB\n"
+
"3bHGcPIay6qjV5WbHs8uM3dufcSOEP/6Pd0nHdlVJwwbKruxVamlS+m50ReL7Z61\n"
+
"/oZQeOtxfbuO6ju7jNDV7ML8dgbUf6MQWoaF1Dpvsf4sEdkf0t6A7IhlMyvMBj9P\n"
+
"Aivvuxes0lZGjGYMSsoH7xtEPJtiE0mzCVmbQ3lhhSU+Z6mBuXpfPAK/TLR3zWHd\n"
+
"trKog8tcRS1ECX0a4zSE0CUDVj6pKf3EsVgDggEFAAKCAQBEGmdP55PyE3M+Q3fU\n"
+
"dCGq0sbKw/04xPVhaNYRnRKNR82n+wb8bMCI1vvFqXy1BB6svti4mTHbQZ8+bQXm\n"
+
"gyce67uYMwIa5BIk6omNGCeW/kd4ruPgyFxeb6O/Y/7w6AWyRmQttlxRA5M5OhSC\n"
+
"tVS4oVC1KK1EfHAUh7mu8S8GrWJoJAWA3PM97Oy/HSGCEUl6HGEu1m7FHPhOKeYG\n"
+
"cLkSaov5cbCYO76smHchI+tdUciVqeL3YKQdS+KAzsQoeAZIu/WpbaI1V+5/rSG1\n"
+
"I94uBITLCjlJfJZ1aredCDrRXOFH7qgSBhM8/WzwFpFCnnpbSKMgrcrKubsFmW9E\n"
+
"jQhXo2MwYTALBgNVHQ8EBAMCA+gwHQYDVR0OBBYEFNA9PhQOjB+05fxxXPNqe0OT\n"
+
"doCjMB8GA1UdIwQYMBaAFBlGEEMkaqUUvuKSAXnwTF/hroG1MBIGA1UdEQEB/wQI\n"
+
"MAaHBH8AAAEwCwYJYIZIAWUDBAMCA0cAMEQCIE0LM2sZi+L8tjH9sgjLEwJmYZvO\n"
+
"yqNfQnXrkTCb+MLMAiBZLaRTVJrOW3edQjum+SonKKuiN22bRclO6pGuNRCtng==\n"
+
"-----END CERTIFICATE-----"
};
// Private key in the format of PKCS#8.
private
final
static
String
[]
endEntityPrivateKeys
=
{
//
// EC private key related to cert endEntityCertStrs[0].
//
"MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgGAy4Pxrd2keM7AdP\n"
+
"VNUMEO5iO681v4/tstVGfdXkCTuhRANCAATjK9EZW/L2JUBPK4c8lV1fr6WH8Yub\n"
+
"+xEnmotP/c9UU6g0i+URU2IBGjvGHKPanpud/faA2Dlh75ALDbRVS/0T"
,
//
// RSA private key related to cert endEntityCertStrs[1].
//
"MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCnR0euJ9ODZpjS\n"
+
"wfTd/YmMrZ9bgMvqAsMqrRiKuw0TTvPngsUh54OKjj1fA+MHs6ltRMLWF/9gpnte\n"
+
"JFbI9rWtijNnzx6aFm35ymTIrP6eZbhq+UBaetX6DHj5tT1P5a4FZ0CtoFyrbtjU\n"
+
"jbrJ8IS0LyTf47Sx2UduFqwX4FQOZf+fj6eJ8l1s2bl5IPHx4VgcVN2OEC53cCfZ\n"
+
"fpAP1ZZKgmk90OLi60eEUCXFbqiyMnGwA+/OjxiyqakIyNlwSSzhmyqJkoqJZRZQ\n"
+
"CMJxsx6sM8Nfb1/J6jfjy7O28myY1HN9zCUW3DGlh3G5mrAeLZCg1pBMZeONtkWa\n"
+
"OfuoSSNfAgMBAAECggEAWnAHKPkPObN2XDvQj1RL0WrtBSOVG2dy7Ne4tQh8ATxm\n"
+
"UXw56CKq03YjaANJ8xgHObQ7QlSnFTHs8PDkmrIHd1OIh09LVDNcMfhilLwyzKBi\n"
+
"HDO1vzU6Cn5DyX1bMJ8UfodcSIKyl1zOjdwyaItIs8HpRcJuJtk57SME18PIrh9H\n"
+
"EWchWSxTvPvKDY2bhb4vBMgVPfTQO3yc8gY/1J5vKPqDpyEuCGjV13zd/AoL/u5A\n"
+
"sG10hQ2veJ9KAn1xwPwEoAkCdNLL8vPB1rCbeMZNamqHZRihfoOgDnnJIf3FtUFF\n"
+
"8bS2FM2kGQR+05SZdhBmJl0obPrbBWil/2vxqeFrgQKBgQDZl1yQsFss2BKK2VAh\n"
+
"9PKc8tU1v6RpHQZhJEDSct2slHQS5DF6bWl5kJiPevXSvcnjgoPamZf7Joii+Rds\n"
+
"3xtPQmRw2vQmXBQzQS1YoRuh4hUlkdFWCjUNNg1kvipue6FO4PVg3ViP7llN8PXK\n"
+
"rSpVxn0a36UiN9jN2zMOUs6tJwKBgQDEzlqa7DghMli7TUdL44uvD2/ceiHqHMMw\n"
+
"5eLsEHeRVn/EVU99beKw/dAOGwRssTpCd9h7fwzQ2503/Qb/Goe0nKE7+xvt3/sE\n"
+
"n2Y8Qfv1W1+hGb2qU2jhQaR5bZrLZp0+BgRuQ4ttpYvzopYe4FLZWhDBA0zsGyu0\n"
+
"nCi7lUSrCQKBgGeGYW8hyS9r2l6fiEWvsiLEUnbRKFsuiRN82S6HojpzI0q9sWDL\n"
+
"X6yMBFn3qa/LxpttRGikPTAsJERN+Tw+ZlLuhrU/J3x8wMumDfomJOx/kYofd5bV\n"
+
"ImqXtgWhiLSqM5RA6d5dUb6hK3Iu2/LDMuo+ltVLZNkD8y32RbNh6J1vAoGAbLqQ\n"
+
"pgyhSf3Vtc0Q+aVB87p0k3tKJ1wynl4zSzYhyMLgHakAHIzL8/qVqmVUwXP8euJZ\n"
+
"UIk1nGHobxk0d1XB6Y+rKEcn+/iFZt1ljx7pQ3ly0L824NXqGKC6bHeYUI1li/Gp\n"
+
"Gv3oFvCh7D1D8NUAEKLIpMndAohUUhkAC/qAkHkCgYEAzSIarDNquayV+umC1SXm\n"
+
"Zo6XLuzWjudLxPd2lyCfwR2aRKlrb+5OFYErX+RSLyCJmaqVZMyXP09PBIvNXu2Z\n"
+
"+gbx5WUC+kA+6zdKEPXowei6i6EHMXYT2AL7395ZbPajZjsCduE3WuUztuHrhtMm\n"
+
"JI+k1o4rCnSLlX4gWdN1oTs="
,
//
// DSA private key related to cert endEntityCertStrs[2].
//
"MIICZAIBADCCAjkGByqGSM44BAEwggIsAoIBAQCWte2WHSAob+cnmLjyt818YFBB\n"
+
"hrHVAwM30FMbTK8grXN2jYFi8bDdf0GL6fb/oYeLcJxttFXpghB/UJcdOj8YO+A8\n"
+
"EjgPN0nnDtsu3HYJqx6XqfXa8Sm11WWn8AYW00sIVfiAzuxDuvi2kb2bsmv2DqjS\n"
+
"BPRDcRVZNDazbAweqXwxF2bAmQCzDdpnJfChp9au73cyUFBFexerixj99851X5kM\n"
+
"liR92FtPVlQhVx7w82RxlwztjtkMCFNQeQLF5zhni5yoF8xKwqDSsFG1RT9FtDlX\n"
+
"iaOKXGXy//E1RCxhvdALrh9VdxrKuj3cwgz8OFL/7+Zu/+pMF6gUMQCQO44TAiEA\n"
+
"jkSBlZh8uZwS0YSD+Lwu77E8W+AkwKT1ZmXi+YEyMLUCggEAdlWS2NtpNviEDOnX\n"
+
"kRity5e7TwoRqypxpk27VE4SM2u9EqfQ5kwYi8zBGPiIBvJGLk+Uk1cVo7NHMVwi\n"
+
"mRjEFrYqDLYlzwNjNxwNP/BNJgy0ps29EQHdscZw8hrLqqNXlZsezy4zd259xI4Q\n"
+
"//o93Scd2VUnDBsqu7FVqaVL6bnRF4vtnrX+hlB463F9u47qO7uM0NXswvx2BtR/\n"
+
"oxBahoXUOm+x/iwR2R/S3oDsiGUzK8wGP08CK++7F6zSVkaMZgxKygfvG0Q8m2IT\n"
+
"SbMJWZtDeWGFJT5nqYG5el88Ar9MtHfNYd22sqiDy1xFLUQJfRrjNITQJQNWPqkp\n"
+
"/cSxWAQiAiAKHYbYwEy0XS9J0MeKQmqPswn0nCJKvH+esfMKkZvV3w=="
};
// Private key names of endEntityPrivateKeys.
private
final
static
String
[]
endEntityPrivateKeyNames
=
{
"EC"
,
"RSA"
,
"DSA"
,
};
/*
* Create an instance of SSLContext with the specified trust/key materials.
*/
private
SSLContext
createSSLContext
(
String
[]
trustedMaterials
,
String
[]
keyMaterialCerts
,
String
[]
keyMaterialKeys
,
String
[]
keyMaterialKeyAlgs
,
ContextParameters
params
)
throws
Exception
{
KeyStore
ts
=
null
;
// trust store
KeyStore
ks
=
null
;
// key store
char
passphrase
[]
=
"passphrase"
.
toCharArray
();
// Generate certificate from cert string.
CertificateFactory
cf
=
CertificateFactory
.
getInstance
(
"X.509"
);
// Import the trused certs.
ByteArrayInputStream
is
;
if
(
trustedMaterials
!=
null
&&
trustedMaterials
.
length
!=
0
)
{
ts
=
KeyStore
.
getInstance
(
"JKS"
);
ts
.
load
(
null
,
null
);
Certificate
[]
trustedCert
=
new
Certificate
[
trustedMaterials
.
length
];
for
(
int
i
=
0
;
i
<
trustedMaterials
.
length
;
i
++)
{
String
trustedCertStr
=
trustedMaterials
[
i
];
is
=
new
ByteArrayInputStream
(
trustedCertStr
.
getBytes
());
try
{
trustedCert
[
i
]
=
cf
.
generateCertificate
(
is
);
}
finally
{
is
.
close
();
}
ts
.
setCertificateEntry
(
"trusted-cert-"
+
i
,
trustedCert
[
i
]);
}
}
// Import the key materials.
//
// Note that certification pathes bigger than one are not supported yet.
boolean
hasKeyMaterials
=
(
keyMaterialCerts
!=
null
)
&&
(
keyMaterialCerts
.
length
!=
0
)
&&
(
keyMaterialKeys
!=
null
)
&&
(
keyMaterialKeys
.
length
!=
0
)
&&
(
keyMaterialKeyAlgs
!=
null
)
&&
(
keyMaterialKeyAlgs
.
length
!=
0
)
&&
(
keyMaterialCerts
.
length
==
keyMaterialKeys
.
length
)
&&
(
keyMaterialCerts
.
length
==
keyMaterialKeyAlgs
.
length
);
if
(
hasKeyMaterials
)
{
ks
=
KeyStore
.
getInstance
(
"JKS"
);
ks
.
load
(
null
,
null
);
for
(
int
i
=
0
;
i
<
keyMaterialCerts
.
length
;
i
++)
{
String
keyCertStr
=
keyMaterialCerts
[
i
];
// generate the private key.
PKCS8EncodedKeySpec
priKeySpec
=
new
PKCS8EncodedKeySpec
(
Base64
.
getMimeDecoder
().
decode
(
keyMaterialKeys
[
i
]));
KeyFactory
kf
=
KeyFactory
.
getInstance
(
keyMaterialKeyAlgs
[
i
]);
PrivateKey
priKey
=
kf
.
generatePrivate
(
priKeySpec
);
// generate certificate chain
is
=
new
ByteArrayInputStream
(
keyCertStr
.
getBytes
());
Certificate
keyCert
=
null
;
try
{
keyCert
=
cf
.
generateCertificate
(
is
);
}
finally
{
is
.
close
();
}
Certificate
[]
chain
=
new
Certificate
[]
{
keyCert
};
// import the key entry.
ks
.
setKeyEntry
(
"cert-"
+
keyMaterialKeyAlgs
[
i
],
priKey
,
passphrase
,
chain
);
}
}
// Create an SSLContext object.
TrustManagerFactory
tmf
=
TrustManagerFactory
.
getInstance
(
params
.
tmAlgorithm
);
tmf
.
init
(
ts
);
SSLContext
context
=
SSLContext
.
getInstance
(
params
.
contextProtocol
);
if
(
hasKeyMaterials
&&
ks
!=
null
)
{
KeyManagerFactory
kmf
=
KeyManagerFactory
.
getInstance
(
params
.
kmAlgorithm
);
kmf
.
init
(
ks
,
passphrase
);
context
.
init
(
kmf
.
getKeyManagers
(),
tmf
.
getTrustManagers
(),
null
);
}
else
{
context
.
init
(
null
,
tmf
.
getTrustManagers
(),
null
);
}
return
context
;
}
/*
* =================================================
* Stuffs to boot up the client-server mode testing.
*/
private
Thread
clientThread
=
null
;
private
Thread
serverThread
=
null
;
private
volatile
Exception
serverException
=
null
;
private
volatile
Exception
clientException
=
null
;
/*
* Should we run the client or server in a separate thread?
* Both sides can throw exceptions, but do you have a preference
* as to which side should be the main thread.
*/
private
static
final
boolean
separateServerThread
=
false
;
/*
* Boot up the testing, used to drive remainder of the test.
*/
private
void
bootup
()
throws
Exception
{
Exception
startException
=
null
;
try
{
if
(
separateServerThread
)
{
startServer
(
true
);
startClient
(
false
);
}
else
{
startClient
(
true
);
startServer
(
false
);
}
}
catch
(
Exception
e
)
{
startException
=
e
;
}
/*
* Wait for other side to close down.
*/
if
(
separateServerThread
)
{
if
(
serverThread
!=
null
)
{
serverThread
.
join
();
}
}
else
{
if
(
clientThread
!=
null
)
{
clientThread
.
join
();
}
}
/*
* When we get here, the test is pretty much over.
* Which side threw the error?
*/
Exception
local
;
Exception
remote
;
if
(
separateServerThread
)
{
remote
=
serverException
;
local
=
clientException
;
}
else
{
remote
=
clientException
;
local
=
serverException
;
}
Exception
exception
=
null
;
/*
* Check various exception conditions.
*/
if
((
local
!=
null
)
&&
(
remote
!=
null
))
{
// If both failed, return the curthread's exception.
local
.
initCause
(
remote
);
exception
=
local
;
}
else
if
(
local
!=
null
)
{
exception
=
local
;
}
else
if
(
remote
!=
null
)
{
exception
=
remote
;
}
else
if
(
startException
!=
null
)
{
exception
=
startException
;
}
/*
* If there was an exception *AND* a startException,
* output it.
*/
if
(
exception
!=
null
)
{
if
(
exception
!=
startException
&&
startException
!=
null
)
{
exception
.
addSuppressed
(
startException
);
}
throw
exception
;
}
// Fall-through: no exception to throw!
}
private
void
startServer
(
boolean
newThread
)
throws
Exception
{
if
(
newThread
)
{
serverThread
=
new
Thread
()
{
@Override
public
void
run
()
{
try
{
doServerSide
();
}
catch
(
Exception
e
)
{
/*
* Our server thread just died.
*
* Release the client, if not active already...
*/
logException
(
"Server died"
,
e
);
serverException
=
e
;
}
}
};
serverThread
.
start
();
}
else
{
try
{
doServerSide
();
}
catch
(
Exception
e
)
{
logException
(
"Server failed"
,
e
);
serverException
=
e
;
}
}
}
private
void
startClient
(
boolean
newThread
)
throws
Exception
{
if
(
newThread
)
{
clientThread
=
new
Thread
()
{
@Override
public
void
run
()
{
try
{
doClientSide
();
}
catch
(
Exception
e
)
{
/*
* Our client thread just died.
*/
logException
(
"Client died"
,
e
);
clientException
=
e
;
}
}
};
clientThread
.
start
();
}
else
{
try
{
doClientSide
();
}
catch
(
Exception
e
)
{
logException
(
"Client failed"
,
e
);
clientException
=
e
;
}
}
}
private
synchronized
void
logException
(
String
prefix
,
Throwable
cause
)
{
System
.
out
.
println
(
prefix
+
": "
+
cause
);
cause
.
printStackTrace
(
System
.
out
);
}
}
test/sun/security/ssl/com/sun/net/ssl/internal/ssl/DHKeyExchange/DHEKeySizing.java
浏览文件 @
3faae241
/*
* Copyright (c) 2013, 201
7
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013, 201
5
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
...
...
@@ -31,44 +31,33 @@
* @bug 6956398
* @summary make ephemeral DH key match the length of the certificate key
* @run main/othervm
* DHEKeySizing TLS_DHE_RSA_WITH_AES_128_CBC_SHA false 1639 267
* @run main/othervm -Djsse.enableFFDHE=false
* DHEKeySizing SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA true 1255 75
* @run main/othervm -Djsse.enableFFDHE=false
* -Djdk.tls.ephemeralDHKeySize=matched
* @run main/othervm -Djdk.tls.ephemeralDHKeySize=matched
* DHEKeySizing SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA true 1255 75
* @run main/othervm -Djsse.enableFFDHE=false
* -Djdk.tls.ephemeralDHKeySize=legacy
* @run main/othervm -Djdk.tls.ephemeralDHKeySize=legacy
* DHEKeySizing SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA true 1255 75
* @run main/othervm -Djsse.enableFFDHE=false
* -Djdk.tls.ephemeralDHKeySize=1024
* @run main/othervm -Djdk.tls.ephemeralDHKeySize=1024
* DHEKeySizing SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA true 1255 75
*
* @run main/othervm
-Djsse.enableFFDHE=false
* @run main/othervm
* DHEKeySizing SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA true 229 75
*
* @run main/othervm
-Djsse.enableFFDHE=false
* @run main/othervm
* DHEKeySizing TLS_DHE_RSA_WITH_AES_128_CBC_SHA false 1383 139
* @run main/othervm -Djsse.enableFFDHE=false
* -Djdk.tls.ephemeralDHKeySize=legacy
* @run main/othervm -Djdk.tls.ephemeralDHKeySize=legacy
* DHEKeySizing TLS_DHE_RSA_WITH_AES_128_CBC_SHA false 1319 107
* @run main/othervm -Djsse.enableFFDHE=false
* -Djdk.tls.ephemeralDHKeySize=matched
* @run main/othervm -Djdk.tls.ephemeralDHKeySize=matched
* DHEKeySizing TLS_DHE_RSA_WITH_AES_128_CBC_SHA false 1639 267
* @run main/othervm -Djsse.enableFFDHE=false
* -Djdk.tls.ephemeralDHKeySize=1024
* @run main/othervm -Djdk.tls.ephemeralDHKeySize=1024
* DHEKeySizing TLS_DHE_RSA_WITH_AES_128_CBC_SHA false 1383 139
*
* @run main/othervm
-Djsse.enableFFDHE=false
* @run main/othervm
* DHEKeySizing SSL_DH_anon_WITH_RC4_128_MD5 false 357 139
* @run main/othervm -Djsse.enableFFDHE=false
* -Djdk.tls.ephemeralDHKeySize=legacy
* @run main/othervm -Djdk.tls.ephemeralDHKeySize=legacy
* DHEKeySizing SSL_DH_anon_WITH_RC4_128_MD5 false 293 107
* @run main/othervm -Djsse.enableFFDHE=false
* -Djdk.tls.ephemeralDHKeySize=matched
* @run main/othervm -Djdk.tls.ephemeralDHKeySize=matched
* DHEKeySizing SSL_DH_anon_WITH_RC4_128_MD5 false 357 139
* @run main/othervm -Djsse.enableFFDHE=false
* -Djdk.tls.ephemeralDHKeySize=1024
* @run main/othervm -Djdk.tls.ephemeralDHKeySize=1024
* DHEKeySizing SSL_DH_anon_WITH_RC4_128_MD5 false 357 139
*/
...
...
test/sun/security/ssl/com/sun/net/ssl/internal/ssl/DHKeyExchange/UseStrongDHSizes.java
已删除
100644 → 0
浏览文件 @
25f17276
/*
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
//
// SunJSSE does not support dynamic system properties, no way to re-use
// system properties in samevm/agentvm mode.
//
/*
* @test
* @bug 8140436
* @modules jdk.crypto.ec
* @library /javax/net/ssl/templates
* @summary Negotiated Finite Field Diffie-Hellman Ephemeral Parameters for TLS
* @run main/othervm UseStrongDHSizes 2048
* @run main/othervm -Djdk.tls.namedGroups=ffdhe2048 UseStrongDHSizes 2048
*/
import
java.io.InputStream
;
import
java.io.OutputStream
;
import
java.security.Security
;
import
javax.net.ssl.SSLSocket
;
public
class
UseStrongDHSizes
extends
SSLSocketTemplate
{
/*
* Run the test case.
*/
public
static
void
main
(
String
[]
args
)
throws
Exception
{
// reset the security property to make sure that the algorithms
// and keys used in this test are not disabled unexpectedly.
String
constraint
=
"DH keySize < "
+
Integer
.
valueOf
(
args
[
0
]);
Security
.
setProperty
(
"jdk.tls.disabledAlgorithms"
,
constraint
);
Security
.
setProperty
(
"jdk.certpath.disabledAlgorithms"
,
""
);
(
new
UseStrongDHSizes
()).
run
();
}
@Override
protected
void
runServerApplication
(
SSLSocket
socket
)
throws
Exception
{
String
ciphers
[]
=
{
"TLS_DHE_RSA_WITH_AES_128_CBC_SHA"
,
"TLS_DHE_DSS_WITH_AES_128_CBC_SHA"
,
"SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA"
,
"SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA"
};
socket
.
setEnabledCipherSuites
(
ciphers
);
socket
.
setWantClientAuth
(
true
);
InputStream
sslIS
=
socket
.
getInputStream
();
OutputStream
sslOS
=
socket
.
getOutputStream
();
sslIS
.
read
();
sslOS
.
write
(
85
);
sslOS
.
flush
();
}
@Override
protected
void
runClientApplication
(
SSLSocket
socket
)
throws
Exception
{
String
ciphers
[]
=
{
"TLS_DHE_RSA_WITH_AES_128_CBC_SHA"
,
"TLS_DHE_DSS_WITH_AES_128_CBC_SHA"
,
"SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA"
,
"SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA"
};
socket
.
setEnabledCipherSuites
(
ciphers
);
socket
.
setUseClientMode
(
true
);
InputStream
sslIS
=
socket
.
getInputStream
();
OutputStream
sslOS
=
socket
.
getOutputStream
();
sslOS
.
write
(
280
);
sslOS
.
flush
();
sslIS
.
read
();
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录