Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_jdk
提交
4c79d01a
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看板
提交
4c79d01a
编写于
10月 19, 2011
作者:
M
mullan
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
7102686: Restructure timestamp code so that jars and modules can more easily share the same code
Reviewed-by: mchung
上级
f0bc2fbe
变更
9
隐藏空白更改
内联
并排
Showing
9 changed file
with
379 addition
and
406 deletion
+379
-406
src/share/classes/sun/security/pkcs/PKCS7.java
src/share/classes/sun/security/pkcs/PKCS7.java
+186
-0
src/share/classes/sun/security/pkcs/SignerInfo.java
src/share/classes/sun/security/pkcs/SignerInfo.java
+62
-1
src/share/classes/sun/security/timestamp/HttpTimestamper.java
...share/classes/sun/security/timestamp/HttpTimestamper.java
+27
-24
src/share/classes/sun/security/timestamp/TSRequest.java
src/share/classes/sun/security/timestamp/TSRequest.java
+17
-40
src/share/classes/sun/security/timestamp/TSResponse.java
src/share/classes/sun/security/timestamp/TSResponse.java
+60
-55
src/share/classes/sun/security/tools/JarSigner.java
src/share/classes/sun/security/tools/JarSigner.java
+3
-4
src/share/classes/sun/security/tools/TimestampedSigner.java
src/share/classes/sun/security/tools/TimestampedSigner.java
+21
-223
src/share/classes/sun/security/util/Debug.java
src/share/classes/sun/security/util/Debug.java
+2
-1
src/share/classes/sun/security/util/SignatureFileVerifier.java
...hare/classes/sun/security/util/SignatureFileVerifier.java
+1
-58
未找到文件。
src/share/classes/sun/security/pkcs/PKCS7.java
浏览文件 @
4c79d01a
...
...
@@ -27,6 +27,7 @@ package sun.security.pkcs;
import
java.io.*
;
import
java.math.BigInteger
;
import
java.net.URI
;
import
java.util.*
;
import
java.security.cert.X509Certificate
;
import
java.security.cert.CertificateException
;
...
...
@@ -35,6 +36,7 @@ import java.security.cert.CRLException;
import
java.security.cert.CertificateFactory
;
import
java.security.*
;
import
sun.security.timestamp.*
;
import
sun.security.util.*
;
import
sun.security.x509.AlgorithmId
;
import
sun.security.x509.CertificateIssuerName
;
...
...
@@ -68,6 +70,30 @@ public class PKCS7 {
private
Principal
[]
certIssuerNames
;
/*
* Random number generator for creating nonce values
*/
private
static
final
SecureRandom
RANDOM
;
static
{
SecureRandom
tmp
=
null
;
try
{
tmp
=
SecureRandom
.
getInstance
(
"SHA1PRNG"
);
}
catch
(
NoSuchAlgorithmException
e
)
{
// should not happen
}
RANDOM
=
tmp
;
}
/*
* Object identifier for the timestamping key purpose.
*/
private
static
final
String
KP_TIMESTAMPING_OID
=
"1.3.6.1.5.5.7.3.8"
;
/*
* Object identifier for extendedKeyUsage extension
*/
private
static
final
String
EXTENDED_KEY_USAGE_OID
=
"2.5.29.37"
;
/**
* Unmarshals a PKCS7 block from its encoded form, parsing the
* encoded bytes from the InputStream.
...
...
@@ -733,4 +759,164 @@ public class PKCS7 {
public
boolean
isOldStyle
()
{
return
this
.
oldStyle
;
}
/**
* Assembles a PKCS #7 signed data message that optionally includes a
* signature timestamp.
*
* @param signature the signature bytes
* @param signerChain the signer's X.509 certificate chain
* @param content the content that is signed; specify null to not include
* it in the PKCS7 data
* @param signatureAlgorithm the name of the signature algorithm
* @param tsaURI the URI of the Timestamping Authority; or null if no
* timestamp is requested
* @return the bytes of the encoded PKCS #7 signed data message
* @throws NoSuchAlgorithmException The exception is thrown if the signature
* algorithm is unrecognised.
* @throws CertificateException The exception is thrown if an error occurs
* while processing the signer's certificate or the TSA's
* certificate.
* @throws IOException The exception is thrown if an error occurs while
* generating the signature timestamp or while generating the signed
* data message.
*/
public
static
byte
[]
generateSignedData
(
byte
[]
signature
,
X509Certificate
[]
signerChain
,
byte
[]
content
,
String
signatureAlgorithm
,
URI
tsaURI
)
throws
CertificateException
,
IOException
,
NoSuchAlgorithmException
{
// Generate the timestamp token
PKCS9Attributes
unauthAttrs
=
null
;
if
(
tsaURI
!=
null
)
{
// Timestamp the signature
HttpTimestamper
tsa
=
new
HttpTimestamper
(
tsaURI
);
byte
[]
tsToken
=
generateTimestampToken
(
tsa
,
signature
);
// Insert the timestamp token into the PKCS #7 signer info element
// (as an unsigned attribute)
unauthAttrs
=
new
PKCS9Attributes
(
new
PKCS9Attribute
[]{
new
PKCS9Attribute
(
PKCS9Attribute
.
SIGNATURE_TIMESTAMP_TOKEN_STR
,
tsToken
)});
}
// Create the SignerInfo
X500Name
issuerName
=
X500Name
.
asX500Name
(
signerChain
[
0
].
getIssuerX500Principal
());
BigInteger
serialNumber
=
signerChain
[
0
].
getSerialNumber
();
String
encAlg
=
AlgorithmId
.
getEncAlgFromSigAlg
(
signatureAlgorithm
);
String
digAlg
=
AlgorithmId
.
getDigAlgFromSigAlg
(
signatureAlgorithm
);
SignerInfo
signerInfo
=
new
SignerInfo
(
issuerName
,
serialNumber
,
AlgorithmId
.
get
(
digAlg
),
null
,
AlgorithmId
.
get
(
encAlg
),
signature
,
unauthAttrs
);
// Create the PKCS #7 signed data message
SignerInfo
[]
signerInfos
=
{
signerInfo
};
AlgorithmId
[]
algorithms
=
{
signerInfo
.
getDigestAlgorithmId
()};
// Include or exclude content
ContentInfo
contentInfo
=
(
content
==
null
)
?
new
ContentInfo
(
ContentInfo
.
DATA_OID
,
null
)
:
new
ContentInfo
(
content
);
PKCS7
pkcs7
=
new
PKCS7
(
algorithms
,
contentInfo
,
signerChain
,
signerInfos
);
ByteArrayOutputStream
p7out
=
new
ByteArrayOutputStream
();
pkcs7
.
encodeSignedData
(
p7out
);
return
p7out
.
toByteArray
();
}
/**
* Requests, processes and validates a timestamp token from a TSA using
* common defaults. Uses the following defaults in the timestamp request:
* SHA-1 for the hash algorithm, a 64-bit nonce, and request certificate
* set to true.
*
* @param tsa the timestamping authority to use
* @param toBeTimestamped the token that is to be timestamped
* @return the encoded timestamp token
* @throws IOException The exception is thrown if an error occurs while
* communicating with the TSA.
* @throws CertificateException The exception is thrown if the TSA's
* certificate is not permitted for timestamping.
*/
private
static
byte
[]
generateTimestampToken
(
Timestamper
tsa
,
byte
[]
toBeTimestamped
)
throws
IOException
,
CertificateException
{
// Generate a timestamp
MessageDigest
messageDigest
=
null
;
TSRequest
tsQuery
=
null
;
try
{
// SHA-1 is always used.
messageDigest
=
MessageDigest
.
getInstance
(
"SHA-1"
);
tsQuery
=
new
TSRequest
(
toBeTimestamped
,
messageDigest
);
}
catch
(
NoSuchAlgorithmException
e
)
{
// ignore
}
// Generate a nonce
BigInteger
nonce
=
null
;
if
(
RANDOM
!=
null
)
{
nonce
=
new
BigInteger
(
64
,
RANDOM
);
tsQuery
.
setNonce
(
nonce
);
}
tsQuery
.
requestCertificate
(
true
);
TSResponse
tsReply
=
tsa
.
generateTimestamp
(
tsQuery
);
int
status
=
tsReply
.
getStatusCode
();
// Handle TSP error
if
(
status
!=
0
&&
status
!=
1
)
{
throw
new
IOException
(
"Error generating timestamp: "
+
tsReply
.
getStatusCodeAsText
()
+
" "
+
tsReply
.
getFailureCodeAsText
());
}
PKCS7
tsToken
=
tsReply
.
getToken
();
TimestampToken
tst
=
tsReply
.
getTimestampToken
();
if
(!
tst
.
getHashAlgorithm
().
getName
().
equals
(
"SHA"
))
{
throw
new
IOException
(
"Digest algorithm not SHA-1 in "
+
"timestamp token"
);
}
if
(!
MessageDigest
.
isEqual
(
tst
.
getHashedMessage
(),
tsQuery
.
getHashedMessage
()))
{
throw
new
IOException
(
"Digest octets changed in timestamp token"
);
}
BigInteger
replyNonce
=
tst
.
getNonce
();
if
(
replyNonce
==
null
&&
nonce
!=
null
)
{
throw
new
IOException
(
"Nonce missing in timestamp token"
);
}
if
(
replyNonce
!=
null
&&
!
replyNonce
.
equals
(
nonce
))
{
throw
new
IOException
(
"Nonce changed in timestamp token"
);
}
// Examine the TSA's certificate (if present)
for
(
SignerInfo
si:
tsToken
.
getSignerInfos
())
{
X509Certificate
cert
=
si
.
getCertificate
(
tsToken
);
if
(
cert
==
null
)
{
// Error, we've already set tsRequestCertificate = true
throw
new
CertificateException
(
"Certificate not included in timestamp token"
);
}
else
{
if
(!
cert
.
getCriticalExtensionOIDs
().
contains
(
EXTENDED_KEY_USAGE_OID
))
{
throw
new
CertificateException
(
"Certificate is not valid for timestamping"
);
}
List
<
String
>
keyPurposes
=
cert
.
getExtendedKeyUsage
();
if
(
keyPurposes
==
null
||
!
keyPurposes
.
contains
(
KP_TIMESTAMPING_OID
))
{
throw
new
CertificateException
(
"Certificate is not valid for timestamping"
);
}
}
}
return
tsReply
.
getEncodedToken
();
}
}
src/share/classes/sun/security/pkcs/SignerInfo.java
浏览文件 @
4c79d01a
...
...
@@ -28,10 +28,14 @@ package sun.security.pkcs;
import
java.io.OutputStream
;
import
java.io.IOException
;
import
java.math.BigInteger
;
import
java.security.cert.CertificateException
;
import
java.security.cert.CertificateFactory
;
import
java.security.cert.CertPath
;
import
java.security.cert.X509Certificate
;
import
java.security.*
;
import
java.util.ArrayList
;
import
sun.security.timestamp.TimestampToken
;
import
sun.security.util.*
;
import
sun.security.x509.AlgorithmId
;
import
sun.security.x509.X500Name
;
...
...
@@ -51,6 +55,8 @@ public class SignerInfo implements DerEncoder {
AlgorithmId
digestAlgorithmId
;
AlgorithmId
digestEncryptionAlgorithmId
;
byte
[]
encryptedDigest
;
Timestamp
timestamp
;
private
boolean
hasTimestamp
=
true
;
PKCS9Attributes
authenticatedAttributes
;
PKCS9Attributes
unauthenticatedAttributes
;
...
...
@@ -442,6 +448,62 @@ public class SignerInfo implements DerEncoder {
return
unauthenticatedAttributes
;
}
/*
* Extracts a timestamp from a PKCS7 SignerInfo.
*
* Examines the signer's unsigned attributes for a
* <tt>signatureTimestampToken</tt> attribute. If present,
* then it is parsed to extract the date and time at which the
* timestamp was generated.
*
* @param info A signer information element of a PKCS 7 block.
*
* @return A timestamp token or null if none is present.
* @throws IOException if an error is encountered while parsing the
* PKCS7 data.
* @throws NoSuchAlgorithmException if an error is encountered while
* verifying the PKCS7 object.
* @throws SignatureException if an error is encountered while
* verifying the PKCS7 object.
* @throws CertificateException if an error is encountered while generating
* the TSA's certpath.
*/
public
Timestamp
getTimestamp
()
throws
IOException
,
NoSuchAlgorithmException
,
SignatureException
,
CertificateException
{
if
(
timestamp
!=
null
||
!
hasTimestamp
)
return
timestamp
;
if
(
unauthenticatedAttributes
==
null
)
{
hasTimestamp
=
false
;
return
null
;
}
PKCS9Attribute
tsTokenAttr
=
unauthenticatedAttributes
.
getAttribute
(
PKCS9Attribute
.
SIGNATURE_TIMESTAMP_TOKEN_OID
);
if
(
tsTokenAttr
==
null
)
{
hasTimestamp
=
false
;
return
null
;
}
PKCS7
tsToken
=
new
PKCS7
((
byte
[])
tsTokenAttr
.
getValue
());
// Extract the content (an encoded timestamp token info)
byte
[]
encTsTokenInfo
=
tsToken
.
getContentInfo
().
getData
();
// Extract the signer (the Timestamping Authority)
// while verifying the content
SignerInfo
[]
tsa
=
tsToken
.
verify
(
encTsTokenInfo
);
// Expect only one signer
ArrayList
<
X509Certificate
>
chain
=
tsa
[
0
].
getCertificateChain
(
tsToken
);
CertificateFactory
cf
=
CertificateFactory
.
getInstance
(
"X.509"
);
CertPath
tsaChain
=
cf
.
generateCertPath
(
chain
);
// Create a timestamp token info object
TimestampToken
tsTokenInfo
=
new
TimestampToken
(
encTsTokenInfo
);
// Create a timestamp object
timestamp
=
new
Timestamp
(
tsTokenInfo
.
getDate
(),
tsaChain
);
return
timestamp
;
}
public
String
toString
()
{
HexDumpEncoder
hexDump
=
new
HexDumpEncoder
();
...
...
@@ -467,5 +529,4 @@ public class SignerInfo implements DerEncoder {
}
return
out
;
}
}
src/share/classes/sun/security/timestamp/HttpTimestamper.java
浏览文件 @
4c79d01a
...
...
@@ -28,13 +28,13 @@ package sun.security.timestamp;
import
java.io.BufferedInputStream
;
import
java.io.DataOutputStream
;
import
java.io.IOException
;
import
java.net.URI
;
import
java.net.URL
;
import
java.net.HttpURLConnection
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Set
;
import
java.util.*
;
import
sun.misc.IOUtils
;
import
sun.security.util.Debug
;
/**
* A timestamper that communicates with a Timestamping Authority (TSA)
...
...
@@ -58,20 +58,23 @@ public class HttpTimestamper implements Timestamper {
private
static
final
String
TS_REPLY_MIME_TYPE
=
"application/timestamp-reply"
;
private
static
final
boolean
DEBUG
=
false
;
private
static
final
Debug
debug
=
Debug
.
getInstance
(
"ts"
)
;
/*
* HTTP UR
L
identifying the location of the TSA
* HTTP UR
I
identifying the location of the TSA
*/
private
String
tsaUrl
=
null
;
private
URI
tsaURI
=
null
;
/**
* Creates a timestamper that connects to the specified TSA.
*
* @param tsa The location of the TSA. It must be an HTTP URL.
* @param tsa The location of the TSA. It must be an HTTP URI.
* @throws IllegalArgumentException if tsaURI is not an HTTP URI
*/
public
HttpTimestamper
(
String
tsaUrl
)
{
this
.
tsaUrl
=
tsaUrl
;
public
HttpTimestamper
(
URI
tsaURI
)
{
if
(!
tsaURI
.
getScheme
().
equalsIgnoreCase
(
"http"
))
throw
new
IllegalArgumentException
(
"TSA must be an HTTP URI"
);
this
.
tsaURI
=
tsaURI
;
}
/**
...
...
@@ -85,7 +88,7 @@ public class HttpTimestamper implements Timestamper {
public
TSResponse
generateTimestamp
(
TSRequest
tsQuery
)
throws
IOException
{
HttpURLConnection
connection
=
(
HttpURLConnection
)
new
URL
(
tsaUrl
).
openConnection
();
(
HttpURLConnection
)
tsaURI
.
toURL
(
).
openConnection
();
connection
.
setDoOutput
(
true
);
connection
.
setUseCaches
(
false
);
// ignore cache
connection
.
setRequestProperty
(
"Content-Type"
,
TS_QUERY_MIME_TYPE
);
...
...
@@ -93,15 +96,15 @@ public class HttpTimestamper implements Timestamper {
// Avoids the "hang" when a proxy is required but none has been set.
connection
.
setConnectTimeout
(
CONNECT_TIMEOUT
);
if
(
DEBUG
)
{
if
(
debug
!=
null
)
{
Set
<
Map
.
Entry
<
String
,
List
<
String
>>>
headers
=
connection
.
getRequestProperties
().
entrySet
();
System
.
out
.
println
(
connection
.
getRequestMethod
()
+
" "
+
tsaUrl
+
connection
.
getRequestProperties
().
entrySet
();
debug
.
println
(
connection
.
getRequestMethod
()
+
" "
+
tsaURI
+
" HTTP/1.1"
);
for
(
Map
.
Entry
<
String
,
List
<
String
>>
e
ntry
:
headers
)
{
System
.
out
.
println
(
" "
+
entry
);
for
(
Map
.
Entry
<
String
,
List
<
String
>>
e
:
headers
)
{
debug
.
println
(
" "
+
e
);
}
System
.
out
.
println
();
debug
.
println
();
}
connection
.
connect
();
// No HTTP authentication is performed
...
...
@@ -112,8 +115,8 @@ public class HttpTimestamper implements Timestamper {
byte
[]
request
=
tsQuery
.
encode
();
output
.
write
(
request
,
0
,
request
.
length
);
output
.
flush
();
if
(
DEBUG
)
{
System
.
out
.
println
(
"sent timestamp query (length="
+
if
(
debug
!=
null
)
{
debug
.
println
(
"sent timestamp query (length="
+
request
.
length
+
")"
);
}
}
finally
{
...
...
@@ -127,17 +130,17 @@ public class HttpTimestamper implements Timestamper {
byte
[]
replyBuffer
=
null
;
try
{
input
=
new
BufferedInputStream
(
connection
.
getInputStream
());
if
(
DEBUG
)
{
if
(
debug
!=
null
)
{
String
header
=
connection
.
getHeaderField
(
0
);
System
.
out
.
println
(
header
);
debug
.
println
(
header
);
int
i
=
1
;
while
((
header
=
connection
.
getHeaderField
(
i
))
!=
null
)
{
String
key
=
connection
.
getHeaderFieldKey
(
i
);
System
.
out
.
println
(
" "
+
((
key
==
null
)
?
""
:
key
+
": "
)
+
debug
.
println
(
" "
+
((
key
==
null
)
?
""
:
key
+
": "
)
+
header
);
i
++;
}
System
.
out
.
println
();
debug
.
println
();
}
verifyMimeType
(
connection
.
getContentType
());
...
...
@@ -145,8 +148,8 @@ public class HttpTimestamper implements Timestamper {
int
contentLength
=
connection
.
getContentLength
();
replyBuffer
=
IOUtils
.
readFully
(
input
,
contentLength
,
false
);
if
(
DEBUG
)
{
System
.
out
.
println
(
"received timestamp response (length="
+
if
(
debug
!=
null
)
{
debug
.
println
(
"received timestamp response (length="
+
total
+
")"
);
}
}
finally
{
...
...
src/share/classes/sun/security/timestamp/TSRequest.java
浏览文件 @
4c79d01a
/*
* 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
...
...
@@ -27,10 +27,13 @@ package sun.security.timestamp;
import
java.io.IOException
;
import
java.math.BigInteger
;
import
java.security.MessageDigest
;
import
java.security.NoSuchAlgorithmException
;
import
java.security.cert.X509Extension
;
import
sun.security.util.DerValue
;
import
sun.security.util.DerOutputStream
;
import
sun.security.util.ObjectIdentifier
;
import
sun.security.x509.AlgorithmId
;
/**
* This class provides a timestamp request, as defined in
...
...
@@ -64,24 +67,9 @@ import sun.security.util.ObjectIdentifier;
public
class
TSRequest
{
private
static
final
ObjectIdentifier
SHA1_OID
;
private
static
final
ObjectIdentifier
MD5_OID
;
static
{
ObjectIdentifier
sha1
=
null
;
ObjectIdentifier
md5
=
null
;
try
{
sha1
=
new
ObjectIdentifier
(
"1.3.14.3.2.26"
);
md5
=
new
ObjectIdentifier
(
"1.2.840.113549.2.5"
);
}
catch
(
IOException
ioe
)
{
// should not happen
}
SHA1_OID
=
sha1
;
MD5_OID
=
md5
;
}
private
int
version
=
1
;
private
ObjectIdentifier
hashAlgorithmId
=
null
;
private
AlgorithmId
hashAlgorithmId
=
null
;
private
byte
[]
hashValue
;
...
...
@@ -94,30 +82,21 @@ public class TSRequest {
private
X509Extension
[]
extensions
=
null
;
/**
* Constructs a timestamp request for the supplied
hash value.
.
* Constructs a timestamp request for the supplied
data
.
*
* @param hashValue The hash value. This is the data to be timestamped.
* @param hashAlgorithm The name of the hash algorithm.
* @param toBeTimeStamped The data to be timestamped.
* @param messageDigest The MessageDigest of the hash algorithm to use.
* @throws NoSuchAlgorithmException if the hash algorithm is not supported
*/
public
TSRequest
(
byte
[]
hashValue
,
String
hashAlgorithm
)
{
public
TSRequest
(
byte
[]
toBeTimeStamped
,
MessageDigest
messageDigest
)
throws
NoSuchAlgorithmException
{
// Check the common hash algorithms
if
(
"MD5"
.
equalsIgnoreCase
(
hashAlgorithm
))
{
hashAlgorithmId
=
MD5_OID
;
// Check that the hash value matches the hash algorithm
assert
hashValue
.
length
==
16
;
}
else
if
(
"SHA-1"
.
equalsIgnoreCase
(
hashAlgorithm
)
||
"SHA"
.
equalsIgnoreCase
(
hashAlgorithm
)
||
"SHA1"
.
equalsIgnoreCase
(
hashAlgorithm
))
{
hashAlgorithmId
=
SHA1_OID
;
// Check that the hash value matches the hash algorithm
assert
hashValue
.
length
==
20
;
this
.
hashAlgorithmId
=
AlgorithmId
.
get
(
messageDigest
.
getAlgorithm
());
this
.
hashValue
=
messageDigest
.
digest
(
toBeTimeStamped
);
}
}
// Clone the hash value
this
.
hashValue
=
new
byte
[
hashValue
.
length
];
System
.
arraycopy
(
hashValue
,
0
,
this
.
hashValue
,
0
,
hashValue
.
length
);
public
byte
[]
getHashedMessage
()
{
return
hashValue
.
clone
();
}
/**
...
...
@@ -176,9 +155,7 @@ public class TSRequest {
// encode messageImprint
DerOutputStream
messageImprint
=
new
DerOutputStream
();
DerOutputStream
hashAlgorithm
=
new
DerOutputStream
();
hashAlgorithm
.
putOID
(
hashAlgorithmId
);
messageImprint
.
write
(
DerValue
.
tag_Sequence
,
hashAlgorithm
);
hashAlgorithmId
.
encode
(
messageImprint
);
messageImprint
.
putOctetString
(
hashValue
);
request
.
write
(
DerValue
.
tag_Sequence
,
messageImprint
);
...
...
src/share/classes/sun/security/timestamp/TSResponse.java
浏览文件 @
4c79d01a
...
...
@@ -27,6 +27,7 @@ package sun.security.timestamp;
import
java.io.IOException
;
import
sun.security.pkcs.PKCS7
;
import
sun.security.util.Debug
;
import
sun.security.util.DerValue
;
/**
...
...
@@ -175,18 +176,20 @@ public class TSResponse {
*/
public
static
final
int
SYSTEM_FAILURE
=
25
;
private
static
final
boolean
DEBUG
=
false
;
private
static
final
Debug
debug
=
Debug
.
getInstance
(
"ts"
)
;
private
int
status
;
private
String
[]
statusString
=
null
;
private
int
failureInfo
=
-
1
;
private
boolean
[]
failureInfo
=
null
;
private
byte
[]
encodedTsToken
=
null
;
private
PKCS7
tsToken
=
null
;
private
TimestampToken
tstInfo
;
/**
* Constructs an object to store the response to a timestamp request.
*
...
...
@@ -215,11 +218,11 @@ public class TSResponse {
}
/**
* Retrieve the failure
code
returned by the TSA.
* Retrieve the failure
info
returned by the TSA.
*
* @return
If -1 then
no failure code was received.
* @return
the failure info, or null if
no failure code was received.
*/
public
int
getFailureCode
()
{
public
boolean
[]
getFailureInfo
()
{
return
failureInfo
;
}
...
...
@@ -250,42 +253,38 @@ public class TSResponse {
}
}
private
boolean
isSet
(
int
position
)
{
return
failureInfo
[
position
];
}
public
String
getFailureCodeAsText
()
{
if
(
failureInfo
==
-
1
)
{
return
null
;
if
(
failureInfo
==
null
)
{
return
""
;
}
switch
(
failureInfo
)
{
case
BAD_ALG:
return
"Unrecognized or unsupported alrorithm identifier."
;
case
BAD_REQUEST:
return
"The requested transaction is not permitted or supported."
;
case
BAD_DATA_FORMAT:
return
"The data submitted has the wrong format."
;
case
TIME_NOT_AVAILABLE:
return
"The TSA's time source is not available."
;
case
UNACCEPTED_POLICY:
return
"The requested TSA policy is not supported by the TSA."
;
case
UNACCEPTED_EXTENSION:
return
"The requested extension is not supported by the TSA."
;
case
ADD_INFO_NOT_AVAILABLE:
return
"The additional information requested could not be "
+
"understood or is not available."
;
case
SYSTEM_FAILURE:
return
"The request cannot be handled due to system failure."
;
default
:
return
(
"unknown status code "
+
status
);
}
try
{
if
(
isSet
(
BAD_ALG
))
return
"Unrecognized or unsupported algorithm identifier."
;
if
(
isSet
(
BAD_REQUEST
))
return
"The requested transaction is not permitted or "
+
"supported."
;
if
(
isSet
(
BAD_DATA_FORMAT
))
return
"The data submitted has the wrong format."
;
if
(
isSet
(
TIME_NOT_AVAILABLE
))
return
"The TSA's time source is not available."
;
if
(
isSet
(
UNACCEPTED_POLICY
))
return
"The requested TSA policy is not supported by the TSA."
;
if
(
isSet
(
UNACCEPTED_EXTENSION
))
return
"The requested extension is not supported by the TSA."
;
if
(
isSet
(
ADD_INFO_NOT_AVAILABLE
))
return
"The additional information requested could not be "
+
"understood or is not available."
;
if
(
isSet
(
SYSTEM_FAILURE
))
return
"The request cannot be handled due to system failure."
;
}
catch
(
ArrayIndexOutOfBoundsException
ex
)
{}
return
(
"unknown failure code"
);
}
/**
...
...
@@ -297,6 +296,10 @@ public class TSResponse {
return
tsToken
;
}
public
TimestampToken
getTimestampToken
()
{
return
tstInfo
;
}
/**
* Retrieve the ASN.1 BER encoded timestamp token returned by the TSA.
*
...
...
@@ -323,29 +326,30 @@ public class TSResponse {
// Parse status
DerValue
status
=
derValue
.
data
.
getDerValue
();
// Parse status
this
.
status
=
status
.
data
.
getInteger
();
if
(
DEBUG
)
{
System
.
out
.
println
(
"timestamp response: status="
+
this
.
status
);
DerValue
statusInfo
=
derValue
.
data
.
getDerValue
();
this
.
status
=
statusInfo
.
data
.
getInteger
();
if
(
debug
!=
null
)
{
debug
.
println
(
"timestamp response: status="
+
this
.
status
);
}
// Parse statusString, if present
if
(
status
.
data
.
available
()
>
0
)
{
DerValue
[]
strings
=
status
.
data
.
getSequence
(
1
);
statusString
=
new
String
[
strings
.
length
];
for
(
int
i
=
0
;
i
<
strings
.
length
;
i
++)
{
statusString
[
i
]
=
strings
[
i
].
data
.
getUTF8String
();
if
(
statusInfo
.
data
.
available
()
>
0
)
{
byte
tag
=
(
byte
)
statusInfo
.
data
.
peekByte
();
if
(
tag
==
DerValue
.
tag_SequenceOf
)
{
DerValue
[]
strings
=
statusInfo
.
data
.
getSequence
(
1
);
statusString
=
new
String
[
strings
.
length
];
for
(
int
i
=
0
;
i
<
strings
.
length
;
i
++)
{
statusString
[
i
]
=
strings
[
i
].
getUTF8String
();
if
(
debug
!=
null
)
{
debug
.
println
(
"timestamp response: statusString="
+
statusString
[
i
]);
}
}
}
}
// Parse failInfo, if present
if
(
status
.
data
.
available
()
>
0
)
{
byte
[]
failInfo
=
status
.
data
.
getBitString
();
int
failureInfo
=
(
new
Byte
(
failInfo
[
0
])).
intValue
();
if
(
failureInfo
<
0
||
failureInfo
>
25
||
failInfo
.
length
!=
1
)
{
throw
new
IOException
(
"Bad encoding for timestamp response: "
+
"unrecognized value for the failInfo element"
);
}
this
.
failureInfo
=
failureInfo
;
if
(
statusInfo
.
data
.
available
()
>
0
)
{
this
.
failureInfo
=
statusInfo
.
data
.
getUnalignedBitString
().
toBooleanArray
();
}
// Parse timeStampToken, if present
...
...
@@ -353,6 +357,7 @@ public class TSResponse {
DerValue
timestampToken
=
derValue
.
data
.
getDerValue
();
encodedTsToken
=
timestampToken
.
toByteArray
();
tsToken
=
new
PKCS7
(
encodedTsToken
);
tstInfo
=
new
TimestampToken
(
tsToken
.
getContentInfo
().
getData
());
}
// Check the format of the timestamp response
...
...
src/share/classes/sun/security/tools/JarSigner.java
浏览文件 @
4c79d01a
...
...
@@ -1277,11 +1277,10 @@ public class JarSigner {
System
.
out
.
println
(
rb
.
getString
(
"TSA.location."
)
+
tsaUrl
);
}
if
(
tsaCert
!=
null
)
{
String
certUrl
=
TimestampedSigner
.
getTimestampingUrl
(
tsaCert
);
if
(
certUrl
!=
null
)
{
URI
tsaURI
=
TimestampedSigner
.
getTimestampingURI
(
tsaCert
);
if
(
tsaURI
!=
null
)
{
System
.
out
.
println
(
rb
.
getString
(
"TSA.location."
)
+
certUrl
);
tsaURI
);
}
System
.
out
.
println
(
rb
.
getString
(
"TSA.certificate."
)
+
printCert
(
""
,
tsaCert
,
false
,
0
,
false
));
...
...
src/share/classes/sun/security/tools/TimestampedSigner.java
浏览文件 @
4c79d01a
...
...
@@ -25,22 +25,14 @@
package
sun.security.tools
;
import
java.io.ByteArrayOutputStream
;
import
java.io.IOException
;
import
java.math.BigInteger
;
import
java.net.URI
;
import
java.security.MessageDigest
;
import
java.security.NoSuchAlgorithmException
;
import
java.security.Principal
;
import
java.security.SecureRandom
;
import
java.security.cert.CertificateException
;
import
java.security.cert.X509Certificate
;
import
java.util.List
;
import
com.sun.jarsigner.*
;
import
java.util.Arrays
;
import
sun.security.pkcs.*
;
import
sun.security.timestamp.*
;
import
sun.security.pkcs.PKCS7
;
import
sun.security.util.*
;
import
sun.security.x509.*
;
...
...
@@ -56,36 +48,12 @@ import sun.security.x509.*;
public
final
class
TimestampedSigner
extends
ContentSigner
{
/*
* Random number generator for creating nonce values
*/
private
static
final
SecureRandom
RANDOM
;
static
{
SecureRandom
tmp
=
null
;
try
{
tmp
=
SecureRandom
.
getInstance
(
"SHA1PRNG"
);
}
catch
(
NoSuchAlgorithmException
e
)
{
// should not happen
}
RANDOM
=
tmp
;
}
/*
* Object identifier for the subject information access X.509 certificate
* extension.
*/
private
static
final
String
SUBJECT_INFO_ACCESS_OID
=
"1.3.6.1.5.5.7.1.11"
;
/*
* Object identifier for the timestamping key purpose.
*/
private
static
final
String
KP_TIMESTAMPING_OID
=
"1.3.6.1.5.5.7.3.8"
;
/*
* Object identifier for extendedKeyUsage extension
*/
private
static
final
String
EXTENDED_KEY_USAGE_OID
=
"2.5.29.37"
;
/*
* Object identifier for the timestamping access descriptors.
*/
...
...
@@ -100,26 +68,6 @@ public final class TimestampedSigner extends ContentSigner {
AD_TIMESTAMPING_Id
=
tmp
;
}
/*
* Location of the TSA.
*/
private
String
tsaUrl
=
null
;
/*
* TSA's X.509 certificate.
*/
private
X509Certificate
tsaCertificate
=
null
;
/*
* Generates an SHA-1 hash value for the data to be timestamped.
*/
private
MessageDigest
messageDigest
=
null
;
/*
* Parameters for the timestamping protocol.
*/
private
boolean
tsRequestCertificate
=
true
;
/**
* Instantiates a content signer that supports timestamped signatures.
*/
...
...
@@ -134,7 +82,7 @@ public final class TimestampedSigner extends ContentSigner {
* and optionally the content that was signed, are packaged into a PKCS #7
* signed data message.
*
* @param param
eter
s The non-null input parameters.
* @param params The non-null input parameters.
* @param omitContent true if the content should be omitted from the
* signed data message. Otherwise the content is included.
* @param applyTimestamp true if the signature should be timestamped.
...
...
@@ -151,98 +99,41 @@ public final class TimestampedSigner extends ContentSigner {
* @throws NullPointerException The exception is thrown if parameters is
* null.
*/
public
byte
[]
generateSignedData
(
ContentSignerParameters
param
eter
s
,
public
byte
[]
generateSignedData
(
ContentSignerParameters
params
,
boolean
omitContent
,
boolean
applyTimestamp
)
throws
NoSuchAlgorithmException
,
CertificateException
,
IOException
{
if
(
param
eter
s
==
null
)
{
if
(
params
==
null
)
{
throw
new
NullPointerException
();
}
// Parse the signature algorithm to extract the digest
and key
// algorithm
s
. The expected format is:
// Parse the signature algorithm to extract the digest
// algorithm. The expected format is:
// "<digest>with<encryption>"
// or "<digest>with<encryption>and<mgf>"
String
signatureAlgorithm
=
parameters
.
getSignatureAlgorithm
();
String
keyAlgorithm
=
AlgorithmId
.
getEncAlgFromSigAlg
(
signatureAlgorithm
);
String
digestAlgorithm
=
AlgorithmId
.
getDigAlgFromSigAlg
(
signatureAlgorithm
);
AlgorithmId
digestAlgorithmId
=
AlgorithmId
.
get
(
digestAlgorithm
);
String
signatureAlgorithm
=
params
.
getSignatureAlgorithm
();
// Examine signer's certificate
X509Certificate
[]
signerCertificateChain
=
parameters
.
getSignerCertificateChain
();
Principal
issuerName
=
signerCertificateChain
[
0
].
getIssuerDN
();
if
(!(
issuerName
instanceof
X500Name
))
{
// must extract the original encoded form of DN for subsequent
// name comparison checks (converting to a String and back to
// an encoded DN could cause the types of String attribute
// values to be changed)
X509CertInfo
tbsCert
=
new
X509CertInfo
(
signerCertificateChain
[
0
].
getTBSCertificate
());
issuerName
=
(
Principal
)
tbsCert
.
get
(
CertificateIssuerName
.
NAME
+
"."
+
CertificateIssuerName
.
DN_NAME
);
}
BigInteger
serialNumber
=
signerCertificateChain
[
0
].
getSerialNumber
();
X509Certificate
[]
signerChain
=
params
.
getSignerCertificateChain
();
byte
[]
signature
=
params
.
getSignature
();
// Include or exclude content
byte
[]
content
=
parameters
.
getContent
();
ContentInfo
contentInfo
;
if
(
omitContent
)
{
contentInfo
=
new
ContentInfo
(
ContentInfo
.
DATA_OID
,
null
);
}
else
{
contentInfo
=
new
ContentInfo
(
content
);
}
byte
[]
content
=
(
omitContent
==
true
)
?
null
:
params
.
getContent
();
// Generate the timestamp token
byte
[]
signature
=
parameters
.
getSignature
();
SignerInfo
signerInfo
=
null
;
URI
tsaURI
=
null
;
if
(
applyTimestamp
)
{
tsaCertificate
=
parameters
.
getTimestampingAuthorityCertificate
();
URI
tsaUri
=
parameters
.
getTimestampingAuthority
();
if
(
tsaUri
!=
null
)
{
tsaUrl
=
tsaUri
.
toString
();
}
else
{
tsaURI
=
params
.
getTimestampingAuthority
();
if
(
tsaURI
==
null
)
{
// Examine TSA cert
String
certUrl
=
getTimestampingUrl
(
tsaCertificate
);
if
(
certUrl
==
null
)
{
tsaURI
=
getTimestampingURI
(
params
.
getTimestampingAuthorityCertificate
());
if
(
tsaURI
==
null
)
{
throw
new
CertificateException
(
"Subject Information Access extension not found"
);
}
tsaUrl
=
certUrl
;
}
// Timestamp the signature
byte
[]
tsToken
=
generateTimestampToken
(
signature
);
// Insert the timestamp token into the PKCS #7 signer info element
// (as an unsigned attribute)
PKCS9Attributes
unsignedAttrs
=
new
PKCS9Attributes
(
new
PKCS9Attribute
[]{
new
PKCS9Attribute
(
PKCS9Attribute
.
SIGNATURE_TIMESTAMP_TOKEN_STR
,
tsToken
)});
signerInfo
=
new
SignerInfo
((
X500Name
)
issuerName
,
serialNumber
,
digestAlgorithmId
,
null
,
AlgorithmId
.
get
(
keyAlgorithm
),
signature
,
unsignedAttrs
);
}
else
{
signerInfo
=
new
SignerInfo
((
X500Name
)
issuerName
,
serialNumber
,
digestAlgorithmId
,
AlgorithmId
.
get
(
keyAlgorithm
),
signature
);
}
SignerInfo
[]
signerInfos
=
{
signerInfo
};
AlgorithmId
[]
algorithms
=
{
digestAlgorithmId
};
// Create the PKCS #7 signed data message
PKCS7
p7
=
new
PKCS7
(
algorithms
,
contentInfo
,
signerCertificateChain
,
null
,
signerInfos
);
ByteArrayOutputStream
p7out
=
new
ByteArrayOutputStream
();
p7
.
encodeSignedData
(
p7out
);
return
p7out
.
toByteArray
();
return
PKCS7
.
generateSignedData
(
signature
,
signerChain
,
content
,
params
.
getSignatureAlgorithm
(),
tsaURI
);
}
/**
...
...
@@ -253,9 +144,9 @@ public final class TimestampedSigner extends ContentSigner {
* <tt>accessLocation</tt> field should contain an HTTP or HTTPS URL.
*
* @param tsaCertificate An X.509 certificate for the TSA.
* @return An HTTP or HTTPS UR
L
or null if none was found.
* @return An HTTP or HTTPS UR
I
or null if none was found.
*/
public
static
String
getTimestampingUrl
(
X509Certificate
tsaCertificate
)
{
public
static
URI
getTimestampingURI
(
X509Certificate
tsaCertificate
)
{
if
(
tsaCertificate
==
null
)
{
return
null
;
...
...
@@ -282,7 +173,7 @@ public final class TimestampedSigner extends ContentSigner {
uri
=
(
URIName
)
location
.
getName
();
if
(
uri
.
getScheme
().
equalsIgnoreCase
(
"http"
)
||
uri
.
getScheme
().
equalsIgnoreCase
(
"https"
))
{
return
uri
.
get
Name
();
return
uri
.
get
URI
();
}
}
}
...
...
@@ -292,97 +183,4 @@ public final class TimestampedSigner extends ContentSigner {
}
return
null
;
}
/*
* Returns a timestamp token from a TSA for the given content.
* Performs a basic check on the token to confirm that it has been signed
* by a certificate that is permitted to sign timestamps.
*
* @param toBeTimestamped The data to be timestamped.
* @throws IOException The exception is throw if an error occurs while
* communicating with the TSA.
* @throws CertificateException The exception is throw if the TSA's
* certificate is not permitted for timestamping.
*/
private
byte
[]
generateTimestampToken
(
byte
[]
toBeTimestamped
)
throws
CertificateException
,
IOException
{
// Generate hash value for the data to be timestamped
// SHA-1 is always used.
if
(
messageDigest
==
null
)
{
try
{
messageDigest
=
MessageDigest
.
getInstance
(
"SHA-1"
);
}
catch
(
NoSuchAlgorithmException
e
)
{
// ignore
}
}
byte
[]
digest
=
messageDigest
.
digest
(
toBeTimestamped
);
// Generate a timestamp
TSRequest
tsQuery
=
new
TSRequest
(
digest
,
"SHA-1"
);
// Generate a nonce
BigInteger
nonce
=
null
;
if
(
RANDOM
!=
null
)
{
nonce
=
new
BigInteger
(
64
,
RANDOM
);
tsQuery
.
setNonce
(
nonce
);
}
tsQuery
.
requestCertificate
(
tsRequestCertificate
);
Timestamper
tsa
=
new
HttpTimestamper
(
tsaUrl
);
// use supplied TSA
TSResponse
tsReply
=
tsa
.
generateTimestamp
(
tsQuery
);
int
status
=
tsReply
.
getStatusCode
();
// Handle TSP error
if
(
status
!=
0
&&
status
!=
1
)
{
int
failureCode
=
tsReply
.
getFailureCode
();
if
(
failureCode
==
-
1
)
{
throw
new
IOException
(
"Error generating timestamp: "
+
tsReply
.
getStatusCodeAsText
());
}
else
{
throw
new
IOException
(
"Error generating timestamp: "
+
tsReply
.
getStatusCodeAsText
()
+
" "
+
tsReply
.
getFailureCodeAsText
());
}
}
PKCS7
tsToken
=
tsReply
.
getToken
();
TimestampToken
tst
=
new
TimestampToken
(
tsToken
.
getContentInfo
().
getData
());
if
(!
tst
.
getHashAlgorithm
().
equals
(
new
AlgorithmId
(
new
ObjectIdentifier
(
"1.3.14.3.2.26"
))))
{
throw
new
IOException
(
"Digest algorithm not SHA-1 in timestamp token"
);
}
if
(!
Arrays
.
equals
(
tst
.
getHashedMessage
(),
digest
))
{
throw
new
IOException
(
"Digest octets changed in timestamp token"
);
}
BigInteger
replyNonce
=
tst
.
getNonce
();
if
(
replyNonce
==
null
&&
nonce
!=
null
)
{
throw
new
IOException
(
"Nonce missing in timestamp token"
);
}
if
(
replyNonce
!=
null
&&
!
replyNonce
.
equals
(
nonce
))
{
throw
new
IOException
(
"Nonce changed in timestamp token"
);
}
// Examine the TSA's certificate (if present)
for
(
SignerInfo
si:
tsToken
.
getSignerInfos
())
{
X509Certificate
cert
=
si
.
getCertificate
(
tsToken
);
if
(
cert
==
null
)
{
// Error, we've already set tsRequestCertificate = true
throw
new
CertificateException
(
"Certificate not included in timestamp token"
);
}
else
{
if
(!
cert
.
getCriticalExtensionOIDs
().
contains
(
EXTENDED_KEY_USAGE_OID
))
{
throw
new
CertificateException
(
"Certificate is not valid for timestamping"
);
}
List
<
String
>
keyPurposes
=
cert
.
getExtendedKeyUsage
();
if
(
keyPurposes
==
null
||
!
keyPurposes
.
contains
(
KP_TIMESTAMPING_OID
))
{
throw
new
CertificateException
(
"Certificate is not valid for timestamping"
);
}
}
}
return
tsReply
.
getEncodedToken
();
}
}
src/share/classes/sun/security/util/Debug.java
浏览文件 @
4c79d01a
/*
* Copyright (c) 1998, 201
0
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 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
...
...
@@ -80,6 +80,7 @@ public class Debug {
System
.
err
.
println
(
"policy loading and granting"
);
System
.
err
.
println
(
"provider security provider debugging"
);
System
.
err
.
println
(
"scl permissions SecureClassLoader assigns"
);
System
.
err
.
println
(
"ts timestamping"
);
System
.
err
.
println
();
System
.
err
.
println
(
"The following can be used with access:"
);
System
.
err
.
println
();
...
...
src/share/classes/sun/security/util/SignatureFileVerifier.java
浏览文件 @
4c79d01a
...
...
@@ -35,7 +35,6 @@ import java.util.*;
import
java.util.jar.*
;
import
sun.security.pkcs.*
;
import
sun.security.timestamp.TimestampToken
;
import
sun.misc.BASE64Decoder
;
import
sun.security.jca.Providers
;
...
...
@@ -485,7 +484,7 @@ public class SignatureFileVerifier {
signers
=
new
ArrayList
<
CodeSigner
>();
}
// Append the new code signer
signers
.
add
(
new
CodeSigner
(
certChain
,
getTimestamp
(
info
)));
signers
.
add
(
new
CodeSigner
(
certChain
,
info
.
getTimestamp
(
)));
if
(
debug
!=
null
)
{
debug
.
println
(
"Signature Block Certificate: "
+
...
...
@@ -500,62 +499,6 @@ public class SignatureFileVerifier {
}
}
/*
* Examines a signature timestamp token to generate a timestamp object.
*
* Examines the signer's unsigned attributes for a
* <tt>signatureTimestampToken</tt> attribute. If present,
* then it is parsed to extract the date and time at which the
* timestamp was generated.
*
* @param info A signer information element of a PKCS 7 block.
*
* @return A timestamp token or null if none is present.
* @throws IOException if an error is encountered while parsing the
* PKCS7 data.
* @throws NoSuchAlgorithmException if an error is encountered while
* verifying the PKCS7 object.
* @throws SignatureException if an error is encountered while
* verifying the PKCS7 object.
* @throws CertificateException if an error is encountered while generating
* the TSA's certpath.
*/
private
Timestamp
getTimestamp
(
SignerInfo
info
)
throws
IOException
,
NoSuchAlgorithmException
,
SignatureException
,
CertificateException
{
Timestamp
timestamp
=
null
;
// Extract the signer's unsigned attributes
PKCS9Attributes
unsignedAttrs
=
info
.
getUnauthenticatedAttributes
();
if
(
unsignedAttrs
!=
null
)
{
PKCS9Attribute
timestampTokenAttr
=
unsignedAttrs
.
getAttribute
(
"signatureTimestampToken"
);
if
(
timestampTokenAttr
!=
null
)
{
PKCS7
timestampToken
=
new
PKCS7
((
byte
[])
timestampTokenAttr
.
getValue
());
// Extract the content (an encoded timestamp token info)
byte
[]
encodedTimestampTokenInfo
=
timestampToken
.
getContentInfo
().
getData
();
// Extract the signer (the Timestamping Authority)
// while verifying the content
SignerInfo
[]
tsa
=
timestampToken
.
verify
(
encodedTimestampTokenInfo
);
// Expect only one signer
ArrayList
<
X509Certificate
>
chain
=
tsa
[
0
].
getCertificateChain
(
timestampToken
);
CertPath
tsaChain
=
certificateFactory
.
generateCertPath
(
chain
);
// Create a timestamp token info object
TimestampToken
timestampTokenInfo
=
new
TimestampToken
(
encodedTimestampTokenInfo
);
// Create a timestamp object
timestamp
=
new
Timestamp
(
timestampTokenInfo
.
getDate
(),
tsaChain
);
}
}
return
timestamp
;
}
// for the toHex function
private
static
final
char
[]
hexc
=
{
'0'
,
'1'
,
'2'
,
'3'
,
'4'
,
'5'
,
'6'
,
'7'
,
'8'
,
'9'
,
'a'
,
'b'
,
'c'
,
'd'
,
'e'
,
'f'
};
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录