Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_jdk
提交
586c5ac8
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看板
提交
586c5ac8
编写于
4月 23, 2014
作者:
X
xuelei
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
8037066: Secure transport layer
Reviewed-by: weijun, ahgross, asmotrak, mbankal
上级
06144182
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
223 addition
and
9 deletion
+223
-9
src/share/classes/sun/security/ssl/ClientHandshaker.java
src/share/classes/sun/security/ssl/ClientHandshaker.java
+186
-7
src/share/classes/sun/security/ssl/Handshaker.java
src/share/classes/sun/security/ssl/Handshaker.java
+12
-1
src/share/classes/sun/security/ssl/SSLSessionImpl.java
src/share/classes/sun/security/ssl/SSLSessionImpl.java
+25
-1
未找到文件。
src/share/classes/sun/security/ssl/ClientHandshaker.java
浏览文件 @
586c5ac8
/*
* Copyright (c) 1996, 201
3
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 201
4
, 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
...
...
@@ -36,6 +36,8 @@ import java.security.spec.ECParameterSpec;
import
java.security.cert.X509Certificate
;
import
java.security.cert.CertificateException
;
import
java.security.cert.CertificateParsingException
;
import
javax.security.auth.x500.X500Principal
;
import
javax.crypto.SecretKey
;
import
javax.crypto.spec.SecretKeySpec
;
...
...
@@ -89,11 +91,65 @@ final class ClientHandshaker extends Handshaker {
private
final
static
boolean
enableSNIExtension
=
Debug
.
getBooleanProperty
(
"jsse.enableSNIExtension"
,
true
);
/*
* Allow unsafe server certificate change?
*
* Server certificate change during SSL/TLS renegotiation may be considered
* unsafe, as described in the Triple Handshake attacks:
*
* https://secure-resumption.com/tlsauth.pdf
*
* Endpoint identification (See
* SSLParameters.getEndpointIdentificationAlgorithm()) is a pretty nice
* guarantee that the server certificate change in renegotiation is legal.
* However, endpoing identification is only enabled for HTTPS and LDAP
* over SSL/TLS by default. It is not enough to protect SSL/TLS
* connections other than HTTPS and LDAP.
*
* The renegotiation indication extension (See RFC 5764) is a pretty
* strong guarantee that the endpoints on both client and server sides
* are identical on the same connection. However, the Triple Handshake
* attacks can bypass this guarantee if there is a session-resumption
* handshake between the initial full handshake and the renegotiation
* full handshake.
*
* Server certificate change may be unsafe and should be restricted if
* endpoint identification is not enabled and the previous handshake is
* a session-resumption abbreviated initial handshake, unless the
* identities represented by both certificates can be regraded as the
* same (See isIdentityEquivalent()).
*
* Considering the compatibility impact and the actual requirements to
* support server certificate change in practice, the system property,
* jdk.tls.allowUnsafeServerCertChange, is used to define whether unsafe
* server certificate change in renegotiation is allowed or not. The
* default value of the system property is "false". To mitigate the
* compactibility impact, applications may want to set the system
* property to "true" at their own risk.
*
* If the value of the system property is "false", server certificate
* change in renegotiation after a session-resumption abbreviated initial
* handshake is restricted (See isIdentityEquivalent()).
*
* If the system property is set to "true" explicitly, the restriction on
* server certificate change in renegotiation is disabled.
*/
private
final
static
boolean
allowUnsafeServerCertChange
=
Debug
.
getBooleanProperty
(
"jdk.tls.allowUnsafeServerCertChange"
,
false
);
private
List
<
SNIServerName
>
requestedServerNames
=
Collections
.<
SNIServerName
>
emptyList
();
private
boolean
serverNamesAccepted
=
false
;
/*
* the reserved server certificate chain in previous handshaking
*
* The server certificate chain is only reserved if the previous
* handshake is a session-resumption abbreviated initial handshake.
*/
private
X509Certificate
[]
reservedServerCerts
=
null
;
/*
* Constructors
*/
...
...
@@ -555,14 +611,19 @@ final class ClientHandshaker extends Handshaker {
// we wanted to resume, but the server refused
session
=
null
;
if
(!
enableNewSession
)
{
throw
new
SSLException
(
"New session creation is disabled"
);
throw
new
SSLException
(
"New session creation is disabled"
);
}
}
}
if
(
resumingSession
&&
session
!=
null
)
{
setHandshakeSessionSE
(
session
);
// Reserve the handshake state if this is a session-resumption
// abbreviated initial handshake.
if
(
isInitialHandshake
)
{
session
.
setAsSessionResumption
(
true
);
}
return
;
}
...
...
@@ -1063,6 +1124,13 @@ final class ClientHandshaker extends Handshaker {
serverVerifyData
=
mesg
.
getVerifyData
();
}
/*
* Reset the handshake state if this is not an initial handshake.
*/
if
(!
isInitialHandshake
)
{
session
.
setAsSessionResumption
(
false
);
}
/*
* OK, it verified. If we're doing the fast handshake, add that
* "Finished" message to the hash of handshake messages, then send
...
...
@@ -1161,8 +1229,23 @@ final class ClientHandshaker extends Handshaker {
System
.
out
.
println
(
"%% No cached client session"
);
}
}
if
((
session
!=
null
)
&&
(
session
.
isRejoinable
()
==
false
))
{
session
=
null
;
if
(
session
!=
null
)
{
// If unsafe server certificate change is not allowed, reserve
// current server certificates if the previous handshake is a
// session-resumption abbreviated initial handshake.
if
(!
allowUnsafeServerCertChange
&&
session
.
isSessionResumption
())
{
try
{
// If existing, peer certificate chain cannot be null.
reservedServerCerts
=
(
X509Certificate
[])
session
.
getPeerCertificates
();
}
catch
(
SSLPeerUnverifiedException
puve
)
{
// Maybe not certificate-based, ignore the exception.
}
}
if
(!
session
.
isRejoinable
())
{
session
=
null
;
}
}
if
(
session
!=
null
)
{
...
...
@@ -1331,9 +1414,28 @@ final class ClientHandshaker extends Handshaker {
}
X509Certificate
[]
peerCerts
=
mesg
.
getCertificateChain
();
if
(
peerCerts
.
length
==
0
)
{
fatalSE
(
Alerts
.
alert_bad_certificate
,
"empty certificate chain"
);
fatalSE
(
Alerts
.
alert_bad_certificate
,
"empty certificate chain"
);
}
// Allow server certificate change in client side during renegotiation
// after a session-resumption abbreviated initial handshake?
//
// DO NOT need to check allowUnsafeServerCertChange here. We only
// reserve server certificates when allowUnsafeServerCertChange is
// flase.
if
(
reservedServerCerts
!=
null
)
{
// It is not necessary to check the certificate update if endpoint
// identification is enabled.
String
identityAlg
=
getEndpointIdentificationAlgorithmSE
();
if
((
identityAlg
==
null
||
identityAlg
.
length
()
==
0
)
&&
!
isIdentityEquivalent
(
peerCerts
[
0
],
reservedServerCerts
[
0
]))
{
fatalSE
(
Alerts
.
alert_bad_certificate
,
"server certificate change is restricted "
+
"during renegotiation"
);
}
}
// ask the trust manager to verify the chain
X509TrustManager
tm
=
sslContext
.
getX509TrustManager
();
try
{
...
...
@@ -1370,4 +1472,81 @@ final class ClientHandshaker extends Handshaker {
}
session
.
setPeerCertificates
(
peerCerts
);
}
/*
* Whether the certificates can represent the same identity?
*
* The certificates can be used to represent the same identity:
* 1. If the subject alternative names of IP address are present in
* both certificates, they should be identical; otherwise,
* 2. if the subject alternative names of DNS name are present in
* both certificates, they should be identical; otherwise,
* 3. if the subject fields are present in both certificates, the
* certificate subjects and issuers should be identical.
*/
private
static
boolean
isIdentityEquivalent
(
X509Certificate
thisCert
,
X509Certificate
prevCert
)
{
if
(
thisCert
.
equals
(
prevCert
))
{
return
true
;
}
// check the iPAddress field in subjectAltName extension
Object
thisIPAddress
=
getSubjectAltName
(
thisCert
,
7
);
// 7: iPAddress
Object
prevIPAddress
=
getSubjectAltName
(
prevCert
,
7
);
if
(
thisIPAddress
!=
null
&&
prevIPAddress
!=
null
)
{
// only allow the exactly match
return
Objects
.
equals
(
thisIPAddress
,
prevIPAddress
);
}
// check the dNSName field in subjectAltName extension
Object
thisDNSName
=
getSubjectAltName
(
thisCert
,
2
);
// 2: dNSName
Object
prevDNSName
=
getSubjectAltName
(
prevCert
,
2
);
if
(
thisDNSName
!=
null
&&
prevDNSName
!=
null
)
{
// only allow the exactly match
return
Objects
.
equals
(
thisDNSName
,
prevDNSName
);
}
// check the certificate subject and issuer
X500Principal
thisSubject
=
thisCert
.
getSubjectX500Principal
();
X500Principal
prevSubject
=
prevCert
.
getSubjectX500Principal
();
X500Principal
thisIssuer
=
thisCert
.
getIssuerX500Principal
();
X500Principal
prevIssuer
=
prevCert
.
getIssuerX500Principal
();
if
(!
thisSubject
.
getName
().
isEmpty
()
&&
!
prevSubject
.
getName
().
isEmpty
()
&&
thisSubject
.
equals
(
prevSubject
)
&&
thisIssuer
.
equals
(
prevIssuer
))
{
return
true
;
}
return
false
;
}
/*
* Returns the subject alternative name of the specified type in the
* subjectAltNames extension of a certificate.
*/
private
static
Object
getSubjectAltName
(
X509Certificate
cert
,
int
type
)
{
Collection
<
List
<?>>
subjectAltNames
;
try
{
subjectAltNames
=
cert
.
getSubjectAlternativeNames
();
}
catch
(
CertificateParsingException
cpe
)
{
if
(
debug
!=
null
&&
Debug
.
isOn
(
"handshake"
))
{
System
.
out
.
println
(
"Attempt to obtain subjectAltNames extension failed!"
);
}
return
null
;
}
if
(
subjectAltNames
!=
null
)
{
for
(
List
<?>
subjectAltName
:
subjectAltNames
)
{
int
subjectAltNameType
=
(
Integer
)
subjectAltName
.
get
(
0
);
if
(
subjectAltNameType
==
type
)
{
return
subjectAltName
.
get
(
1
);
}
}
}
return
null
;
}
}
src/share/classes/sun/security/ssl/Handshaker.java
浏览文件 @
586c5ac8
/*
* Copyright (c) 1996, 201
3
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 201
4
, 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
...
...
@@ -359,6 +359,17 @@ abstract class Handshaker {
}
}
String
getEndpointIdentificationAlgorithmSE
()
{
SSLParameters
paras
;
if
(
conn
!=
null
)
{
paras
=
conn
.
getSSLParameters
();
}
else
{
paras
=
engine
.
getSSLParameters
();
}
return
paras
.
getEndpointIdentificationAlgorithm
();
}
private
void
setVersionSE
(
ProtocolVersion
protocolVersion
)
{
if
(
conn
!=
null
)
{
conn
.
setVersion
(
protocolVersion
);
...
...
src/share/classes/sun/security/ssl/SSLSessionImpl.java
浏览文件 @
586c5ac8
/*
* Copyright (c) 1996, 201
3
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 201
4
, 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
...
...
@@ -114,6 +114,14 @@ final class SSLSessionImpl extends ExtendedSSLSession {
private
Principal
peerPrincipal
;
private
Principal
localPrincipal
;
/*
* Is the session currently re-established with a session-resumption
* abbreviated initial handshake?
*
* Note that currently we only set this variable in client side.
*/
private
boolean
isSessionResumption
=
false
;
/*
* We count session creations, eventually for statistical data but
* also since counters make shorter debugging IDs than the big ones
...
...
@@ -324,6 +332,22 @@ final class SSLSessionImpl extends ExtendedSSLSession {
}
}
/**
* Return true if the session is currently re-established with a
* session-resumption abbreviated initial handshake.
*/
boolean
isSessionResumption
()
{
return
isSessionResumption
;
}
/**
* Resets whether the session is re-established with a session-resumption
* abbreviated initial handshake.
*/
void
setAsSessionResumption
(
boolean
flag
)
{
isSessionResumption
=
flag
;
}
/**
* Returns the name of the cipher suite in use on this session
*/
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录