1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package mock
16
17 import (
18 "bytes"
19 "crypto"
20 "crypto/elliptic"
21 "crypto/rand"
22 "crypto/x509"
23 "encoding/asn1"
24 "fmt"
25 "io"
26 "time"
27
28 "github.com/go-openapi/runtime"
29 "github.com/pkg/errors"
30
31 "github.com/digitorus/timestamp"
32 "github.com/sigstore/sigstore/pkg/cryptoutils"
33 "github.com/sigstore/sigstore/pkg/signature"
34 "github.com/sigstore/timestamp-authority/pkg/generated/client"
35 ts "github.com/sigstore/timestamp-authority/pkg/generated/client/timestamp"
36 "github.com/sigstore/timestamp-authority/pkg/signer"
37 )
38
39
40
41
42
43 type TSAClient struct {
44 Signer crypto.Signer
45 CertChain []*x509.Certificate
46 CertChainPEM string
47 Time time.Time
48 Message []byte
49 }
50
51
52 type TSAClientOptions struct {
53
54 Time time.Time
55
56 Message []byte
57
58 Signer crypto.Signer
59 }
60
61 func NewTSAClient(o TSAClientOptions) (*client.TimestampAuthority, error) {
62 sv := o.Signer
63 if sv == nil {
64 var err error
65 sv, _, err = signature.NewECDSASignerVerifier(elliptic.P256(), rand.Reader, crypto.SHA256)
66 if err != nil {
67 return nil, err
68 }
69 }
70 certChain, err := signer.NewTimestampingCertWithChain(sv)
71 if err != nil {
72 return nil, errors.Wrap(err, "generating timestamping cert chain")
73 }
74 certChainPEM, err := cryptoutils.MarshalCertificatesToPEM(certChain)
75 if err != nil {
76 return nil, fmt.Errorf("marshal certificates to PEM: %w", err)
77 }
78
79 return &client.TimestampAuthority{
80 Timestamp: &TSAClient{
81 Signer: sv,
82 CertChain: certChain,
83 CertChainPEM: string(certChainPEM),
84 Time: o.Time,
85 Message: o.Message,
86 },
87 }, nil
88 }
89
90 func (c *TSAClient) GetTimestampCertChain(_ *ts.GetTimestampCertChainParams, _ ...ts.ClientOption) (*ts.GetTimestampCertChainOK, error) {
91 return &ts.GetTimestampCertChainOK{Payload: c.CertChainPEM}, nil
92 }
93
94 func (c *TSAClient) GetTimestampResponse(params *ts.GetTimestampResponseParams, w io.Writer, _ ...ts.ClientOption) (*ts.GetTimestampResponseCreated, error) {
95 var hashAlg crypto.Hash
96 var hashedMessage []byte
97
98 if params.Request != nil {
99 requestBytes, err := io.ReadAll(params.Request)
100 if err != nil {
101 return nil, err
102 }
103
104 req, err := timestamp.ParseRequest(requestBytes)
105 if err != nil {
106 return nil, err
107 }
108 hashAlg = req.HashAlgorithm
109 hashedMessage = req.HashedMessage
110 } else {
111 hashAlg = crypto.SHA256
112 h := hashAlg.New()
113 h.Write(c.Message)
114 hashedMessage = h.Sum(nil)
115 }
116
117 nonce, err := cryptoutils.GenerateSerialNumber()
118 if err != nil {
119 return nil, err
120 }
121 duration, _ := time.ParseDuration("1s")
122
123 tsStruct := timestamp.Timestamp{
124 HashAlgorithm: hashAlg,
125 HashedMessage: hashedMessage,
126 Nonce: nonce,
127 Policy: asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 57264, 2},
128 Ordering: false,
129 Accuracy: duration,
130 Qualified: false,
131 AddTSACertificate: true,
132 }
133
134 if c.Time.IsZero() {
135 tsStruct.Time = time.Now()
136 } else {
137 tsStruct.Time = c.Time
138 }
139
140 resp, err := tsStruct.CreateResponseWithOpts(c.CertChain[0], c.Signer, crypto.SHA256)
141 if err != nil {
142 return nil, err
143 }
144
145
146 if w != nil {
147 _, err := w.Write(resp)
148 if err != nil {
149 return nil, err
150 }
151 }
152 return &ts.GetTimestampResponseCreated{Payload: bytes.NewBuffer(resp)}, nil
153 }
154
155 func (c *TSAClient) SetTransport(_ runtime.ClientTransport) {
156
157 }
158
View as plain text