-
Notifications
You must be signed in to change notification settings - Fork 1
/
dss.go
119 lines (102 loc) · 3.38 KB
/
dss.go
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
package globalsign
import (
"context"
"encoding/base64"
"encoding/hex"
"strings"
"time"
)
// DSSService implements GlobalSign Digital Signing Service.
type DSSService interface {
Login(*LoginRequest) (*LoginResponse, error)
Identity(*IdentityRequest) (*IdentityResponse, error)
Timestamp(*TimestampRequest) (*TimestampResponse, error)
Sign(*SigningRequest) (*SigningResponse, error)
CertificatePath() (*CertificatePathResponse, error)
TrustChain() (*TrustChainResponse, error)
ValidationPolicy() (*ValidationPolicyResponse, error)
QuotasSignatures() (*QuotasResponse, error)
QuotasTimestamps() (*QuotasResponse, error)
// DSS Identity and sign process services.
DSSGetIdentity(context.Context, string, *IdentityRequest) (*DSSIdentity, error)
DSSIdentitySign(context.Context, string, *IdentityRequest, []byte) ([]byte, error)
DSSIdentityTimestamp(context.Context, string, *IdentityRequest, []byte) ([]byte, error)
}
// DSSIdentity represent acquired credential from login and identity request.
type DSSIdentity struct {
ID string
SigningCert string
OCSP string
CA string
Ts time.Time
}
// DSSGetIdentity get identity information, signing certificate, OCSP, and CA certificate -
// automatically request identity if token expired.
func (s *globalSignDSSService) DSSGetIdentity(ctx context.Context, signer string, req *IdentityRequest) (*DSSIdentity, error) {
// Check identity in vault.
identity, ok := s.client.vault.Get(signer)
if ok {
return identity, nil
}
// Otherwise request new identity,
err := s.client.ensureToken(ctx)
if err != nil {
return nil, err
}
// Request id and signing certificate.
identityResp, err := s.client.DSSService.Identity(req)
if err != nil {
return nil, err
}
// Request CA certificate.
certResp, err := s.client.DSSService.CertificatePath()
if err != nil {
return nil, err
}
identity = &DSSIdentity{
ID: identityResp.ID,
SigningCert: identityResp.SigningCert,
OCSP: identityResp.OCSPResponse,
CA: certResp.CA,
}
s.client.vault.Set(signer, identity)
return identity, nil
}
// DSSIdentitySign request signature with signer and identity,
// automatically request identity if token expired.
func (s *globalSignDSSService) DSSIdentitySign(ctx context.Context, signer string, identityReq *IdentityRequest, digest []byte) ([]byte, error) {
err := s.client.ensureToken(ctx)
if err != nil {
return nil, err
}
identity, err := s.DSSGetIdentity(ctx, signer, identityReq)
if err != nil {
return nil, err
}
// Encode digest to hex.
digestHex := strings.ToUpper(hex.EncodeToString(digest))
signatureResp, err := s.client.DSSService.Sign(&SigningRequest{
ID: identity.ID,
Digest: digestHex,
})
if err != nil {
return nil, err
}
return hex.DecodeString(signatureResp.Signature)
}
// DSSIdentityTimestamp add timestamp token to signer, automatically request identity if token expired.
func (s *globalSignDSSService) DSSIdentityTimestamp(ctx context.Context, signer string, identityReq *IdentityRequest, digest []byte) ([]byte, error) {
err := s.client.ensureToken(ctx)
if err != nil {
return nil, err
}
// Encode digest to hex.
digestHex := strings.ToUpper(hex.EncodeToString(digest))
timestampResp, err := s.client.DSSService.Timestamp(&TimestampRequest{
Digest: digestHex,
})
if err != nil {
return nil, err
}
return base64.StdEncoding.DecodeString(timestampResp.Token)
}