-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathBouncyCastleTsaClient.vb
133 lines (117 loc) · 5.12 KB
/
BouncyCastleTsaClient.vb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
Imports DevExpress.Pdf
Imports Org.BouncyCastle.Asn1.Cmp
Imports Org.BouncyCastle.Crypto
Imports Org.BouncyCastle.Crypto.Digests
Imports Org.BouncyCastle.Math
Imports Org.BouncyCastle.Security
Imports Org.BouncyCastle.Tsp
Imports System
Imports System.IO
Imports System.Net
Imports System.Security.Cryptography
Imports System.Diagnostics
Imports DevExpress.Office.Tsp
Namespace CustomTsaClient
Public Class BouncyCastleTsaClient
Implements ITsaClient
Private ReadOnly tsaServerURI As Uri
Private ReadOnly hashCalculator As IDigest
Public Sub New(ByVal tsaServerURI As Uri, ByVal hashCalculator As IDigest)
Me.tsaServerURI = tsaServerURI
Me.hashCalculator = hashCalculator
End Sub
Private Function CalculateDigest(ByVal stream As Stream) As Byte()
Dim buffer(81919) As Byte
hashCalculator.Reset()
Dim bytesRead As Integer
bytesRead = stream.Read(buffer, 0, buffer.Length)
Do While bytesRead > 0
hashCalculator.BlockUpdate(buffer, 0, bytesRead)
bytesRead = stream.Read(buffer, 0, buffer.Length)
Loop
Dim result(hashCalculator.GetDigestSize() - 1) As Byte
hashCalculator.DoFinal(result, 0)
Return result
End Function
Public Function GenerateTimeStamp(ByVal stream As Stream) As Byte() Implements ITsaClient.GenerateTimeStamp
'Generate a timestamp request:
Dim tsqGenerator As New TimeStampRequestGenerator()
tsqGenerator.SetCertReq(True)
Dim nonce As BigInteger
Using generator As RandomNumberGenerator = RandomNumberGenerator.Create()
Dim nonceValue(9) As Byte
generator.GetBytes(nonceValue)
nonce = New BigInteger(nonceValue)
End Using
Dim algorithmOid As String = DigestUtilities.GetObjectIdentifier(hashCalculator.AlgorithmName).Id
Dim request As TimeStampRequest = tsqGenerator.Generate(algorithmOid, CalculateDigest(stream), nonce)
Dim requestBytes() As Byte = request.GetEncoded()
'Send the request to a server:
Dim httpRequest As HttpWebRequest = CType(WebRequest.Create(tsaServerURI), HttpWebRequest)
httpRequest.Method = "POST"
httpRequest.ContentType = "application/timestamp-query"
httpRequest.ContentLength = requestBytes.Length
Using requestStream As Stream = httpRequest.GetRequestStream()
requestStream.Write(requestBytes, 0, requestBytes.Length)
End Using
'Get a response from the server:
Dim httpResponse As HttpWebResponse = CType(httpRequest.GetResponse(), HttpWebResponse)
Using respStream As Stream = New BufferedStream(httpResponse.GetResponseStream())
'Read the responce:
Dim response As New TimeStampResponse(respStream)
response.Validate(request)
Dim failure As PkiFailureInfo = response.GetFailInfo()
'Throw an exception if the responce returned an error:
If failure IsNot Nothing Then
Throw New Exception($"TimeStamp request to the ""{tsaServerURI}"" failed.")
End If
Dim token As TimeStampToken = response.TimeStampToken
'Throw an exception if the responce doesn't contain the timestamp:
If token Is Nothing Then
Throw New Exception($"TimeStamp request to the ""{tsaServerURI}"" failed.")
End If
Return token.GetEncoded()
End Using
End Function
Public Function GenerateTimeStamp(digest() As Byte, digestAlgorithmOID As String) As Byte() Implements ITsaClient.GenerateTimeStamp
'Generate a timestamp request:
Dim tsqGenerator As New TimeStampRequestGenerator()
tsqGenerator.SetCertReq(True)
Dim nonce As BigInteger
Using generator As RandomNumberGenerator = RandomNumberGenerator.Create()
Dim nonceValue(9) As Byte
generator.GetBytes(nonceValue)
nonce = New BigInteger(nonceValue)
End Using
Dim algorithmOid As String = DigestUtilities.GetObjectIdentifier(hashCalculator.AlgorithmName).Id
Dim request As TimeStampRequest = tsqGenerator.Generate(algorithmOid, digest, nonce)
Dim requestBytes() As Byte = request.GetEncoded()
'Send the request to a server:
Dim httpRequest As HttpWebRequest = CType(WebRequest.Create(tsaServerURI), HttpWebRequest)
httpRequest.Method = "POST"
httpRequest.ContentType = "application/timestamp-query"
httpRequest.ContentLength = requestBytes.Length
Using requestStream As Stream = httpRequest.GetRequestStream()
requestStream.Write(requestBytes, 0, requestBytes.Length)
End Using
'Get a response from the server:
Dim httpResponse As HttpWebResponse = CType(httpRequest.GetResponse(), HttpWebResponse)
Using respStream As Stream = New BufferedStream(httpResponse.GetResponseStream())
'Read the responce:
Dim response As New TimeStampResponse(respStream)
response.Validate(request)
Dim failure As PkiFailureInfo = response.GetFailInfo()
'Throw an exception if the responce returned an error:
If failure IsNot Nothing Then
Throw New Exception($"TimeStamp request to the ""{tsaServerURI}"" failed.")
End If
Dim token As TimeStampToken = response.TimeStampToken
'Throw an exception if the responce doesn't contain the timestamp:
If token Is Nothing Then
Throw New Exception($"TimeStamp request to the ""{tsaServerURI}"" failed.")
End If
Return token.GetEncoded()
End Using
End Function
End Class
End Namespace