Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_jdk
提交
81eccafb
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看板
提交
81eccafb
编写于
10月 19, 2011
作者:
M
mullan
浏览文件
操作
浏览文件
下载
差异文件
Merge
上级
4c79d01a
138dcf01
变更
10
隐藏空白更改
内联
并排
Showing
10 changed file
with
636 addition
and
142 deletion
+636
-142
src/share/classes/sun/security/pkcs11/KeyCache.java
src/share/classes/sun/security/pkcs11/KeyCache.java
+5
-5
src/share/classes/sun/security/provider/X509Factory.java
src/share/classes/sun/security/provider/X509Factory.java
+12
-11
src/share/classes/sun/security/provider/certpath/CertStoreHelper.java
...asses/sun/security/provider/certpath/CertStoreHelper.java
+3
-2
src/share/classes/sun/security/provider/certpath/URICertStore.java
.../classes/sun/security/provider/certpath/URICertStore.java
+8
-9
src/share/classes/sun/security/provider/certpath/X509CertificatePair.java
...s/sun/security/provider/certpath/X509CertificatePair.java
+5
-4
src/share/classes/sun/security/provider/certpath/ldap/LDAPCertStore.java
...es/sun/security/provider/certpath/ldap/LDAPCertStore.java
+22
-23
src/share/classes/sun/security/ssl/CipherBox.java
src/share/classes/sun/security/ssl/CipherBox.java
+8
-5
src/share/classes/sun/security/ssl/SSLSessionContextImpl.java
...share/classes/sun/security/ssl/SSLSessionContextImpl.java
+16
-15
src/share/classes/sun/security/util/Cache.java
src/share/classes/sun/security/util/Cache.java
+78
-68
test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/SSLEngineBadBufferArrayAccess.java
...rnal/ssl/SSLEngineImpl/SSLEngineBadBufferArrayAccess.java
+479
-0
未找到文件。
src/share/classes/sun/security/pkcs11/KeyCache.java
浏览文件 @
81eccafb
/*
* Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003,
2011,
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
...
...
@@ -48,7 +48,7 @@ import sun.security.util.Cache;
*/
final
class
KeyCache
{
private
final
Cache
strongCache
;
private
final
Cache
<
IdentityWrapper
,
P11Key
>
strongCache
;
private
WeakReference
<
Map
<
Key
,
P11Key
>>
cacheReference
;
...
...
@@ -77,7 +77,7 @@ final class KeyCache {
}
synchronized
P11Key
get
(
Key
key
)
{
P11Key
p11Key
=
(
P11Key
)
strongCache
.
get
(
new
IdentityWrapper
(
key
));
P11Key
p11Key
=
strongCache
.
get
(
new
IdentityWrapper
(
key
));
if
(
p11Key
!=
null
)
{
return
p11Key
;
}
...
...
@@ -94,8 +94,8 @@ final class KeyCache {
Map
<
Key
,
P11Key
>
map
=
(
cacheReference
==
null
)
?
null
:
cacheReference
.
get
();
if
(
map
==
null
)
{
map
=
new
IdentityHashMap
<
Key
,
P11Key
>();
cacheReference
=
new
WeakReference
<
Map
<
Key
,
P11Key
>
>(
map
);
map
=
new
IdentityHashMap
<>();
cacheReference
=
new
WeakReference
<>(
map
);
}
map
.
put
(
key
,
p11Key
);
}
...
...
src/share/classes/sun/security/provider/X509Factory.java
浏览文件 @
81eccafb
...
...
@@ -64,8 +64,10 @@ public class X509Factory extends CertificateFactorySpi {
private
static
final
int
ENC_MAX_LENGTH
=
4096
*
1024
;
// 4 MB MAX
private
static
final
Cache
certCache
=
Cache
.
newSoftMemoryCache
(
750
);
private
static
final
Cache
crlCache
=
Cache
.
newSoftMemoryCache
(
750
);
private
static
final
Cache
<
Object
,
X509CertImpl
>
certCache
=
Cache
.
newSoftMemoryCache
(
750
);
private
static
final
Cache
<
Object
,
X509CRLImpl
>
crlCache
=
Cache
.
newSoftMemoryCache
(
750
);
/**
* Generates an X.509 certificate object and initializes it with
...
...
@@ -90,7 +92,7 @@ public class X509Factory extends CertificateFactorySpi {
try
{
byte
[]
encoding
=
readOneBlock
(
is
);
if
(
encoding
!=
null
)
{
X509CertImpl
cert
=
(
X509CertImpl
)
getFromCache
(
certCache
,
encoding
);
X509CertImpl
cert
=
getFromCache
(
certCache
,
encoding
);
if
(
cert
!=
null
)
{
return
cert
;
}
...
...
@@ -151,7 +153,7 @@ public class X509Factory extends CertificateFactorySpi {
}
else
{
encoding
=
c
.
getEncoded
();
}
X509CertImpl
newC
=
(
X509CertImpl
)
getFromCache
(
certCache
,
encoding
);
X509CertImpl
newC
=
getFromCache
(
certCache
,
encoding
);
if
(
newC
!=
null
)
{
return
newC
;
}
...
...
@@ -181,7 +183,7 @@ public class X509Factory extends CertificateFactorySpi {
}
else
{
encoding
=
c
.
getEncoded
();
}
X509CRLImpl
newC
=
(
X509CRLImpl
)
getFromCache
(
crlCache
,
encoding
);
X509CRLImpl
newC
=
getFromCache
(
crlCache
,
encoding
);
if
(
newC
!=
null
)
{
return
newC
;
}
...
...
@@ -198,18 +200,17 @@ public class X509Factory extends CertificateFactorySpi {
/**
* Get the X509CertImpl or X509CRLImpl from the cache.
*/
private
static
synchronized
Object
getFromCache
(
Cache
cache
,
private
static
synchronized
<
K
,
V
>
V
getFromCache
(
Cache
<
K
,
V
>
cache
,
byte
[]
encoding
)
{
Object
key
=
new
Cache
.
EqualByteArray
(
encoding
);
Object
value
=
cache
.
get
(
key
);
return
value
;
return
cache
.
get
(
key
);
}
/**
* Add the X509CertImpl or X509CRLImpl to the cache.
*/
private
static
synchronized
void
addToCache
(
Cache
cache
,
byte
[]
encoding
,
Object
value
)
{
private
static
synchronized
<
V
>
void
addToCache
(
Cache
<
Object
,
V
>
cache
,
byte
[]
encoding
,
V
value
)
{
if
(
encoding
.
length
>
ENC_MAX_LENGTH
)
{
return
;
}
...
...
@@ -361,7 +362,7 @@ public class X509Factory extends CertificateFactorySpi {
try
{
byte
[]
encoding
=
readOneBlock
(
is
);
if
(
encoding
!=
null
)
{
X509CRLImpl
crl
=
(
X509CRLImpl
)
getFromCache
(
crlCache
,
encoding
);
X509CRLImpl
crl
=
getFromCache
(
crlCache
,
encoding
);
if
(
crl
!=
null
)
{
return
crl
;
}
...
...
src/share/classes/sun/security/provider/certpath/CertStoreHelper.java
浏览文件 @
81eccafb
...
...
@@ -59,12 +59,13 @@ public abstract class CertStoreHelper {
"SSLServer"
,
"sun.security.provider.certpath.ssl.SSLServerCertStoreHelper"
);
};
private
static
Cache
cache
=
Cache
.
newSoftMemoryCache
(
NUM_TYPES
);
private
static
Cache
<
String
,
CertStoreHelper
>
cache
=
Cache
.
newSoftMemoryCache
(
NUM_TYPES
);
public
static
CertStoreHelper
getInstance
(
final
String
type
)
throws
NoSuchAlgorithmException
{
CertStoreHelper
helper
=
(
CertStoreHelper
)
cache
.
get
(
type
);
CertStoreHelper
helper
=
cache
.
get
(
type
);
if
(
helper
!=
null
)
{
return
helper
;
}
...
...
src/share/classes/sun/security/provider/certpath/URICertStore.java
浏览文件 @
81eccafb
...
...
@@ -100,8 +100,7 @@ class URICertStore extends CertStoreSpi {
private
final
CertificateFactory
factory
;
// cached Collection of X509Certificates (may be empty, never null)
private
Collection
<
X509Certificate
>
certs
=
Collections
.<
X509Certificate
>
emptySet
();
private
Collection
<
X509Certificate
>
certs
=
Collections
.
emptySet
();
// cached X509CRL (may be null)
private
X509CRL
crl
;
...
...
@@ -157,14 +156,14 @@ class URICertStore extends CertStoreSpi {
* Returns a URI CertStore. This method consults a cache of
* CertStores (shared per JVM) using the URI as a key.
*/
private
static
final
Cache
certStoreCache
=
Cache
.
newSoftMemoryCache
(
CACHE_SIZE
);
private
static
final
Cache
<
URICertStoreParameters
,
CertStore
>
certStoreCache
=
Cache
.
newSoftMemoryCache
(
CACHE_SIZE
);
static
synchronized
CertStore
getInstance
(
URICertStoreParameters
params
)
throws
NoSuchAlgorithmException
,
InvalidAlgorithmParameterException
{
if
(
debug
!=
null
)
{
debug
.
println
(
"CertStore URI:"
+
params
.
uri
);
}
CertStore
ucs
=
(
CertStore
)
certStoreCache
.
get
(
params
);
CertStore
ucs
=
certStoreCache
.
get
(
params
);
if
(
ucs
==
null
)
{
ucs
=
new
UCS
(
new
URICertStore
(
params
),
null
,
"URI"
,
params
);
certStoreCache
.
put
(
params
,
ucs
);
...
...
@@ -287,7 +286,7 @@ class URICertStore extends CertStoreSpi {
}
// exception, forget previous values
lastModified
=
0
;
certs
=
Collections
.
<
X509Certificate
>
emptySet
();
certs
=
Collections
.
emptySet
();
return
certs
;
}
...
...
@@ -394,7 +393,7 @@ class URICertStore extends CertStoreSpi {
// exception, forget previous values
lastModified
=
0
;
crl
=
null
;
return
Collections
.
<
X509CRL
>
emptyList
();
return
Collections
.
emptyList
();
}
/**
...
...
@@ -404,9 +403,9 @@ class URICertStore extends CertStoreSpi {
private
static
Collection
<
X509CRL
>
getMatchingCRLs
(
X509CRL
crl
,
CRLSelector
selector
)
{
if
(
selector
==
null
||
(
crl
!=
null
&&
selector
.
match
(
crl
)))
{
return
Collections
.
<
X509CRL
>
singletonList
(
crl
);
return
Collections
.
singletonList
(
crl
);
}
else
{
return
Collections
.
<
X509CRL
>
emptyList
();
return
Collections
.
emptyList
();
}
}
...
...
src/share/classes/sun/security/provider/certpath/X509CertificatePair.java
浏览文件 @
81eccafb
/*
* Copyright (c) 2000, 20
02
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 20
11
, 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
...
...
@@ -79,7 +79,8 @@ public class X509CertificatePair {
private
X509Certificate
reverse
;
private
byte
[]
encoded
;
private
static
final
Cache
cache
=
Cache
.
newSoftMemoryCache
(
750
);
private
static
final
Cache
<
Object
,
X509CertificatePair
>
cache
=
Cache
.
newSoftMemoryCache
(
750
);
/**
* Creates an empty instance of X509CertificatePair.
...
...
@@ -114,7 +115,7 @@ public class X509CertificatePair {
*
* For internal use only, external code should use generateCertificatePair.
*/
private
X509CertificatePair
(
byte
[]
encoded
)
throws
CertificateException
{
private
X509CertificatePair
(
byte
[]
encoded
)
throws
CertificateException
{
try
{
parse
(
new
DerValue
(
encoded
));
this
.
encoded
=
encoded
;
...
...
@@ -138,7 +139,7 @@ public class X509CertificatePair {
public
static
synchronized
X509CertificatePair
generateCertificatePair
(
byte
[]
encoded
)
throws
CertificateException
{
Object
key
=
new
Cache
.
EqualByteArray
(
encoded
);
X509CertificatePair
pair
=
(
X509CertificatePair
)
cache
.
get
(
key
);
X509CertificatePair
pair
=
cache
.
get
(
key
);
if
(
pair
!=
null
)
{
return
pair
;
}
...
...
src/share/classes/sun/security/provider/certpath/ldap/LDAPCertStore.java
浏览文件 @
81eccafb
/*
* Copyright (c) 2000, 20
06
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 20
11
, 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
...
...
@@ -160,7 +160,7 @@ public final class LDAPCertStore extends CertStoreSpi {
*/
private
boolean
prefetchCRLs
=
false
;
private
final
Cache
valueCache
;
private
final
Cache
<
String
,
byte
[][]>
valueCache
;
private
int
cacheHits
=
0
;
private
int
cacheMisses
=
0
;
...
...
@@ -207,10 +207,11 @@ public final class LDAPCertStore extends CertStoreSpi {
* Returns an LDAP CertStore. This method consults a cache of
* CertStores (shared per JVM) using the LDAP server/port as a key.
*/
private
static
final
Cache
certStoreCache
=
Cache
.
newSoftMemoryCache
(
185
);
private
static
final
Cache
<
LDAPCertStoreParameters
,
CertStore
>
certStoreCache
=
Cache
.
newSoftMemoryCache
(
185
);
static
synchronized
CertStore
getInstance
(
LDAPCertStoreParameters
params
)
throws
NoSuchAlgorithmException
,
InvalidAlgorithmParameterException
{
CertStore
lcs
=
(
CertStore
)
certStoreCache
.
get
(
params
);
CertStore
lcs
=
certStoreCache
.
get
(
params
);
if
(
lcs
==
null
)
{
lcs
=
CertStore
.
getInstance
(
"LDAP"
,
params
);
certStoreCache
.
put
(
params
,
lcs
);
...
...
@@ -232,7 +233,7 @@ public final class LDAPCertStore extends CertStoreSpi {
private
void
createInitialDirContext
(
String
server
,
int
port
)
throws
InvalidAlgorithmParameterException
{
String
url
=
"ldap://"
+
server
+
":"
+
port
;
Hashtable
<
String
,
Object
>
env
=
new
Hashtable
<
String
,
Object
>();
Hashtable
<
String
,
Object
>
env
=
new
Hashtable
<>();
env
.
put
(
Context
.
INITIAL_CONTEXT_FACTORY
,
"com.sun.jndi.ldap.LdapCtxFactory"
);
env
.
put
(
Context
.
PROVIDER_URL
,
url
);
...
...
@@ -283,7 +284,7 @@ public final class LDAPCertStore extends CertStoreSpi {
LDAPRequest
(
String
name
)
{
this
.
name
=
name
;
requestedAttributes
=
new
ArrayList
<
String
>(
5
);
requestedAttributes
=
new
ArrayList
<>(
5
);
}
String
getName
()
{
...
...
@@ -311,7 +312,7 @@ public final class LDAPCertStore extends CertStoreSpi {
+
cacheMisses
);
}
String
cacheKey
=
name
+
"|"
+
attrId
;
byte
[][]
values
=
(
byte
[][])
valueCache
.
get
(
cacheKey
);
byte
[][]
values
=
valueCache
.
get
(
cacheKey
);
if
(
values
!=
null
)
{
cacheHits
++;
return
values
;
...
...
@@ -347,7 +348,7 @@ public final class LDAPCertStore extends CertStoreSpi {
System
.
out
.
println
(
"LDAP requests: "
+
requests
);
}
}
valueMap
=
new
HashMap
<
String
,
byte
[][]
>(
8
);
valueMap
=
new
HashMap
<>(
8
);
String
[]
attrIds
=
requestedAttributes
.
toArray
(
STRING0
);
Attributes
attrs
;
try
{
...
...
@@ -429,10 +430,10 @@ public final class LDAPCertStore extends CertStoreSpi {
int
n
=
encodedCert
.
length
;
if
(
n
==
0
)
{
return
Collections
.
<
X509Certificate
>
emptySet
();
return
Collections
.
emptySet
();
}
List
<
X509Certificate
>
certs
=
new
ArrayList
<
X509Certificate
>(
n
);
List
<
X509Certificate
>
certs
=
new
ArrayList
<>(
n
);
/* decode certs and check if they satisfy selector */
for
(
int
i
=
0
;
i
<
n
;
i
++)
{
ByteArrayInputStream
bais
=
new
ByteArrayInputStream
(
encodedCert
[
i
]);
...
...
@@ -477,11 +478,10 @@ public final class LDAPCertStore extends CertStoreSpi {
int
n
=
encodedCertPair
.
length
;
if
(
n
==
0
)
{
return
Collections
.
<
X509CertificatePair
>
emptySet
();
return
Collections
.
emptySet
();
}
List
<
X509CertificatePair
>
certPairs
=
new
ArrayList
<
X509CertificatePair
>(
n
);
List
<
X509CertificatePair
>
certPairs
=
new
ArrayList
<>(
n
);
/* decode each cert pair and add it to the Collection */
for
(
int
i
=
0
;
i
<
n
;
i
++)
{
try
{
...
...
@@ -528,8 +528,7 @@ public final class LDAPCertStore extends CertStoreSpi {
getCertPairs
(
request
,
CROSS_CERT
);
// Find Certificates that match and put them in a list
ArrayList
<
X509Certificate
>
matchingCerts
=
new
ArrayList
<
X509Certificate
>();
ArrayList
<
X509Certificate
>
matchingCerts
=
new
ArrayList
<>();
for
(
X509CertificatePair
certPair
:
certPairs
)
{
X509Certificate
cert
;
if
(
forward
!=
null
)
{
...
...
@@ -587,7 +586,7 @@ public final class LDAPCertStore extends CertStoreSpi {
int
basicConstraints
=
xsel
.
getBasicConstraints
();
String
subject
=
xsel
.
getSubjectAsString
();
String
issuer
=
xsel
.
getIssuerAsString
();
HashSet
<
X509Certificate
>
certs
=
new
HashSet
<
X509Certificate
>();
HashSet
<
X509Certificate
>
certs
=
new
HashSet
<>();
if
(
debug
!=
null
)
{
debug
.
println
(
"LDAPCertStore.engineGetCertificates() basicConstraints: "
+
basicConstraints
);
...
...
@@ -706,10 +705,10 @@ public final class LDAPCertStore extends CertStoreSpi {
int
n
=
encodedCRL
.
length
;
if
(
n
==
0
)
{
return
Collections
.
<
X509CRL
>
emptySet
();
return
Collections
.
emptySet
();
}
List
<
X509CRL
>
crls
=
new
ArrayList
<
X509CRL
>(
n
);
List
<
X509CRL
>
crls
=
new
ArrayList
<>(
n
);
/* decode each crl and check if it matches selector */
for
(
int
i
=
0
;
i
<
n
;
i
++)
{
try
{
...
...
@@ -765,13 +764,13 @@ public final class LDAPCertStore extends CertStoreSpi {
throw
new
CertStoreException
(
"need X509CRLSelector to find CRLs"
);
}
X509CRLSelector
xsel
=
(
X509CRLSelector
)
selector
;
HashSet
<
X509CRL
>
crls
=
new
HashSet
<
X509CRL
>();
HashSet
<
X509CRL
>
crls
=
new
HashSet
<>();
// Look in directory entry for issuer of cert we're checking.
Collection
<
Object
>
issuerNames
;
X509Certificate
certChecking
=
xsel
.
getCertificateChecking
();
if
(
certChecking
!=
null
)
{
issuerNames
=
new
HashSet
<
Object
>();
issuerNames
=
new
HashSet
<>();
X500Principal
issuer
=
certChecking
.
getIssuerX500Principal
();
issuerNames
.
add
(
issuer
.
getName
(
X500Principal
.
RFC2253
));
}
else
{
...
...
@@ -796,7 +795,7 @@ public final class LDAPCertStore extends CertStoreSpi {
issuerName
=
(
String
)
nameObject
;
}
// If all we want is CA certs, try to get the (probably shorter) ARL
Collection
<
X509CRL
>
entryCRLs
=
Collections
.
<
X509CRL
>
emptySet
();
Collection
<
X509CRL
>
entryCRLs
=
Collections
.
emptySet
();
if
(
certChecking
==
null
||
certChecking
.
getBasicConstraints
()
!=
-
1
)
{
LDAPRequest
request
=
new
LDAPRequest
(
issuerName
);
request
.
addRequestedAttribute
(
CROSS_CERT
);
...
...
@@ -1028,9 +1027,9 @@ public final class LDAPCertStore extends CertStoreSpi {
throws
IOException
{
this
.
selector
=
selector
==
null
?
new
X509CRLSelector
()
:
selector
;
this
.
certIssuers
=
certIssuers
;
issuerNames
=
new
HashSet
<
Object
>();
issuerNames
=
new
HashSet
<>();
issuerNames
.
add
(
ldapDN
);
issuers
=
new
HashSet
<
X500Principal
>();
issuers
=
new
HashSet
<>();
issuers
.
add
(
new
X500Name
(
ldapDN
).
asX500Principal
());
}
// we only override the get (accessor methods) since the set methods
...
...
src/share/classes/sun/security/ssl/CipherBox.java
浏览文件 @
81eccafb
/*
* Copyright (c) 1996, 201
0
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 201
1
, 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
...
...
@@ -305,9 +305,11 @@ final class CipherBox {
byte
[]
buf
=
null
;
int
limit
=
bb
.
limit
();
if
(
bb
.
hasArray
())
{
int
arrayOffset
=
bb
.
arrayOffset
();
buf
=
bb
.
array
();
System
.
arraycopy
(
buf
,
pos
,
buf
,
pos
+
prefix
.
length
,
limit
-
pos
);
System
.
arraycopy
(
buf
,
arrayOffset
+
pos
,
buf
,
arrayOffset
+
pos
+
prefix
.
length
,
limit
-
pos
);
bb
.
limit
(
limit
+
prefix
.
length
);
}
else
{
buf
=
new
byte
[
limit
-
pos
];
...
...
@@ -491,9 +493,10 @@ final class CipherBox {
byte
[]
buf
=
null
;
int
limit
=
bb
.
limit
();
if
(
bb
.
hasArray
())
{
int
arrayOffset
=
bb
.
arrayOffset
();
buf
=
bb
.
array
();
System
.
arraycopy
(
buf
,
pos
+
blockSize
,
buf
,
pos
,
limit
-
pos
-
blockSize
);
System
.
arraycopy
(
buf
,
arrayOffset
+
pos
+
blockSize
,
buf
,
arrayOffset
+
pos
,
limit
-
pos
-
blockSize
);
bb
.
limit
(
limit
-
blockSize
);
}
else
{
buf
=
new
byte
[
limit
-
pos
-
blockSize
];
...
...
src/share/classes/sun/security/ssl/SSLSessionContextImpl.java
浏览文件 @
81eccafb
/*
* Copyright (c) 1999, 20
09
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1999, 20
11
, 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,11 +43,14 @@ import javax.net.ssl.SSLPeerUnverifiedException;
import
javax.net.ssl.SSLSession
;
import
sun.security.util.Cache
;
import
sun.security.util.Cache.CacheVisitor
;
final
class
SSLSessionContextImpl
implements
SSLSessionContext
{
private
Cache
sessionCache
;
// session cache, session id as key
private
Cache
sessionHostPortCache
;
// session cache, "host:port" as key
private
Cache
<
SessionId
,
SSLSessionImpl
>
sessionCache
;
// session cache, session id as key
private
Cache
<
String
,
SSLSessionImpl
>
sessionHostPortCache
;
// session cache, "host:port" as key
private
int
cacheLimit
;
// the max cache size
private
int
timeout
;
// timeout in seconds
...
...
@@ -71,8 +74,7 @@ final class SSLSessionContextImpl implements SSLSessionContext {
throw
new
NullPointerException
(
"session id cannot be null"
);
}
SSLSessionImpl
sess
=
(
SSLSessionImpl
)
sessionCache
.
get
(
new
SessionId
(
sessionId
));
SSLSessionImpl
sess
=
sessionCache
.
get
(
new
SessionId
(
sessionId
));
if
(!
isTimedout
(
sess
))
{
return
sess
;
}
...
...
@@ -157,8 +159,7 @@ final class SSLSessionContextImpl implements SSLSessionContext {
return
null
;
}
SSLSessionImpl
sess
=
(
SSLSessionImpl
)
sessionHostPortCache
.
get
(
getKey
(
hostname
,
port
));
SSLSessionImpl
sess
=
sessionHostPortCache
.
get
(
getKey
(
hostname
,
port
));
if
(!
isTimedout
(
sess
))
{
return
sess
;
}
...
...
@@ -193,7 +194,7 @@ final class SSLSessionContextImpl implements SSLSessionContext {
// package-private method, remove a cached SSLSession
void
remove
(
SessionId
key
)
{
SSLSessionImpl
s
=
(
SSLSessionImpl
)
sessionCache
.
get
(
key
);
SSLSessionImpl
s
=
sessionCache
.
get
(
key
);
if
(
s
!=
null
)
{
sessionCache
.
remove
(
key
);
sessionHostPortCache
.
remove
(
...
...
@@ -233,17 +234,17 @@ final class SSLSessionContextImpl implements SSLSessionContext {
}
final
class
SessionCacheVisitor
implements
sun
.
security
.
util
.
Cache
.
CacheVisitor
{
implements
Cache
.
CacheVisitor
<
SessionId
,
SSLSessionImpl
>
{
Vector
<
byte
[]>
ids
=
null
;
// public void visit(java.util.Map<
Object, Object
> map) {}
public
void
visit
(
java
.
util
.
Map
<
Object
,
Object
>
map
)
{
ids
=
new
Vector
<
byte
[]
>(
map
.
size
());
// public void visit(java.util.Map<
K,V
> map) {}
public
void
visit
(
java
.
util
.
Map
<
SessionId
,
SSLSessionImpl
>
map
)
{
ids
=
new
Vector
<>(
map
.
size
());
for
(
Object
key
:
map
.
keySet
())
{
SSLSessionImpl
value
=
(
SSLSessionImpl
)
map
.
get
(
key
);
for
(
SessionId
key
:
map
.
keySet
())
{
SSLSessionImpl
value
=
map
.
get
(
key
);
if
(!
isTimedout
(
value
))
{
ids
.
addElement
(
((
SessionId
)
key
)
.
getId
());
ids
.
addElement
(
key
.
getId
());
}
}
}
...
...
src/share/classes/sun/security/util/Cache.java
浏览文件 @
81eccafb
...
...
@@ -43,7 +43,7 @@ import java.lang.ref.*;
*
* . optional lifetime, specified in seconds.
*
* . sa
v
e for concurrent use by multiple threads
* . sa
f
e for concurrent use by multiple threads
*
* . values are held by either standard references or via SoftReferences.
* SoftReferences have the advantage that they are automatically cleared
...
...
@@ -69,7 +69,7 @@ import java.lang.ref.*;
*
* @author Andreas Sterbenz
*/
public
abstract
class
Cache
{
public
abstract
class
Cache
<
K
,
V
>
{
protected
Cache
()
{
// empty
...
...
@@ -88,12 +88,12 @@ public abstract class Cache {
/**
* Add an entry to the cache.
*/
public
abstract
void
put
(
Object
key
,
Object
value
);
public
abstract
void
put
(
K
key
,
V
value
);
/**
* Get a value from the cache.
*/
public
abstract
Object
get
(
Object
key
);
public
abstract
V
get
(
Object
key
);
/**
* Remove an entry from the cache.
...
...
@@ -113,14 +113,14 @@ public abstract class Cache {
/**
* accept a visitor
*/
public
abstract
void
accept
(
CacheVisitor
visitor
);
public
abstract
void
accept
(
CacheVisitor
<
K
,
V
>
visitor
);
/**
* Return a new memory cache with the specified maximum size, unlimited
* lifetime for entries, with the values held by SoftReferences.
*/
public
static
Cache
newSoftMemoryCache
(
int
size
)
{
return
new
MemoryCache
(
true
,
size
);
public
static
<
K
,
V
>
Cache
<
K
,
V
>
newSoftMemoryCache
(
int
size
)
{
return
new
MemoryCache
<>
(
true
,
size
);
}
/**
...
...
@@ -128,23 +128,24 @@ public abstract class Cache {
* specified maximum lifetime (in seconds), with the values held
* by SoftReferences.
*/
public
static
Cache
newSoftMemoryCache
(
int
size
,
int
timeout
)
{
return
new
MemoryCache
(
true
,
size
,
timeout
);
public
static
<
K
,
V
>
Cache
<
K
,
V
>
newSoftMemoryCache
(
int
size
,
int
timeout
)
{
return
new
MemoryCache
<>
(
true
,
size
,
timeout
);
}
/**
* Return a new memory cache with the specified maximum size, unlimited
* lifetime for entries, with the values held by standard references.
*/
public
static
Cache
newHardMemoryCache
(
int
size
)
{
return
new
MemoryCache
(
false
,
size
);
public
static
<
K
,
V
>
Cache
<
K
,
V
>
newHardMemoryCache
(
int
size
)
{
return
new
MemoryCache
<>
(
false
,
size
);
}
/**
* Return a dummy cache that does nothing.
*/
public
static
Cache
newNullCache
()
{
return
NullCache
.
INSTANCE
;
@SuppressWarnings
(
"unchecked"
)
public
static
<
K
,
V
>
Cache
<
K
,
V
>
newNullCache
()
{
return
(
Cache
<
K
,
V
>)
NullCache
.
INSTANCE
;
}
/**
...
...
@@ -152,8 +153,8 @@ public abstract class Cache {
* specified maximum lifetime (in seconds), with the values held
* by standard references.
*/
public
static
Cache
newHardMemoryCache
(
int
size
,
int
timeout
)
{
return
new
MemoryCache
(
false
,
size
,
timeout
);
public
static
<
K
,
V
>
Cache
<
K
,
V
>
newHardMemoryCache
(
int
size
,
int
timeout
)
{
return
new
MemoryCache
<>
(
false
,
size
,
timeout
);
}
/**
...
...
@@ -193,15 +194,15 @@ public abstract class Cache {
}
}
public
interface
CacheVisitor
{
public
void
visit
(
Map
<
Object
,
Object
>
map
);
public
interface
CacheVisitor
<
K
,
V
>
{
public
void
visit
(
Map
<
K
,
V
>
map
);
}
}
class
NullCache
extends
Cache
{
class
NullCache
<
K
,
V
>
extends
Cache
<
K
,
V
>
{
final
static
Cache
INSTANCE
=
new
NullCache
();
final
static
Cache
<
Object
,
Object
>
INSTANCE
=
new
NullCache
<>
();
private
NullCache
()
{
// empty
...
...
@@ -215,11 +216,11 @@ class NullCache extends Cache {
// empty
}
public
void
put
(
Object
key
,
Object
value
)
{
public
void
put
(
K
key
,
V
value
)
{
// empty
}
public
Object
get
(
Object
key
)
{
public
V
get
(
Object
key
)
{
return
null
;
}
...
...
@@ -235,23 +236,26 @@ class NullCache extends Cache {
// empty
}
public
void
accept
(
CacheVisitor
visitor
)
{
public
void
accept
(
CacheVisitor
<
K
,
V
>
visitor
)
{
// empty
}
}
class
MemoryCache
extends
Cache
{
class
MemoryCache
<
K
,
V
>
extends
Cache
<
K
,
V
>
{
private
final
static
float
LOAD_FACTOR
=
0.75f
;
// XXXX
private
final
static
boolean
DEBUG
=
false
;
private
final
Map
<
Object
,
CacheEntry
>
cacheMap
;
private
final
Map
<
K
,
CacheEntry
<
K
,
V
>
>
cacheMap
;
private
int
maxSize
;
private
long
lifetime
;
private
final
ReferenceQueue
<
Object
>
queue
;
// ReferenceQueue is of type V instead of Cache<K,V>
// to allow SoftCacheEntry to extend SoftReference<V>
private
final
ReferenceQueue
<
V
>
queue
;
public
MemoryCache
(
boolean
soft
,
int
maxSize
)
{
this
(
soft
,
maxSize
,
0
);
...
...
@@ -260,10 +264,13 @@ class MemoryCache extends Cache {
public
MemoryCache
(
boolean
soft
,
int
maxSize
,
int
lifetime
)
{
this
.
maxSize
=
maxSize
;
this
.
lifetime
=
lifetime
*
1000
;
this
.
queue
=
soft
?
new
ReferenceQueue
<
Object
>()
:
null
;
if
(
soft
)
this
.
queue
=
new
ReferenceQueue
<>();
else
this
.
queue
=
null
;
int
buckets
=
(
int
)(
maxSize
/
LOAD_FACTOR
)
+
1
;
cacheMap
=
new
LinkedHashMap
<
Object
,
CacheEntry
>(
buckets
,
LOAD_FACTOR
,
true
);
cacheMap
=
new
LinkedHashMap
<>(
buckets
,
LOAD_FACTOR
,
true
);
}
/**
...
...
@@ -279,16 +286,17 @@ class MemoryCache extends Cache {
}
int
startSize
=
cacheMap
.
size
();
while
(
true
)
{
CacheEntry
entry
=
(
CacheEntry
)
queue
.
poll
();
@SuppressWarnings
(
"unchecked"
)
CacheEntry
<
K
,
V
>
entry
=
(
CacheEntry
<
K
,
V
>)
queue
.
poll
();
if
(
entry
==
null
)
{
break
;
}
Object
key
=
entry
.
getKey
();
K
key
=
entry
.
getKey
();
if
(
key
==
null
)
{
// key is null, entry has already been removed
continue
;
}
CacheEntry
currentEntry
=
cacheMap
.
remove
(
key
);
CacheEntry
<
K
,
V
>
currentEntry
=
cacheMap
.
remove
(
key
);
// check if the entry in the map corresponds to the expired
// entry. If not, readd the entry
if
((
currentEntry
!=
null
)
&&
(
entry
!=
currentEntry
))
{
...
...
@@ -314,9 +322,9 @@ class MemoryCache extends Cache {
}
int
cnt
=
0
;
long
time
=
System
.
currentTimeMillis
();
for
(
Iterator
<
CacheEntry
>
t
=
cacheMap
.
values
().
iterator
();
for
(
Iterator
<
CacheEntry
<
K
,
V
>
>
t
=
cacheMap
.
values
().
iterator
();
t
.
hasNext
();
)
{
CacheEntry
entry
=
t
.
next
();
CacheEntry
<
K
,
V
>
entry
=
t
.
next
();
if
(
entry
.
isValid
(
time
)
==
false
)
{
t
.
remove
();
cnt
++;
...
...
@@ -339,7 +347,7 @@ class MemoryCache extends Cache {
if
(
queue
!=
null
)
{
// if this is a SoftReference cache, first invalidate() all
// entries so that GC does not have to enqueue them
for
(
CacheEntry
entry
:
cacheMap
.
values
())
{
for
(
CacheEntry
<
K
,
V
>
entry
:
cacheMap
.
values
())
{
entry
.
invalidate
();
}
while
(
queue
.
poll
()
!=
null
)
{
...
...
@@ -349,12 +357,12 @@ class MemoryCache extends Cache {
cacheMap
.
clear
();
}
public
synchronized
void
put
(
Object
key
,
Object
value
)
{
public
synchronized
void
put
(
K
key
,
V
value
)
{
emptyQueue
();
long
expirationTime
=
(
lifetime
==
0
)
?
0
:
System
.
currentTimeMillis
()
+
lifetime
;
CacheEntry
newEntry
=
newEntry
(
key
,
value
,
expirationTime
,
queue
);
CacheEntry
oldEntry
=
cacheMap
.
put
(
key
,
newEntry
);
CacheEntry
<
K
,
V
>
newEntry
=
newEntry
(
key
,
value
,
expirationTime
,
queue
);
CacheEntry
<
K
,
V
>
oldEntry
=
cacheMap
.
put
(
key
,
newEntry
);
if
(
oldEntry
!=
null
)
{
oldEntry
.
invalidate
();
return
;
...
...
@@ -362,8 +370,8 @@ class MemoryCache extends Cache {
if
(
maxSize
>
0
&&
cacheMap
.
size
()
>
maxSize
)
{
expungeExpiredEntries
();
if
(
cacheMap
.
size
()
>
maxSize
)
{
// still too large?
Iterator
<
CacheEntry
>
t
=
cacheMap
.
values
().
iterator
();
CacheEntry
lruEntry
=
t
.
next
();
Iterator
<
CacheEntry
<
K
,
V
>
>
t
=
cacheMap
.
values
().
iterator
();
CacheEntry
<
K
,
V
>
lruEntry
=
t
.
next
();
if
(
DEBUG
)
{
System
.
out
.
println
(
"** Overflow removal "
+
lruEntry
.
getKey
()
+
" | "
+
lruEntry
.
getValue
());
...
...
@@ -374,9 +382,9 @@ class MemoryCache extends Cache {
}
}
public
synchronized
Object
get
(
Object
key
)
{
public
synchronized
V
get
(
Object
key
)
{
emptyQueue
();
CacheEntry
entry
=
cacheMap
.
get
(
key
);
CacheEntry
<
K
,
V
>
entry
=
cacheMap
.
get
(
key
);
if
(
entry
==
null
)
{
return
null
;
}
...
...
@@ -393,7 +401,7 @@ class MemoryCache extends Cache {
public
synchronized
void
remove
(
Object
key
)
{
emptyQueue
();
CacheEntry
entry
=
cacheMap
.
remove
(
key
);
CacheEntry
<
K
,
V
>
entry
=
cacheMap
.
remove
(
key
);
if
(
entry
!=
null
)
{
entry
.
invalidate
();
}
...
...
@@ -402,9 +410,9 @@ class MemoryCache extends Cache {
public
synchronized
void
setCapacity
(
int
size
)
{
expungeExpiredEntries
();
if
(
size
>
0
&&
cacheMap
.
size
()
>
size
)
{
Iterator
<
CacheEntry
>
t
=
cacheMap
.
values
().
iterator
();
Iterator
<
CacheEntry
<
K
,
V
>
>
t
=
cacheMap
.
values
().
iterator
();
for
(
int
i
=
cacheMap
.
size
()
-
size
;
i
>
0
;
i
--)
{
CacheEntry
lruEntry
=
t
.
next
();
CacheEntry
<
K
,
V
>
lruEntry
=
t
.
next
();
if
(
DEBUG
)
{
System
.
out
.
println
(
"** capacity reset removal "
+
lruEntry
.
getKey
()
+
" | "
+
lruEntry
.
getValue
());
...
...
@@ -431,60 +439,61 @@ class MemoryCache extends Cache {
}
// it is a heavyweight method.
public
synchronized
void
accept
(
CacheVisitor
visitor
)
{
public
synchronized
void
accept
(
CacheVisitor
<
K
,
V
>
visitor
)
{
expungeExpiredEntries
();
Map
<
Object
,
Object
>
cached
=
getCachedEntries
();
Map
<
K
,
V
>
cached
=
getCachedEntries
();
visitor
.
visit
(
cached
);
}
private
Map
<
Object
,
Object
>
getCachedEntries
()
{
Map
<
Object
,
Object
>
kvmap
=
new
HashMap
<
Object
,
Object
>(
cacheMap
.
size
());
private
Map
<
K
,
V
>
getCachedEntries
()
{
Map
<
K
,
V
>
kvmap
=
new
HashMap
<
>(
cacheMap
.
size
());
for
(
CacheEntry
entry
:
cacheMap
.
values
())
{
for
(
CacheEntry
<
K
,
V
>
entry
:
cacheMap
.
values
())
{
kvmap
.
put
(
entry
.
getKey
(),
entry
.
getValue
());
}
return
kvmap
;
}
protected
CacheEntry
newEntry
(
Object
key
,
Object
value
,
long
expirationTime
,
ReferenceQueue
<
Object
>
queue
)
{
protected
CacheEntry
<
K
,
V
>
newEntry
(
K
key
,
V
value
,
long
expirationTime
,
ReferenceQueue
<
V
>
queue
)
{
if
(
queue
!=
null
)
{
return
new
SoftCacheEntry
(
key
,
value
,
expirationTime
,
queue
);
return
new
SoftCacheEntry
<>
(
key
,
value
,
expirationTime
,
queue
);
}
else
{
return
new
HardCacheEntry
(
key
,
value
,
expirationTime
);
return
new
HardCacheEntry
<>
(
key
,
value
,
expirationTime
);
}
}
private
static
interface
CacheEntry
{
private
static
interface
CacheEntry
<
K
,
V
>
{
boolean
isValid
(
long
currentTime
);
void
invalidate
();
Object
getKey
();
K
getKey
();
Object
getValue
();
V
getValue
();
}
private
static
class
HardCacheEntry
implements
CacheEntry
{
private
static
class
HardCacheEntry
<
K
,
V
>
implements
CacheEntry
<
K
,
V
>
{
private
Object
key
,
value
;
private
K
key
;
private
V
value
;
private
long
expirationTime
;
HardCacheEntry
(
Object
key
,
Object
value
,
long
expirationTime
)
{
HardCacheEntry
(
K
key
,
V
value
,
long
expirationTime
)
{
this
.
key
=
key
;
this
.
value
=
value
;
this
.
expirationTime
=
expirationTime
;
}
public
Object
getKey
()
{
public
K
getKey
()
{
return
key
;
}
public
Object
getValue
()
{
public
V
getValue
()
{
return
value
;
}
...
...
@@ -503,24 +512,25 @@ class MemoryCache extends Cache {
}
}
private
static
class
SoftCacheEntry
extends
SoftReference
<
Object
>
implements
CacheEntry
{
private
static
class
SoftCacheEntry
<
K
,
V
>
extends
SoftReference
<
V
>
implements
CacheEntry
<
K
,
V
>
{
private
Object
key
;
private
K
key
;
private
long
expirationTime
;
SoftCacheEntry
(
Object
key
,
Object
value
,
long
expirationTime
,
ReferenceQueue
<
Object
>
queue
)
{
SoftCacheEntry
(
K
key
,
V
value
,
long
expirationTime
,
ReferenceQueue
<
V
>
queue
)
{
super
(
value
,
queue
);
this
.
key
=
key
;
this
.
expirationTime
=
expirationTime
;
}
public
Object
getKey
()
{
public
K
getKey
()
{
return
key
;
}
public
Object
getValue
()
{
public
V
getValue
()
{
return
get
();
}
...
...
test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/SSLEngineBadBufferArrayAccess.java
0 → 100644
浏览文件 @
81eccafb
/*
* Copyright (c) 2011, 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.
*/
/*
* @test
* @bug 7031830
* @summary bad_record_mac failure on TLSv1.2 enabled connection with SSLEngine
* @run main/othervm SSLEngineBadBufferArrayAccess
*
* SunJSSE does not support dynamic system properties, no way to re-use
* system properties in samevm/agentvm mode.
*/
/**
* A SSLSocket/SSLEngine interop test case. This is not the way to
* code SSLEngine-based servers, but works for what we need to do here,
* which is to make sure that SSLEngine/SSLSockets can talk to each other.
* SSLEngines can use direct or indirect buffers, and different code
* is used to get at the buffer contents internally, so we test that here.
*
* The test creates one SSLSocket (client) and one SSLEngine (server).
* The SSLSocket talks to a raw ServerSocket, and the server code
* does the translation between byte [] and ByteBuffers that the SSLEngine
* can use. The "transport" layer consists of a Socket Input/OutputStream
* and two byte buffers for the SSLEngines: think of them
* as directly connected pipes.
*
* Again, this is a *very* simple example: real code will be much more
* involved. For example, different threading and I/O models could be
* used, transport mechanisms could close unexpectedly, and so on.
*
* When this application runs, notice that several messages
* (wrap/unwrap) pass before any application data is consumed or
* produced. (For more information, please see the SSL/TLS
* specifications.) There may several steps for a successful handshake,
* so it's typical to see the following series of operations:
*
* client server message
* ====== ====== =======
* write() ... ClientHello
* ... unwrap() ClientHello
* ... wrap() ServerHello/Certificate
* read() ... ServerHello/Certificate
* write() ... ClientKeyExchange
* write() ... ChangeCipherSpec
* write() ... Finished
* ... unwrap() ClientKeyExchange
* ... unwrap() ChangeCipherSpec
* ... unwrap() Finished
* ... wrap() ChangeCipherSpec
* ... wrap() Finished
* read() ... ChangeCipherSpec
* read() ... Finished
*
* This particular bug had a problem where byte buffers backed by an
* array didn't offset correctly, and we got bad MAC errors.
*/
import
javax.net.ssl.*
;
import
javax.net.ssl.SSLEngineResult.*
;
import
java.io.*
;
import
java.net.*
;
import
java.security.*
;
import
java.nio.*
;
public
class
SSLEngineBadBufferArrayAccess
{
/*
* Enables logging of the SSL/TLS operations.
*/
private
static
boolean
logging
=
true
;
/*
* Enables the JSSE system debugging system property:
*
* -Djavax.net.debug=all
*
* This gives a lot of low-level information about operations underway,
* including specific handshake messages, and might be best examined
* after gaining some familiarity with this application.
*/
private
static
boolean
debug
=
false
;
private
SSLContext
sslc
;
private
SSLEngine
serverEngine
;
// server-side SSLEngine
private
SSLSocket
sslSocket
;
// client-side socket
private
ServerSocket
serverSocket
;
// server-side Socket, generates the...
private
Socket
socket
;
// server-side socket that will read
private
final
byte
[]
serverMsg
=
"Hi there Client, I'm a Server"
.
getBytes
();
private
final
byte
[]
clientMsg
=
"Hello Server, I'm a Client"
.
getBytes
();
private
ByteBuffer
serverOut
;
// write side of serverEngine
private
ByteBuffer
serverIn
;
// read side of serverEngine
private
volatile
Exception
clientException
;
private
volatile
Exception
serverException
;
/*
* For data transport, this example uses local ByteBuffers.
*/
private
ByteBuffer
cTOs
;
// "reliable" transport client->server
private
ByteBuffer
sTOc
;
// "reliable" transport server->client
/*
* The following is to set up the keystores/trust material.
*/
private
static
final
String
pathToStores
=
"../../../../../../../etc/"
;
private
static
final
String
keyStoreFile
=
"keystore"
;
private
static
final
String
trustStoreFile
=
"truststore"
;
private
static
final
String
passwd
=
"passphrase"
;
private
static
String
keyFilename
=
System
.
getProperty
(
"test.src"
,
"."
)
+
"/"
+
pathToStores
+
"/"
+
keyStoreFile
;
private
static
String
trustFilename
=
System
.
getProperty
(
"test.src"
,
"."
)
+
"/"
+
pathToStores
+
"/"
+
trustStoreFile
;
/*
* Main entry point for this test.
*/
public
static
void
main
(
String
args
[])
throws
Exception
{
if
(
debug
)
{
System
.
setProperty
(
"javax.net.debug"
,
"all"
);
}
String
[]
protocols
=
new
String
[]
{
"SSLv3"
,
"TLSv1"
,
"TLSv1.1"
,
"TLSv1.2"
};
for
(
String
protocol
:
protocols
)
{
log
(
"Testing "
+
protocol
);
/*
* Run the tests with direct and indirect buffers.
*/
SSLEngineBadBufferArrayAccess
test
=
new
SSLEngineBadBufferArrayAccess
(
protocol
);
test
.
runTest
(
true
);
test
.
runTest
(
false
);
}
System
.
out
.
println
(
"Test Passed."
);
}
/*
* Create an initialized SSLContext to use for these tests.
*/
public
SSLEngineBadBufferArrayAccess
(
String
protocol
)
throws
Exception
{
KeyStore
ks
=
KeyStore
.
getInstance
(
"JKS"
);
KeyStore
ts
=
KeyStore
.
getInstance
(
"JKS"
);
char
[]
passphrase
=
"passphrase"
.
toCharArray
();
ks
.
load
(
new
FileInputStream
(
keyFilename
),
passphrase
);
ts
.
load
(
new
FileInputStream
(
trustFilename
),
passphrase
);
KeyManagerFactory
kmf
=
KeyManagerFactory
.
getInstance
(
"SunX509"
);
kmf
.
init
(
ks
,
passphrase
);
TrustManagerFactory
tmf
=
TrustManagerFactory
.
getInstance
(
"SunX509"
);
tmf
.
init
(
ts
);
SSLContext
sslCtx
=
SSLContext
.
getInstance
(
protocol
);
sslCtx
.
init
(
kmf
.
getKeyManagers
(),
tmf
.
getTrustManagers
(),
null
);
sslc
=
sslCtx
;
}
/*
* Run the test.
*
* Sit in a tight loop, with the server engine calling wrap/unwrap
* regardless of whether data is available or not. We do this until
* we get the application data. Then we shutdown and go to the next one.
*
* The main loop handles all of the I/O phases of the SSLEngine's
* lifetime:
*
* initial handshaking
* application data transfer
* engine closing
*
* One could easily separate these phases into separate
* sections of code.
*/
private
void
runTest
(
boolean
direct
)
throws
Exception
{
boolean
serverClose
=
direct
;
serverSocket
=
new
ServerSocket
(
0
);
int
port
=
serverSocket
.
getLocalPort
();
Thread
thread
=
createClientThread
(
port
,
serverClose
);
socket
=
serverSocket
.
accept
();
socket
.
setSoTimeout
(
500
);
serverSocket
.
close
();
createSSLEngine
();
createBuffers
(
direct
);
try
{
boolean
closed
=
false
;
InputStream
is
=
socket
.
getInputStream
();
OutputStream
os
=
socket
.
getOutputStream
();
SSLEngineResult
serverResult
;
// results from last operation
/*
* Examining the SSLEngineResults could be much more involved,
* and may alter the overall flow of the application.
*
* For example, if we received a BUFFER_OVERFLOW when trying
* to write to the output pipe, we could reallocate a larger
* pipe, but instead we wait for the peer to drain it.
*/
byte
[]
inbound
=
new
byte
[
8192
];
byte
[]
outbound
=
new
byte
[
8192
];
while
(!
isEngineClosed
(
serverEngine
))
{
int
len
=
0
;
// Inbound data
log
(
"================"
);
// Read from the Client side.
try
{
len
=
is
.
read
(
inbound
);
if
(
len
==
-
1
)
{
throw
new
Exception
(
"Unexpected EOF"
);
}
cTOs
.
put
(
inbound
,
0
,
len
);
}
catch
(
SocketTimeoutException
ste
)
{
// swallow. Nothing yet, probably waiting on us.
}
cTOs
.
flip
();
serverResult
=
serverEngine
.
unwrap
(
cTOs
,
serverIn
);
log
(
"server unwrap: "
,
serverResult
);
runDelegatedTasks
(
serverResult
,
serverEngine
);
cTOs
.
compact
();
// Outbound data
log
(
"----"
);
serverResult
=
serverEngine
.
wrap
(
serverOut
,
sTOc
);
log
(
"server wrap: "
,
serverResult
);
runDelegatedTasks
(
serverResult
,
serverEngine
);
sTOc
.
flip
();
if
((
len
=
sTOc
.
remaining
())
!=
0
)
{
sTOc
.
get
(
outbound
,
0
,
len
);
os
.
write
(
outbound
,
0
,
len
);
// Give the other side a chance to process
}
sTOc
.
compact
();
if
(!
closed
&&
(
serverOut
.
remaining
()
==
0
))
{
closed
=
true
;
/*
* We'll alternate initiatating the shutdown.
* When the server initiates, it will take one more
* loop, but tests the orderly shutdown.
*/
if
(
serverClose
)
{
serverEngine
.
closeOutbound
();
}
serverIn
.
flip
();
/*
* A sanity check to ensure we got what was sent.
*/
if
(
serverIn
.
remaining
()
!=
clientMsg
.
length
)
{
throw
new
Exception
(
"Client: Data length error"
);
}
for
(
int
i
=
0
;
i
<
clientMsg
.
length
;
i
++)
{
if
(
clientMsg
[
i
]
!=
serverIn
.
get
())
{
throw
new
Exception
(
"Client: Data content error"
);
}
}
serverIn
.
compact
();
}
}
return
;
}
catch
(
Exception
e
)
{
serverException
=
e
;
}
finally
{
socket
.
close
();
// Wait for the client to join up with us.
thread
.
join
();
if
(
serverException
!=
null
)
{
throw
serverException
;
}
if
(
clientException
!=
null
)
{
throw
clientException
;
}
}
}
/*
* Create a client thread which does simple SSLSocket operations.
* We'll write and read one data packet.
*/
private
Thread
createClientThread
(
final
int
port
,
final
boolean
serverClose
)
throws
Exception
{
Thread
t
=
new
Thread
(
"ClientThread"
)
{
@Override
public
void
run
()
{
try
{
Thread
.
sleep
(
1000
);
// Give server time to finish setup.
sslSocket
=
(
SSLSocket
)
sslc
.
getSocketFactory
().
createSocket
(
"localhost"
,
port
);
OutputStream
os
=
sslSocket
.
getOutputStream
();
InputStream
is
=
sslSocket
.
getInputStream
();
// write(byte[]) goes in one shot.
os
.
write
(
clientMsg
);
byte
[]
inbound
=
new
byte
[
2048
];
int
pos
=
0
;
int
len
;
done:
while
((
len
=
is
.
read
(
inbound
,
pos
,
2048
-
pos
))
!=
-
1
)
{
pos
+=
len
;
// Let the client do the closing.
if
((
pos
==
serverMsg
.
length
)
&&
!
serverClose
)
{
sslSocket
.
close
();
break
done
;
}
}
if
(
pos
!=
serverMsg
.
length
)
{
throw
new
Exception
(
"Client: Data length error"
);
}
for
(
int
i
=
0
;
i
<
serverMsg
.
length
;
i
++)
{
if
(
inbound
[
i
]
!=
serverMsg
[
i
])
{
throw
new
Exception
(
"Client: Data content error"
);
}
}
}
catch
(
Exception
e
)
{
clientException
=
e
;
}
}
};
t
.
start
();
return
t
;
}
/*
* Using the SSLContext created during object creation,
* create/configure the SSLEngines we'll use for this test.
*/
private
void
createSSLEngine
()
throws
Exception
{
/*
* Configure the serverEngine to act as a server in the SSL/TLS
* handshake.
*/
serverEngine
=
sslc
.
createSSLEngine
();
serverEngine
.
setUseClientMode
(
false
);
serverEngine
.
getNeedClientAuth
();
}
/*
* Create and size the buffers appropriately.
*/
private
void
createBuffers
(
boolean
direct
)
{
SSLSession
session
=
serverEngine
.
getSession
();
int
appBufferMax
=
session
.
getApplicationBufferSize
();
int
netBufferMax
=
session
.
getPacketBufferSize
();
/*
* We'll make the input buffers a bit bigger than the max needed
* size, so that unwrap()s following a successful data transfer
* won't generate BUFFER_OVERFLOWS.
*
* We'll use a mix of direct and indirect ByteBuffers for
* tutorial purposes only. In reality, only use direct
* ByteBuffers when they give a clear performance enhancement.
*/
if
(
direct
)
{
serverIn
=
ByteBuffer
.
allocateDirect
(
appBufferMax
+
50
);
cTOs
=
ByteBuffer
.
allocateDirect
(
netBufferMax
);
sTOc
=
ByteBuffer
.
allocateDirect
(
netBufferMax
);
}
else
{
serverIn
=
ByteBuffer
.
allocate
(
appBufferMax
+
50
);
cTOs
=
ByteBuffer
.
allocate
(
netBufferMax
);
sTOc
=
ByteBuffer
.
allocate
(
netBufferMax
);
}
serverOut
=
ByteBuffer
.
wrap
(
serverMsg
);
}
/*
* If the result indicates that we have outstanding tasks to do,
* go ahead and run them in this thread.
*/
private
static
void
runDelegatedTasks
(
SSLEngineResult
result
,
SSLEngine
engine
)
throws
Exception
{
if
(
result
.
getHandshakeStatus
()
==
HandshakeStatus
.
NEED_TASK
)
{
Runnable
runnable
;
while
((
runnable
=
engine
.
getDelegatedTask
())
!=
null
)
{
log
(
"\trunning delegated task..."
);
runnable
.
run
();
}
HandshakeStatus
hsStatus
=
engine
.
getHandshakeStatus
();
if
(
hsStatus
==
HandshakeStatus
.
NEED_TASK
)
{
throw
new
Exception
(
"handshake shouldn't need additional tasks"
);
}
log
(
"\tnew HandshakeStatus: "
+
hsStatus
);
}
}
private
static
boolean
isEngineClosed
(
SSLEngine
engine
)
{
return
(
engine
.
isOutboundDone
()
&&
engine
.
isInboundDone
());
}
/*
* Logging code
*/
private
static
boolean
resultOnce
=
true
;
private
static
void
log
(
String
str
,
SSLEngineResult
result
)
{
if
(!
logging
)
{
return
;
}
if
(
resultOnce
)
{
resultOnce
=
false
;
System
.
out
.
println
(
"The format of the SSLEngineResult is: \n"
+
"\t\"getStatus() / getHandshakeStatus()\" +\n"
+
"\t\"bytesConsumed() / bytesProduced()\"\n"
);
}
HandshakeStatus
hsStatus
=
result
.
getHandshakeStatus
();
log
(
str
+
result
.
getStatus
()
+
"/"
+
hsStatus
+
", "
+
result
.
bytesConsumed
()
+
"/"
+
result
.
bytesProduced
()
+
" bytes"
);
if
(
hsStatus
==
HandshakeStatus
.
FINISHED
)
{
log
(
"\t...ready for application data"
);
}
}
private
static
void
log
(
String
str
)
{
if
(
logging
)
{
System
.
out
.
println
(
str
);
}
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录