├── .github ├── dependabot.yml └── workflows │ ├── go.yml │ └── golangci-lint.yml ├── LICENSE ├── README.md ├── borrowed.go ├── go.mod ├── go.sum ├── rfc3161_struct.go ├── signing_cert_v2_struct.go ├── signing_cert_v2_struct_test.go ├── timestamp.go ├── timestamp_example_test.go └── timestamp_test.go /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # To get started with Dependabot version updates, you'll need to specify which 2 | # package ecosystems to update and where the package manifests are located. 3 | # Please see the documentation for all configuration options: 4 | # https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates 5 | 6 | version: 2 7 | updates: 8 | - package-ecosystem: "gomod" 9 | directory: "/" 10 | schedule: 11 | interval: "weekly" 12 | -------------------------------------------------------------------------------- /.github/workflows/go.yml: -------------------------------------------------------------------------------- 1 | name: Build & Test 2 | 3 | on: 4 | push: 5 | branches: [ master ] 6 | pull_request: 7 | branches: [ master ] 8 | 9 | jobs: 10 | 11 | build: 12 | name: Build 13 | runs-on: ubuntu-latest 14 | steps: 15 | 16 | - name: Set up Go 1.x 17 | uses: actions/setup-go@v2 18 | with: 19 | go-version: ^1.13 20 | 21 | - name: Check out code into the Go module directory 22 | uses: actions/checkout@v2 23 | 24 | - name: Get dependencies 25 | run: | 26 | go get -v -t -d ./... 27 | 28 | - name: Build 29 | run: go build -v ./... 30 | 31 | - name: Test 32 | run: go test -v -race -coverprofile=coverage.txt -covermode=atomic ./... 33 | 34 | - name: Upload coverage report 35 | uses: codecov/codecov-action@v1 36 | with: 37 | file: ./coverage.txt 38 | flags: unittests 39 | name: codecov-umbrella 40 | -------------------------------------------------------------------------------- /.github/workflows/golangci-lint.yml: -------------------------------------------------------------------------------- 1 | name: golangci-lint 2 | on: 3 | push: 4 | branches: 5 | - master 6 | - main 7 | pull_request: 8 | 9 | permissions: 10 | contents: read 11 | # Optional: allow read access to pull request. Use with `only-new-issues` option. 12 | # pull-requests: read 13 | 14 | jobs: 15 | golangci: 16 | name: lint 17 | runs-on: ubuntu-latest 18 | steps: 19 | - uses: actions/checkout@v4 20 | - uses: actions/setup-go@v5 21 | with: 22 | go-version: '1.22' 23 | cache: false 24 | - name: golangci-lint 25 | uses: golangci/golangci-lint-action@v4 26 | with: 27 | # Require: The version of golangci-lint to use. 28 | # When `install-mode` is `binary` (default) the value can be v1.2 or v1.2.3 or `latest` to use the latest version. 29 | # When `install-mode` is `goinstall` the value can be v1.2.3, `latest`, or the hash of a commit. 30 | version: v1.62 31 | 32 | # Optional: working directory, useful for monorepos 33 | # working-directory: somedir 34 | 35 | # Optional: golangci-lint command line arguments. 36 | # 37 | # Note: By default, the `.golangci.yml` file should be at the root of the repository. 38 | # The location of the configuration file can be changed by using `--config=` 39 | # args: --timeout=30m --config=/my/path/.golangci.yml --issues-exit-code=0 40 | 41 | # Optional: show only new issues if it's a pull request. The default value is `false`. 42 | # only-new-issues: true 43 | 44 | # Optional: if set to true, then all caching functionality will be completely disabled, 45 | # takes precedence over all other caching options. 46 | # skip-cache: true 47 | 48 | # Optional: if set to true, then the action won't cache or restore ~/go/pkg. 49 | # skip-pkg-cache: true 50 | 51 | # Optional: if set to true, then the action won't cache or restore ~/.cache/go-build. 52 | # skip-build-cache: true 53 | 54 | # Optional: The mode to install golangci-lint. It can be 'binary' or 'goinstall'. 55 | # install-mode: "goinstall" 56 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 2-Clause License 2 | 3 | Copyright (c) 2017, Digitorus B.V. 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | 1. Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | 2. Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 20 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 23 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # RFC3161 Time-Stamp Protocol (TSP) package for Go 2 | 3 | [![Build & Test](https://github.com/digitorus/timestamp/workflows/Build%20&%20Test/badge.svg)](https://github.com/digitorus/timestamp/actions?query=workflow%3Abuild-and-test) 4 | [![golangci-lint](https://github.com/digitorus/timestamp/workflows/golangci-lint/badge.svg)](https://github.com/digitorus/timestamp/actions?query=workflow%3Agolangci-lint) 5 | [![CodeQL](https://github.com/digitorus/timestamp/workflows/CodeQL/badge.svg)](https://github.com/digitorus/timestamp/actions?query=workflow%3Acodeql) 6 | [![Go Report Card](https://goreportcard.com/badge/github.com/digitorus/timestamp)](https://goreportcard.com/report/github.com/digitorus/timestamp) 7 | [![Coverage Status](https://codecov.io/gh/digitorus/timestamp/branch/master/graph/badge.svg)](https://codecov.io/gh/digitorus/timestamp) 8 | [![Go Reference](https://pkg.go.dev/badge/github.com/digitorus/timestamp.svg)](https://pkg.go.dev/github.com/digitorus/timestamp) 9 | 10 | Time-Stamp Protocol (TSP) package for Go 11 | 12 | #### General 13 | The package timestamp implements the Time-Stamp Protocol (TSP) as specified in RFC3161 (Internet X.509 Public Key Infrastructure Time-Stamp Protocol (TSP)). 14 | -------------------------------------------------------------------------------- /borrowed.go: -------------------------------------------------------------------------------- 1 | package timestamp 2 | 3 | import ( 4 | "crypto" 5 | "encoding/asn1" 6 | ) 7 | 8 | // TODO(vanbroup): taken from "golang.org/x/crypto/ocsp" 9 | // use directly from crypto/x509 when exported as suggested below. 10 | 11 | var hashOIDs = map[crypto.Hash]asn1.ObjectIdentifier{ 12 | crypto.SHA1: asn1.ObjectIdentifier([]int{1, 3, 14, 3, 2, 26}), 13 | crypto.SHA256: asn1.ObjectIdentifier([]int{2, 16, 840, 1, 101, 3, 4, 2, 1}), 14 | crypto.SHA384: asn1.ObjectIdentifier([]int{2, 16, 840, 1, 101, 3, 4, 2, 2}), 15 | crypto.SHA512: asn1.ObjectIdentifier([]int{2, 16, 840, 1, 101, 3, 4, 2, 3}), 16 | } 17 | 18 | // TODO(rlb): This is not taken from crypto/x509, but it's of the same general form. 19 | func getHashAlgorithmFromOID(target asn1.ObjectIdentifier) crypto.Hash { 20 | for hash, oid := range hashOIDs { 21 | if oid.Equal(target) { 22 | return hash 23 | } 24 | } 25 | return crypto.Hash(0) 26 | } 27 | 28 | func getOIDFromHashAlgorithm(target crypto.Hash) asn1.ObjectIdentifier { 29 | for hash, oid := range hashOIDs { 30 | if hash == target { 31 | return oid 32 | } 33 | } 34 | return nil 35 | } 36 | 37 | // TODO(vanbroup): taken from golang.org/x/crypto/x509 38 | // asn1BitLength returns the bit-length of bitString by considering the 39 | // most-significant bit in a byte to be the "first" bit. This convention 40 | // matches ASN.1, but differs from almost everything else. 41 | func asn1BitLength(bitString []byte) int { 42 | bitLen := len(bitString) * 8 43 | 44 | for i := range bitString { 45 | b := bitString[len(bitString)-i-1] 46 | 47 | for bit := uint(0); bit < 8; bit++ { 48 | if (b>>bit)&1 == 1 { 49 | return bitLen 50 | } 51 | bitLen-- 52 | } 53 | } 54 | 55 | return 0 56 | } 57 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/digitorus/timestamp 2 | 3 | go 1.16 4 | 5 | require github.com/digitorus/pkcs7 v0.0.0-20230713084857-e76b763bdc49 6 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/digitorus/pkcs7 v0.0.0-20230713084857-e76b763bdc49 h1:h+XMRXf+WLY0h/3itqE8OT3TgjCMHK4nq2FNGi0au2c= 2 | github.com/digitorus/pkcs7 v0.0.0-20230713084857-e76b763bdc49/go.mod h1:SKVExuS+vpu2l9IoOc0RwqE7NYnb0JlcFHFnEJkVDzc= 3 | -------------------------------------------------------------------------------- /rfc3161_struct.go: -------------------------------------------------------------------------------- 1 | package timestamp 2 | 3 | import ( 4 | "crypto/x509/pkix" 5 | "encoding/asn1" 6 | "math/big" 7 | "time" 8 | ) 9 | 10 | // http://www.ietf.org/rfc/rfc3161.txt 11 | // 2.4.1. Request Format 12 | type request struct { 13 | Version int 14 | MessageImprint messageImprint 15 | ReqPolicy asn1.ObjectIdentifier `asn1:"optional"` 16 | Nonce *big.Int `asn1:"optional"` 17 | CertReq bool `asn1:"optional,default:false"` 18 | Extensions []pkix.Extension `asn1:"tag:0,optional"` 19 | } 20 | 21 | type messageImprint struct { 22 | HashAlgorithm pkix.AlgorithmIdentifier 23 | HashedMessage []byte 24 | } 25 | 26 | // 2.4.2. Response Format 27 | type response struct { 28 | Status pkiStatusInfo 29 | TimeStampToken asn1.RawValue `asn1:"optional"` 30 | } 31 | 32 | type pkiStatusInfo struct { 33 | Status Status 34 | StatusString []string `asn1:"optional,utf8"` 35 | FailInfo asn1.BitString `asn1:"optional"` 36 | } 37 | 38 | func (s pkiStatusInfo) FailureInfo() FailureInfo { 39 | fi := []FailureInfo{BadAlgorithm, BadRequest, BadDataFormat, TimeNotAvailable, 40 | UnacceptedPolicy, UnacceptedExtension, AddInfoNotAvailable, SystemFailure} 41 | 42 | for _, f := range fi { 43 | if s.FailInfo.At(int(f)) != 0 { 44 | return f 45 | } 46 | } 47 | 48 | return UnknownFailureInfo 49 | } 50 | 51 | // eContent within SignedData is TSTInfo 52 | type tstInfo struct { 53 | Version int 54 | Policy asn1.ObjectIdentifier 55 | MessageImprint messageImprint 56 | SerialNumber *big.Int 57 | Time time.Time `asn1:"generalized"` 58 | Accuracy accuracy `asn1:"optional"` 59 | Ordering bool `asn1:"optional,default:false"` 60 | Nonce *big.Int `asn1:"optional"` 61 | TSA asn1.RawValue `asn1:"tag:0,optional"` 62 | Extensions []pkix.Extension `asn1:"tag:1,optional"` 63 | } 64 | 65 | // accuracy within TSTInfo 66 | type accuracy struct { 67 | Seconds int64 `asn1:"optional"` 68 | Milliseconds int64 `asn1:"tag:0,optional"` 69 | Microseconds int64 `asn1:"tag:1,optional"` 70 | } 71 | 72 | type qcStatement struct { 73 | StatementID asn1.ObjectIdentifier 74 | StatementInfo asn1.RawValue `asn1:"optional"` 75 | } 76 | -------------------------------------------------------------------------------- /signing_cert_v2_struct.go: -------------------------------------------------------------------------------- 1 | package timestamp 2 | 3 | import ( 4 | "crypto/x509/pkix" 5 | "encoding/asn1" 6 | "math/big" 7 | ) 8 | 9 | type issuerAndSerial struct { 10 | IssuerName generalNames 11 | SerialNumber *big.Int 12 | } 13 | 14 | type generalNames struct { 15 | Name asn1.RawValue `asn1:"optional,tag:4"` 16 | } 17 | 18 | type essCertIDv2 struct { 19 | HashAlgorithm pkix.AlgorithmIdentifier `asn1:"optional"` // default sha256 20 | CertHash []byte 21 | IssuerSerial issuerAndSerial `asn1:"optional"` 22 | } 23 | 24 | type signingCertificateV2 struct { 25 | Certs []essCertIDv2 26 | } 27 | -------------------------------------------------------------------------------- /signing_cert_v2_struct_test.go: -------------------------------------------------------------------------------- 1 | package timestamp 2 | 3 | import ( 4 | "crypto/x509/pkix" 5 | "encoding/asn1" 6 | "encoding/base64" 7 | "encoding/hex" 8 | "testing" 9 | ) 10 | 11 | const openSSLsigningCertificateV2 = "MIGmMIGjMCIEIF3fpxB3ZHtqRQhp+yXouV/BC3Lq+qu2ZlzKK5gs5KNQMH0EIKVoZJ8s/3CtF6Uk5NktrvzvGhurqtFb8VjC3lYfPG09MFkwQaQ/MD0xGjAYBgNVBAMTEURpZ2l0b3J1cyBUZXN0IFIxMQswCQYDVQQGEwJOTDESMBAGA1UEChMJRGlnaXRvcnVzAhR5l9lohaINhjG85JxnRQJ+4ZzoIzANBgkqhkiG9w0BAQEFAASCAQBwz6D9nLivzryLlwvrWQhC9DgX6hh0h9swcqkcHdrQHzZSADcCLjJU+9eO/6yrY99e6uKwNyJiIdi39oQy/aWYcayHHyN+OO32LKJhupJrraDMFPTD7n5bhOCZOsXKIlKcm718WrVkNrle/GWabaS/fRqBFDoj8A+LBPtH6xGRz6ohUhtxpAzZoYW1KcnqHOpD40LRdA4i4jC5Y67h7//jYeA/B7Bf6KNC1TmFi388VeuVjU6FnADlB/9MkwbGunYmOlp6QY+QzJthf/1VCZlna9HKdcY5hEGCSH+ta0uXqU84ePLrvy6UvQRUNVTqIaSbLeL6MC1S636mbCjuJZ2C" 12 | 13 | func TestOpenSSLSigningCertificateV2(t *testing.T) { 14 | v2bytes, err := base64.StdEncoding.DecodeString(openSSLsigningCertificateV2) 15 | if err != nil { 16 | t.Error(err) 17 | return 18 | } 19 | 20 | var scv2 signingCertificateV2 21 | if _, err = asn1.Unmarshal(v2bytes, &scv2); err != nil { 22 | t.Error(err) 23 | return 24 | } 25 | 26 | if len(scv2.Certs) != 2 { 27 | t.Error("Expected one essCertIDv2") 28 | return 29 | } 30 | 31 | // Check against the cert hash from openssl asn1parse 32 | if hex.EncodeToString(scv2.Certs[0].CertHash) != "5ddfa71077647b6a450869fb25e8b95fc10b72eafaabb6665cca2b982ce4a350" { 33 | t.Error("Unxpected certificate hash") 34 | } 35 | if hex.EncodeToString(scv2.Certs[1].CertHash) != "a568649f2cff70ad17a524e4d92daefcef1a1babaad15bf158c2de561f3c6d3d" { 36 | t.Error("Unxpected certificate hash") 37 | } 38 | if hex.EncodeToString(scv2.Certs[1].IssuerSerial.SerialNumber.Bytes()) != "7997d96885a20d8631bce49c6745027ee19ce823" { 39 | t.Error("Unxpected serial number") 40 | } 41 | 42 | // Check if we can parse the issuer name value 43 | var issuerRDN pkix.RDNSequence 44 | if rest, err := asn1.Unmarshal(scv2.Certs[1].IssuerSerial.IssuerName.Name.Bytes, &issuerRDN); err != nil { 45 | t.Error(err) 46 | return 47 | } else if len(rest) != 0 { 48 | t.Error("trailing data after issuer") 49 | } 50 | 51 | var issuer pkix.Name 52 | issuer.FillFromRDNSequence(&issuerRDN) 53 | if len(issuer.Organization) == 0 || issuer.Organization[0] != "Digitorus" { 54 | t.Error("Unexpected issuer organization") 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /timestamp.go: -------------------------------------------------------------------------------- 1 | // Package timestamp implements the Time-Stamp Protocol (TSP) as specified in 2 | // RFC3161 (Internet X.509 Public Key Infrastructure Time-Stamp Protocol (TSP)). 3 | package timestamp 4 | 5 | import ( 6 | "crypto" 7 | "crypto/rand" 8 | "crypto/x509" 9 | "crypto/x509/pkix" 10 | "encoding/asn1" 11 | "fmt" 12 | "io" 13 | "math/big" 14 | "strconv" 15 | "strings" 16 | "time" 17 | 18 | "github.com/digitorus/pkcs7" 19 | ) 20 | 21 | // FailureInfo contains the failure details of an Time-Stamp request. See 22 | // https://tools.ietf.org/html/rfc3161#section-2.4.2 23 | type FailureInfo int 24 | 25 | const ( 26 | // UnknownFailureInfo mean that no known failure info was provided 27 | UnknownFailureInfo FailureInfo = -1 28 | // BadAlgorithm defines an unrecognized or unsupported Algorithm Identifier 29 | BadAlgorithm FailureInfo = 0 30 | // BadRequest indicates that the transaction not permitted or supported 31 | BadRequest FailureInfo = 2 32 | // BadDataFormat means tha data submitted has the wrong format 33 | BadDataFormat FailureInfo = 5 34 | // TimeNotAvailable indicates that TSA's time source is not available 35 | TimeNotAvailable FailureInfo = 14 36 | // UnacceptedPolicy indicates that the requested TSA policy is not supported 37 | // by the TSA 38 | UnacceptedPolicy FailureInfo = 15 39 | // UnacceptedExtension indicates that the requested extension is not supported 40 | // by the TSA 41 | UnacceptedExtension FailureInfo = 16 42 | // AddInfoNotAvailable means that the information requested could not be 43 | // understood or is not available 44 | AddInfoNotAvailable FailureInfo = 17 45 | // SystemFailure indicates that the request cannot be handled due to system 46 | // failure 47 | SystemFailure FailureInfo = 25 48 | ) 49 | 50 | func (f FailureInfo) String() string { 51 | switch f { 52 | case BadAlgorithm: 53 | return "unrecognized or unsupported Algorithm Identifier" 54 | case BadRequest: 55 | return "transaction not permitted or supported" 56 | case BadDataFormat: 57 | return "the data submitted has the wrong format" 58 | case TimeNotAvailable: 59 | return "the TSA's time source is not available" 60 | case UnacceptedPolicy: 61 | return "the requested TSA policy is not supported by the TSA" 62 | case UnacceptedExtension: 63 | return "the requested extension is not supported by the TSA" 64 | case AddInfoNotAvailable: 65 | return "the additional information requested could not be understood or is not available" 66 | case SystemFailure: 67 | return "the request cannot be handled due to system failure" 68 | default: 69 | return "unknown failure" 70 | } 71 | } 72 | 73 | // Status contains the status of an Time-Stamp request. See 74 | // https://tools.ietf.org/html/rfc3161#section-2.4.2 75 | type Status int 76 | 77 | const ( 78 | // Granted PKIStatus contains the value zero a TimeStampToken, as requested, 79 | // is present. 80 | Granted Status = 0 81 | // GrantedWithMods PKIStatus contains the value one a TimeStampToken, with 82 | // modifications, is present. 83 | GrantedWithMods Status = 1 84 | // Rejection PKIStatus 85 | Rejection Status = 2 86 | // Waiting PKIStatus 87 | Waiting Status = 3 88 | // RevocationWarning PKIStatus 89 | RevocationWarning Status = 4 90 | // RevocationNotification PKIStatus 91 | RevocationNotification Status = 5 92 | ) 93 | 94 | func (s Status) String() string { 95 | switch s { 96 | case Granted: 97 | return "the request is granted" 98 | case GrantedWithMods: 99 | return "the request is granted with modifications" 100 | case Rejection: 101 | return "the request is rejected" 102 | case Waiting: 103 | return "the request is waiting" 104 | case RevocationWarning: 105 | return "revocation is imminent" 106 | case RevocationNotification: 107 | return "revocation has occurred" 108 | default: 109 | return "unknown status: " + strconv.Itoa(int(s)) 110 | } 111 | } 112 | 113 | // ParseError results from an invalid Time-Stamp request or response. 114 | type ParseError string 115 | 116 | func (p ParseError) Error() string { 117 | return string(p) 118 | } 119 | 120 | // Request represents an Time-Stamp request. See 121 | // https://tools.ietf.org/html/rfc3161#section-2.4.1 122 | type Request struct { 123 | HashAlgorithm crypto.Hash 124 | HashedMessage []byte 125 | 126 | // Certificates indicates if the TSA needs to return the signing certificate 127 | // and optionally any other certificates of the chain as part of the response. 128 | Certificates bool 129 | 130 | // The TSAPolicyOID field, if provided, indicates the TSA policy under 131 | // which the TimeStampToken SHOULD be provided 132 | TSAPolicyOID asn1.ObjectIdentifier 133 | 134 | // The nonce, if provided, allows the client to verify the timeliness of 135 | // the response. 136 | Nonce *big.Int 137 | 138 | // Extensions contains raw X.509 extensions from the Extensions field of the 139 | // Time-Stamp request. When parsing requests, this can be used to extract 140 | // non-critical extensions that are not parsed by this package. When 141 | // marshaling OCSP requests, the Extensions field is ignored, see 142 | // ExtraExtensions. 143 | Extensions []pkix.Extension 144 | 145 | // ExtraExtensions contains extensions to be copied, raw, into any marshaled 146 | // OCSP response (in the singleExtensions field). Values override any 147 | // extensions that would otherwise be produced based on the other fields. The 148 | // ExtraExtensions field is not populated when parsing Time-Stamp requests, 149 | // see Extensions. 150 | ExtraExtensions []pkix.Extension 151 | } 152 | 153 | // ParseRequest parses an timestamp request in DER form. 154 | func ParseRequest(bytes []byte) (*Request, error) { 155 | var err error 156 | var rest []byte 157 | var req request 158 | 159 | if rest, err = asn1.Unmarshal(bytes, &req); err != nil { 160 | return nil, err 161 | } 162 | if len(rest) > 0 { 163 | return nil, ParseError("trailing data in Time-Stamp request") 164 | } 165 | 166 | if len(req.MessageImprint.HashedMessage) == 0 { 167 | return nil, ParseError("Time-Stamp request contains no hashed message") 168 | } 169 | 170 | hashFunc := getHashAlgorithmFromOID(req.MessageImprint.HashAlgorithm.Algorithm) 171 | if hashFunc == crypto.Hash(0) { 172 | return nil, ParseError("Time-Stamp request uses unknown hash function") 173 | } 174 | 175 | return &Request{ 176 | HashAlgorithm: hashFunc, 177 | HashedMessage: req.MessageImprint.HashedMessage, 178 | Certificates: req.CertReq, 179 | Nonce: req.Nonce, 180 | TSAPolicyOID: req.ReqPolicy, 181 | Extensions: req.Extensions, 182 | }, nil 183 | } 184 | 185 | // Marshal marshals the Time-Stamp request to ASN.1 DER encoded form. 186 | func (req *Request) Marshal() ([]byte, error) { 187 | request := request{ 188 | Version: 1, 189 | MessageImprint: messageImprint{ 190 | HashAlgorithm: pkix.AlgorithmIdentifier{ 191 | Algorithm: getOIDFromHashAlgorithm(req.HashAlgorithm), 192 | Parameters: asn1.RawValue{ 193 | Tag: 5, /* ASN.1 NULL */ 194 | }, 195 | }, 196 | HashedMessage: req.HashedMessage, 197 | }, 198 | CertReq: req.Certificates, 199 | Extensions: req.ExtraExtensions, 200 | } 201 | 202 | if req.TSAPolicyOID != nil { 203 | request.ReqPolicy = req.TSAPolicyOID 204 | } 205 | if req.Nonce != nil { 206 | request.Nonce = req.Nonce 207 | } 208 | reqBytes, err := asn1.Marshal(request) 209 | if err != nil { 210 | return nil, err 211 | } 212 | return reqBytes, nil 213 | } 214 | 215 | // Timestamp represents an Time-Stamp. See: 216 | // https://tools.ietf.org/html/rfc3161#section-2.4.1 217 | type Timestamp struct { 218 | // Timestamp token part of raw ASN.1 DER content. 219 | RawToken []byte 220 | 221 | HashAlgorithm crypto.Hash 222 | HashedMessage []byte 223 | 224 | Time time.Time 225 | Accuracy time.Duration 226 | SerialNumber *big.Int 227 | Policy asn1.ObjectIdentifier 228 | Ordering bool 229 | Nonce *big.Int 230 | Qualified bool 231 | 232 | Certificates []*x509.Certificate 233 | 234 | // If set to true, includes TSA certificate in timestamp response 235 | AddTSACertificate bool 236 | 237 | // Extensions contains raw X.509 extensions from the Extensions field of the 238 | // Time-Stamp. When parsing time-stamps, this can be used to extract 239 | // non-critical extensions that are not parsed by this package. When 240 | // marshaling time-stamps, the Extensions field is ignored, see 241 | // ExtraExtensions. 242 | Extensions []pkix.Extension 243 | 244 | // ExtraExtensions contains extensions to be copied, raw, into any marshaled 245 | // Time-Stamp response. Values override any extensions that would otherwise 246 | // be produced based on the other fields. The ExtraExtensions field is not 247 | // populated when parsing Time-Stamp responses, see Extensions. 248 | ExtraExtensions []pkix.Extension 249 | } 250 | 251 | // ParseResponse parses an Time-Stamp response in DER form containing a 252 | // TimeStampToken. 253 | // 254 | // Invalid signatures or parse failures will result in a ParseError. Error 255 | // responses will result in a ResponseError. 256 | func ParseResponse(bytes []byte) (*Timestamp, error) { 257 | var err error 258 | var rest []byte 259 | var resp response 260 | 261 | if rest, err = asn1.Unmarshal(bytes, &resp); err != nil { 262 | return nil, err 263 | } 264 | if len(rest) > 0 { 265 | return nil, ParseError("trailing data in Time-Stamp response") 266 | } 267 | 268 | if resp.Status.Status > 0 { 269 | var fis string 270 | fi := resp.Status.FailureInfo() 271 | if fi != UnknownFailureInfo { 272 | fis = fi.String() 273 | } 274 | return nil, fmt.Errorf("%s: %s (%v)", 275 | resp.Status.Status.String(), 276 | strings.Join(resp.Status.StatusString, ","), 277 | fis) 278 | } 279 | 280 | if len(resp.TimeStampToken.Bytes) == 0 { 281 | return nil, ParseError("no pkcs7 data in Time-Stamp response") 282 | } 283 | 284 | return Parse(resp.TimeStampToken.FullBytes) 285 | } 286 | 287 | // Parse parses an Time-Stamp in DER form. If the time-stamp contains a 288 | // certificate then the signature over the response is checked. 289 | // 290 | // Invalid signatures or parse failures will result in a ParseError. Error 291 | // responses will result in a ResponseError. 292 | func Parse(bytes []byte) (*Timestamp, error) { 293 | var addTSACertificate bool 294 | p7, err := pkcs7.Parse(bytes) 295 | if err != nil { 296 | return nil, err 297 | } 298 | 299 | if len(p7.Certificates) > 0 { 300 | if err = p7.Verify(); err != nil { 301 | return nil, err 302 | } 303 | addTSACertificate = true 304 | } else { 305 | addTSACertificate = false 306 | } 307 | 308 | var inf tstInfo 309 | if _, err = asn1.Unmarshal(p7.Content, &inf); err != nil { 310 | return nil, err 311 | } 312 | 313 | if len(inf.MessageImprint.HashedMessage) == 0 { 314 | return nil, ParseError("Time-Stamp response contains no hashed message") 315 | } 316 | 317 | ret := &Timestamp{ 318 | RawToken: bytes, 319 | HashedMessage: inf.MessageImprint.HashedMessage, 320 | Time: inf.Time, 321 | Accuracy: time.Duration((time.Second * time.Duration(inf.Accuracy.Seconds)) + 322 | (time.Millisecond * time.Duration(inf.Accuracy.Milliseconds)) + 323 | (time.Microsecond * time.Duration(inf.Accuracy.Microseconds))), 324 | SerialNumber: inf.SerialNumber, 325 | Policy: inf.Policy, 326 | Ordering: inf.Ordering, 327 | Nonce: inf.Nonce, 328 | Certificates: p7.Certificates, 329 | AddTSACertificate: addTSACertificate, 330 | Extensions: inf.Extensions, 331 | } 332 | 333 | ret.HashAlgorithm = getHashAlgorithmFromOID(inf.MessageImprint.HashAlgorithm.Algorithm) 334 | if ret.HashAlgorithm == crypto.Hash(0) { 335 | return nil, ParseError("Time-Stamp response uses unknown hash function") 336 | } 337 | 338 | if oidInExtensions(asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 1, 3}, inf.Extensions) { 339 | ret.Qualified = true 340 | } 341 | return ret, nil 342 | } 343 | 344 | // RequestOptions contains options for constructing timestamp requests. 345 | type RequestOptions struct { 346 | // Hash contains the hash function that should be used when 347 | // constructing the timestamp request. If zero, SHA-256 will be used. 348 | Hash crypto.Hash 349 | 350 | // Certificates sets Request.Certificates 351 | Certificates bool 352 | 353 | // The TSAPolicyOID field, if provided, indicates the TSA policy under 354 | // which the TimeStampToken SHOULD be provided 355 | TSAPolicyOID asn1.ObjectIdentifier 356 | 357 | // The nonce, if provided, allows the client to verify the timeliness of 358 | // the response. 359 | Nonce *big.Int 360 | } 361 | 362 | func (opts *RequestOptions) hash() crypto.Hash { 363 | if opts == nil || opts.Hash == 0 { 364 | return crypto.SHA256 365 | } 366 | return opts.Hash 367 | } 368 | 369 | // CreateRequest returns a DER-encoded, timestamp request for the status of cert. If 370 | // opts is nil then sensible defaults are used. 371 | func CreateRequest(r io.Reader, opts *RequestOptions) ([]byte, error) { 372 | hashFunc := opts.hash() 373 | 374 | if !hashFunc.Available() { 375 | return nil, x509.ErrUnsupportedAlgorithm 376 | } 377 | h := opts.hash().New() 378 | 379 | b := make([]byte, h.Size()) 380 | for { 381 | n, err := r.Read(b) 382 | if err == io.EOF { 383 | break 384 | } 385 | 386 | _, err = h.Write(b[:n]) 387 | if err != nil { 388 | return nil, fmt.Errorf("failed to create hash") 389 | } 390 | } 391 | 392 | req := &Request{ 393 | HashAlgorithm: opts.hash(), 394 | HashedMessage: h.Sum(nil), 395 | } 396 | if opts != nil { 397 | req.Certificates = opts.Certificates 398 | } 399 | if opts != nil && opts.TSAPolicyOID != nil { 400 | req.TSAPolicyOID = opts.TSAPolicyOID 401 | } 402 | if opts != nil && opts.Nonce != nil { 403 | req.Nonce = opts.Nonce 404 | } 405 | return req.Marshal() 406 | } 407 | 408 | // CreateResponseWithOpts returns a DER-encoded timestamp response with the specified contents. 409 | // The fields in the response are populated as follows: 410 | // 411 | // The responder cert is used to populate the responder's name field, and the 412 | // certificate itself is provided alongside the timestamp response signature. 413 | func (t *Timestamp) CreateResponseWithOpts(signingCert *x509.Certificate, priv crypto.Signer, opts crypto.SignerOpts) ([]byte, error) { 414 | messageImprint := getMessageImprint(t.HashAlgorithm, t.HashedMessage) 415 | 416 | tsaSerialNumber, err := generateTSASerialNumber() 417 | if err != nil { 418 | return nil, err 419 | } 420 | tstInfo, err := t.populateTSTInfo(messageImprint, t.Policy, tsaSerialNumber, signingCert) 421 | if err != nil { 422 | return nil, err 423 | } 424 | signature, err := t.generateSignedData(tstInfo, priv, signingCert, opts) 425 | if err != nil { 426 | return nil, err 427 | } 428 | timestampRes := response{ 429 | Status: pkiStatusInfo{ 430 | Status: Granted, 431 | }, 432 | TimeStampToken: asn1.RawValue{FullBytes: signature}, 433 | } 434 | tspResponseBytes, err := asn1.Marshal(timestampRes) 435 | if err != nil { 436 | return nil, err 437 | } 438 | return tspResponseBytes, nil 439 | } 440 | 441 | // CreateResponse returns a DER-encoded timestamp response with the specified contents. 442 | // The fields in the response are populated as follows: 443 | // 444 | // The responder cert is used to populate the responder's name field, and the 445 | // certificate itself is provided alongside the timestamp response signature. 446 | // 447 | // This function is equivalent to CreateResponseWithOpts, using a SHA256 hash. 448 | // 449 | // Deprecated: Use CreateResponseWithOpts instead. 450 | func (t *Timestamp) CreateResponse(signingCert *x509.Certificate, priv crypto.Signer) ([]byte, error) { 451 | return t.CreateResponseWithOpts(signingCert, priv, crypto.SHA256) 452 | } 453 | 454 | // CreateErrorResponse is used to create response other than granted and granted with mod status 455 | func CreateErrorResponse(pkiStatus Status, pkiFailureInfo FailureInfo) ([]byte, error) { 456 | var bs asn1.BitString 457 | setFlag(&bs, int(pkiFailureInfo)) 458 | 459 | timestampRes := response{ 460 | Status: pkiStatusInfo{ 461 | Status: pkiStatus, 462 | FailInfo: bs, 463 | }, 464 | } 465 | tspResponseBytes, err := asn1.Marshal(timestampRes) 466 | if err != nil { 467 | return nil, err 468 | } 469 | return tspResponseBytes, nil 470 | } 471 | 472 | func setFlag(bs *asn1.BitString, i int) { 473 | for l := len(bs.Bytes); l < 4; l++ { 474 | (*bs).Bytes = append((*bs).Bytes, byte(0)) 475 | (*bs).BitLength = len((*bs).Bytes) * 8 476 | } 477 | b := i / 8 478 | p := uint(7 - (i - 8*b)) 479 | (*bs).Bytes[b] = (*bs).Bytes[b] | (1 << p) 480 | bs.BitLength = asn1BitLength(bs.Bytes) 481 | bs.Bytes = bs.Bytes[0 : (bs.BitLength/8)+1] 482 | } 483 | 484 | func getMessageImprint(hashAlgorithm crypto.Hash, hashedMessage []byte) messageImprint { 485 | messageImprint := messageImprint{ 486 | HashAlgorithm: pkix.AlgorithmIdentifier{ 487 | Algorithm: getOIDFromHashAlgorithm(hashAlgorithm), 488 | Parameters: asn1.NullRawValue, 489 | }, 490 | HashedMessage: hashedMessage, 491 | } 492 | return messageImprint 493 | } 494 | 495 | func generateTSASerialNumber() (*big.Int, error) { 496 | randomBytes := make([]byte, 20) 497 | _, err := rand.Read(randomBytes) 498 | if err != nil { 499 | return nil, err 500 | } 501 | serialNumber := big.NewInt(0) 502 | serialNumber = serialNumber.SetBytes(randomBytes) 503 | return serialNumber, nil 504 | } 505 | 506 | func (t *Timestamp) populateTSTInfo(messageImprint messageImprint, policyOID asn1.ObjectIdentifier, tsaSerialNumber *big.Int, tsaCert *x509.Certificate) ([]byte, error) { 507 | dirGeneralName, err := asn1.Marshal(asn1.RawValue{Tag: 4, Class: 2, IsCompound: true, Bytes: tsaCert.RawSubject}) 508 | if err != nil { 509 | return nil, err 510 | } 511 | tstInfo := tstInfo{ 512 | Version: 1, 513 | Policy: policyOID, 514 | MessageImprint: messageImprint, 515 | SerialNumber: tsaSerialNumber, 516 | Time: t.Time, 517 | TSA: asn1.RawValue{Tag: 0, Class: 2, IsCompound: true, Bytes: dirGeneralName}, 518 | Ordering: t.Ordering, 519 | } 520 | if t.Nonce != nil { 521 | tstInfo.Nonce = t.Nonce 522 | } 523 | if t.Accuracy != 0 { 524 | if t.Accuracy < time.Microsecond { 525 | // Round up to 1 microsecond if accuracy is lower than 1 microsecond but greater than 0 nanosecond 526 | tstInfo.Accuracy.Microseconds = 1 527 | } else { 528 | seconds := t.Accuracy.Truncate(time.Second) 529 | tstInfo.Accuracy.Seconds = int64(seconds.Seconds()) 530 | ms := (t.Accuracy - seconds).Truncate(time.Millisecond) 531 | if ms != 0 { 532 | tstInfo.Accuracy.Milliseconds = int64(ms.Milliseconds()) 533 | } 534 | microSeconds := (t.Accuracy - seconds - ms).Truncate(time.Microsecond) 535 | if microSeconds != 0 { 536 | tstInfo.Accuracy.Microseconds = int64(microSeconds.Microseconds()) 537 | } 538 | } 539 | } 540 | if len(t.ExtraExtensions) != 0 { 541 | tstInfo.Extensions = t.ExtraExtensions 542 | } 543 | if t.Qualified && !oidInExtensions(asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 1, 3}, t.ExtraExtensions) { 544 | qcStatements := []qcStatement{{ 545 | StatementID: asn1.ObjectIdentifier{0, 4, 0, 19422, 1, 1}, 546 | }} 547 | asn1QcStats, err := asn1.Marshal(qcStatements) 548 | if err != nil { 549 | return nil, err 550 | } 551 | tstInfo.Extensions = append(tstInfo.Extensions, pkix.Extension{ 552 | Id: []int{1, 3, 6, 1, 5, 5, 7, 1, 3}, 553 | Value: asn1QcStats, 554 | Critical: false, 555 | }) 556 | } 557 | tstInfoBytes, err := asn1.Marshal(tstInfo) 558 | if err != nil { 559 | return nil, err 560 | } 561 | return tstInfoBytes, nil 562 | } 563 | 564 | func (t *Timestamp) populateSigningCertificateV2Ext(certificate *x509.Certificate) ([]byte, error) { 565 | if !t.HashAlgorithm.Available() { 566 | return nil, x509.ErrUnsupportedAlgorithm 567 | } 568 | if t.HashAlgorithm.HashFunc() == crypto.SHA1 { 569 | return nil, fmt.Errorf("for SHA1 use ESSCertID instead of ESSCertIDv2") 570 | } 571 | 572 | h := t.HashAlgorithm.HashFunc().New() 573 | _, err := h.Write(certificate.Raw) 574 | if err != nil { 575 | return nil, fmt.Errorf("failed to create hash") 576 | } 577 | 578 | var hashAlg pkix.AlgorithmIdentifier 579 | 580 | // HashAlgorithm defaults to SHA256 581 | if t.HashAlgorithm.HashFunc() != crypto.SHA256 { 582 | hashAlg = pkix.AlgorithmIdentifier{ 583 | Algorithm: hashOIDs[t.HashAlgorithm.HashFunc()], 584 | Parameters: asn1.NullRawValue, 585 | } 586 | } 587 | 588 | signingCertificateV2 := signingCertificateV2{ 589 | Certs: []essCertIDv2{{ 590 | HashAlgorithm: hashAlg, 591 | CertHash: h.Sum(nil), 592 | IssuerSerial: issuerAndSerial{ 593 | IssuerName: generalNames{ 594 | Name: asn1.RawValue{Tag: 4, Class: 2, IsCompound: true, Bytes: certificate.RawIssuer}, 595 | }, 596 | SerialNumber: certificate.SerialNumber, 597 | }, 598 | }}, 599 | } 600 | signingCertV2Bytes, err := asn1.Marshal(signingCertificateV2) 601 | if err != nil { 602 | return nil, err 603 | } 604 | return signingCertV2Bytes, nil 605 | } 606 | 607 | // digestAlgorithmToOID converts the hash func to the corresponding OID. 608 | // This should have parity with [pkcs7.getHashForOID]. 609 | func digestAlgorithmToOID(hash crypto.Hash) (asn1.ObjectIdentifier, error) { 610 | switch hash { 611 | case crypto.SHA1: 612 | return pkcs7.OIDDigestAlgorithmSHA1, nil 613 | case crypto.SHA256: 614 | return pkcs7.OIDDigestAlgorithmSHA256, nil 615 | case crypto.SHA384: 616 | return pkcs7.OIDDigestAlgorithmSHA384, nil 617 | case crypto.SHA512: 618 | return pkcs7.OIDDigestAlgorithmSHA512, nil 619 | } 620 | return nil, pkcs7.ErrUnsupportedAlgorithm 621 | } 622 | 623 | func (t *Timestamp) generateSignedData(tstInfo []byte, signer crypto.Signer, certificate *x509.Certificate, opts crypto.SignerOpts) ([]byte, error) { 624 | signedData, err := pkcs7.NewSignedData(tstInfo) 625 | if err != nil { 626 | return nil, err 627 | } 628 | 629 | alg, err := digestAlgorithmToOID(opts.HashFunc()) 630 | if err != nil { 631 | return nil, err 632 | } 633 | signedData.SetDigestAlgorithm(alg) 634 | signedData.SetContentType(asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 9, 16, 1, 4}) 635 | signedData.GetSignedData().Version = 3 636 | 637 | signingCertV2Bytes, err := t.populateSigningCertificateV2Ext(certificate) 638 | if err != nil { 639 | return nil, err 640 | } 641 | 642 | signerInfoConfig := pkcs7.SignerInfoConfig{ 643 | ExtraSignedAttributes: []pkcs7.Attribute{ 644 | { 645 | Type: asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 9, 16, 2, 47}, 646 | Value: asn1.RawValue{FullBytes: signingCertV2Bytes}, 647 | }, 648 | }, 649 | } 650 | if !t.AddTSACertificate { 651 | signerInfoConfig.SkipCertificates = true 652 | } 653 | 654 | if len(t.Certificates) > 0 { 655 | err = signedData.AddSignerChain(certificate, signer, t.Certificates, signerInfoConfig) 656 | } else { 657 | err = signedData.AddSigner(certificate, signer, signerInfoConfig) 658 | } 659 | if err != nil { 660 | return nil, err 661 | } 662 | 663 | signature, err := signedData.Finish() 664 | if err != nil { 665 | return nil, err 666 | } 667 | return signature, nil 668 | } 669 | 670 | // copied from crypto/x509 package 671 | // oidNotInExtensions reports whether an extension with the given oid exists in 672 | // extensions. 673 | func oidInExtensions(oid asn1.ObjectIdentifier, extensions []pkix.Extension) bool { 674 | for _, e := range extensions { 675 | if e.Id.Equal(oid) { 676 | return true 677 | } 678 | } 679 | return false 680 | } 681 | -------------------------------------------------------------------------------- /timestamp_example_test.go: -------------------------------------------------------------------------------- 1 | package timestamp_test 2 | 3 | import ( 4 | "bytes" 5 | "crypto" 6 | "fmt" 7 | "io" 8 | "log" 9 | "net/http" 10 | "strings" 11 | 12 | "github.com/digitorus/timestamp" 13 | ) 14 | 15 | // ExampleCreateRequest_ParseResponse demonstrates the creation of a time-stamp request, sending 16 | // it to the server and parsing the response. 17 | // nolint: govet 18 | func ExampleCreateRequest_ParseResponse() { 19 | tsq, err := timestamp.CreateRequest(strings.NewReader("ExampleCreateRequestParseResponse"), ×tamp.RequestOptions{ 20 | Hash: crypto.SHA256, 21 | Certificates: true, 22 | }) 23 | if err != nil { 24 | log.Fatal(err) 25 | } 26 | 27 | tsr, err := http.Post("https://freetsa.org/tsr", "application/timestamp-query", bytes.NewReader(tsq)) 28 | if err != nil { 29 | log.Fatal(err) 30 | } 31 | 32 | if tsr.StatusCode > 200 { 33 | log.Fatal(tsr.Status) 34 | } 35 | 36 | resp, err := io.ReadAll(tsr.Body) 37 | if err != nil { 38 | log.Fatal(err) 39 | } 40 | 41 | tsResp, err := timestamp.ParseResponse(resp) 42 | if err != nil { 43 | log.Fatal(err) 44 | } 45 | 46 | fmt.Println(tsResp.HashedMessage) 47 | fmt.Println(tsResp.Policy) 48 | for _, c := range tsResp.Certificates { 49 | fmt.Println(c.Subject.Organization, c.Subject.OrganizationalUnit) 50 | } 51 | 52 | // Output: 53 | // [140 222 43 143 28 80 96 97 4 176 145 205 188 119 197 142 149 101 26 96 188 163 178 64 230 162 199 171 176 178 173 128] 54 | // 1.2.3.4.1 55 | // [Free TSA] [TSA] 56 | // [Free TSA] [Root CA] 57 | 58 | } 59 | -------------------------------------------------------------------------------- /timestamp_test.go: -------------------------------------------------------------------------------- 1 | package timestamp 2 | 3 | import ( 4 | "bytes" 5 | "crypto" 6 | "crypto/rsa" 7 | _ "crypto/sha1" 8 | "crypto/sha256" 9 | _ "crypto/sha256" 10 | _ "crypto/sha512" 11 | "crypto/x509" 12 | "encoding/asn1" 13 | "encoding/pem" 14 | "fmt" 15 | "math/big" 16 | "strings" 17 | "testing" 18 | "time" 19 | 20 | "github.com/digitorus/pkcs7" 21 | ) 22 | 23 | // Random data, to create with OpenSSL: 24 | // 25 | // $ openssl rand -base64 32 > data.txt 26 | // 27 | // Contents of our random date in tests below "RhT49MYCgJzWssTF+LXtFZbLD4pe94q4uezLWoTLzyM=" 28 | var hashedMessage = []byte{0xf4, 0x87, 0xd8, 0x81, 0x64, 0xbd, 0xe2, 0x23, 0xb7, 0xfd, 0x3c, 0x71, 0xb3, 0xe9, 0xc6, 0x24, 0xc8, 0xa0, 0xcb, 0x55, 0x9c, 0x85, 0x3b, 0x49, 0x55, 0x8e, 0x7e, 0x5e, 0xf4, 0xce, 0x55, 0xf0} 29 | 30 | // Time-Stamp request with nonce, to create with OpenSSL: 31 | // 32 | // $ openssl ts -query -data data.txt -cert -sha256 -out reqnonoce.tsq 33 | var reqNonce = []byte{0x30, 0x43, 0x2, 0x1, 0x1, 0x30, 0x31, 0x30, 0xd, 0x6, 0x9, 0x60, 0x86, 0x48, 0x1, 0x65, 0x3, 0x4, 0x2, 0x1, 0x5, 0x0, 0x4, 0x20, 0xf4, 0x87, 0xd8, 0x81, 0x64, 0xbd, 0xe2, 0x23, 0xb7, 0xfd, 0x3c, 0x71, 0xb3, 0xe9, 0xc6, 0x24, 0xc8, 0xa0, 0xcb, 0x55, 0x9c, 0x85, 0x3b, 0x49, 0x55, 0x8e, 0x7e, 0x5e, 0xf4, 0xce, 0x55, 0xf0, 0x2, 0x8, 0x9, 0x2e, 0xf1, 0x9f, 0xfb, 0x5d, 0x2a, 0xe8, 0x1, 0x1, 0xff} 34 | 35 | var respNonce = []byte{0x30, 0x82, 0xe, 0x35, 0x30, 0x3, 0x2, 0x1, 0x0, 0x30, 0x82, 0xe, 0x2c, 0x6, 0x9, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0xd, 0x1, 0x7, 0x2, 0xa0, 0x82, 0xe, 0x1d, 0x30, 0x82, 0xe, 0x19, 0x2, 0x1, 0x3, 0x31, 0xf, 0x30, 0xd, 0x6, 0x9, 0x60, 0x86, 0x48, 0x1, 0x65, 0x3, 0x4, 0x2, 0x1, 0x5, 0x0, 0x30, 0x81, 0xed, 0x6, 0xb, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0xd, 0x1, 0x9, 0x10, 0x1, 0x4, 0xa0, 0x81, 0xdd, 0x4, 0x81, 0xda, 0x30, 0x81, 0xd7, 0x2, 0x1, 0x1, 0x6, 0x9, 0x2b, 0x6, 0x1, 0x4, 0x1, 0xa0, 0x32, 0x2, 0x1, 0x30, 0x31, 0x30, 0xd, 0x6, 0x9, 0x60, 0x86, 0x48, 0x1, 0x65, 0x3, 0x4, 0x2, 0x1, 0x5, 0x0, 0x4, 0x20, 0xf4, 0x87, 0xd8, 0x81, 0x64, 0xbd, 0xe2, 0x23, 0xb7, 0xfd, 0x3c, 0x71, 0xb3, 0xe9, 0xc6, 0x24, 0xc8, 0xa0, 0xcb, 0x55, 0x9c, 0x85, 0x3b, 0x49, 0x55, 0x8e, 0x7e, 0x5e, 0xf4, 0xce, 0x55, 0xf0, 0x2, 0x14, 0x5, 0xee, 0xb0, 0xc5, 0x78, 0x43, 0x5b, 0xa7, 0x17, 0x90, 0x39, 0x4f, 0xeb, 0xb8, 0x21, 0x67, 0xb3, 0x64, 0x4c, 0xcc, 0x18, 0xf, 0x32, 0x30, 0x31, 0x37, 0x30, 0x34, 0x31, 0x39, 0x30, 0x36, 0x32, 0x39, 0x35, 0x33, 0x5a, 0x30, 0x3, 0x2, 0x1, 0x1, 0x2, 0x8, 0x9, 0x2e, 0xf1, 0x9f, 0xfb, 0x5d, 0x2a, 0xe8, 0xa0, 0x5e, 0xa4, 0x5c, 0x30, 0x5a, 0x31, 0xb, 0x30, 0x9, 0x6, 0x3, 0x55, 0x4, 0x6, 0x13, 0x2, 0x53, 0x47, 0x31, 0x1f, 0x30, 0x1d, 0x6, 0x3, 0x55, 0x4, 0xa, 0x13, 0x16, 0x47, 0x4d, 0x4f, 0x20, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x50, 0x74, 0x65, 0x20, 0x4c, 0x74, 0x64, 0x31, 0x2a, 0x30, 0x28, 0x6, 0x3, 0x55, 0x4, 0x3, 0x13, 0x21, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x54, 0x53, 0x41, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x41, 0x64, 0x6f, 0x62, 0x65, 0x20, 0x43, 0x44, 0x53, 0x20, 0x2d, 0x20, 0x47, 0x32, 0xa0, 0x82, 0xa, 0x47, 0x30, 0x82, 0x5, 0x47, 0x30, 0x82, 0x4, 0x2f, 0xa0, 0x3, 0x2, 0x1, 0x2, 0x2, 0x12, 0x11, 0x21, 0xd2, 0xd1, 0x82, 0xa, 0xf0, 0xa5, 0xc5, 0x48, 0x14, 0x9a, 0x32, 0x74, 0xdc, 0xc3, 0x43, 0x57, 0x30, 0xd, 0x6, 0x9, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0xd, 0x1, 0x1, 0xb, 0x5, 0x0, 0x30, 0x72, 0x31, 0xb, 0x30, 0x9, 0x6, 0x3, 0x55, 0x4, 0x6, 0x13, 0x2, 0x42, 0x45, 0x31, 0x19, 0x30, 0x17, 0x6, 0x3, 0x55, 0x4, 0xa, 0x13, 0x10, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x6e, 0x76, 0x2d, 0x73, 0x61, 0x31, 0x17, 0x30, 0x15, 0x6, 0x3, 0x55, 0x4, 0xb, 0x13, 0xe, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x44, 0x53, 0x31, 0x2f, 0x30, 0x2d, 0x6, 0x3, 0x55, 0x4, 0x3, 0x13, 0x26, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x20, 0x43, 0x41, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x41, 0x64, 0x6f, 0x62, 0x65, 0x30, 0x1e, 0x17, 0xd, 0x31, 0x36, 0x30, 0x35, 0x32, 0x34, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0xd, 0x32, 0x32, 0x30, 0x35, 0x32, 0x34, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x5a, 0x31, 0xb, 0x30, 0x9, 0x6, 0x3, 0x55, 0x4, 0x6, 0x13, 0x2, 0x53, 0x47, 0x31, 0x1f, 0x30, 0x1d, 0x6, 0x3, 0x55, 0x4, 0xa, 0x13, 0x16, 0x47, 0x4d, 0x4f, 0x20, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x50, 0x74, 0x65, 0x20, 0x4c, 0x74, 0x64, 0x31, 0x2a, 0x30, 0x28, 0x6, 0x3, 0x55, 0x4, 0x3, 0x13, 0x21, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x54, 0x53, 0x41, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x41, 0x64, 0x6f, 0x62, 0x65, 0x20, 0x43, 0x44, 0x53, 0x20, 0x2d, 0x20, 0x47, 0x32, 0x30, 0x82, 0x1, 0x22, 0x30, 0xd, 0x6, 0x9, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0xd, 0x1, 0x1, 0x1, 0x5, 0x0, 0x3, 0x82, 0x1, 0xf, 0x0, 0x30, 0x82, 0x1, 0xa, 0x2, 0x82, 0x1, 0x1, 0x0, 0xd7, 0xbc, 0xf9, 0x4f, 0xea, 0xab, 0x40, 0xdf, 0x15, 0x5c, 0xd4, 0xe8, 0xa5, 0x8e, 0x7a, 0x8, 0x2e, 0xc6, 0x15, 0xea, 0xa, 0xc, 0x69, 0x94, 0xae, 0x9, 0xc2, 0xe2, 0x86, 0xc, 0xf4, 0xed, 0x18, 0x60, 0x5b, 0x9f, 0x28, 0x9b, 0x6c, 0xdb, 0xf3, 0xa7, 0x55, 0x2b, 0xd7, 0x5, 0x5e, 0x81, 0xd0, 0xed, 0xe6, 0xf4, 0xe2, 0xb8, 0x28, 0x12, 0x46, 0xa7, 0x27, 0xfd, 0x8a, 0x89, 0x65, 0x5e, 0x1a, 0x4b, 0x58, 0x67, 0xbc, 0x10, 0xa9, 0x2b, 0x4c, 0x5e, 0xb0, 0x85, 0xdf, 0x7f, 0x59, 0x6c, 0x9e, 0x8c, 0xe1, 0xb9, 0x5f, 0x8f, 0x70, 0x4f, 0xf9, 0x58, 0x0, 0x70, 0x78, 0x2a, 0xcb, 0xd5, 0x36, 0x15, 0xb1, 0xe8, 0xc0, 0x62, 0xa5, 0x7a, 0xe2, 0x6b, 0xa7, 0x90, 0xa5, 0x1, 0x95, 0x6c, 0xa6, 0x8c, 0xea, 0x2a, 0x8a, 0xe5, 0x2a, 0x3e, 0xd3, 0x42, 0xbc, 0x8e, 0x5a, 0xb1, 0x18, 0x18, 0x71, 0x4c, 0x84, 0x7c, 0xaf, 0xf5, 0xb, 0x49, 0x1c, 0x16, 0xf6, 0x50, 0xf9, 0xaf, 0xb0, 0x20, 0x4f, 0x40, 0x49, 0x35, 0xe5, 0x5, 0x9b, 0xaf, 0x6, 0x6f, 0xca, 0x89, 0xb8, 0xe8, 0xae, 0x92, 0x18, 0xb1, 0xb2, 0x56, 0xf1, 0xad, 0x70, 0x94, 0x96, 0x47, 0xea, 0xeb, 0x4f, 0x26, 0x1, 0x5a, 0xd2, 0x65, 0xeb, 0x25, 0xd0, 0x19, 0xb, 0x22, 0x3c, 0xb0, 0x2e, 0x7b, 0x88, 0x92, 0x9, 0x1a, 0xb3, 0xf9, 0x80, 0xa2, 0x7e, 0x90, 0x78, 0xca, 0x4a, 0x20, 0x8b, 0xc4, 0xd, 0xe9, 0x5f, 0x66, 0xb, 0x5c, 0xac, 0xb2, 0xc4, 0x9c, 0x1b, 0xf7, 0x95, 0x24, 0xdc, 0x13, 0x83, 0x8c, 0x94, 0xc8, 0x57, 0xd8, 0x4f, 0x33, 0xf2, 0xda, 0x5d, 0x73, 0x70, 0x4f, 0x3a, 0xc9, 0xa2, 0x5f, 0x2a, 0x7c, 0x71, 0xc9, 0xc1, 0x4a, 0x5d, 0xe1, 0x98, 0x34, 0x6b, 0xd3, 0xc1, 0x74, 0x15, 0x33, 0x89, 0x93, 0x2, 0x3, 0x1, 0x0, 0x1, 0xa3, 0x82, 0x1, 0xed, 0x30, 0x82, 0x1, 0xe9, 0x30, 0xe, 0x6, 0x3, 0x55, 0x1d, 0xf, 0x1, 0x1, 0xff, 0x4, 0x4, 0x3, 0x2, 0x7, 0x80, 0x30, 0x81, 0xdd, 0x6, 0x3, 0x55, 0x1d, 0x20, 0x4, 0x81, 0xd5, 0x30, 0x81, 0xd2, 0x30, 0x81, 0xcf, 0x6, 0x9, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x2f, 0x1, 0x2, 0x1, 0x30, 0x81, 0xc1, 0x30, 0x81, 0x8a, 0x6, 0x8, 0x2b, 0x6, 0x1, 0x5, 0x5, 0x7, 0x2, 0x2, 0x30, 0x7e, 0xc, 0x7c, 0x54, 0x68, 0x69, 0x73, 0x20, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x68, 0x61, 0x73, 0x20, 0x62, 0x65, 0x65, 0x6e, 0x20, 0x69, 0x73, 0x73, 0x75, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x20, 0x61, 0x63, 0x63, 0x6f, 0x72, 0x64, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x44, 0x53, 0x20, 0x43, 0x50, 0x53, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x65, 0x64, 0x20, 0x61, 0x74, 0x20, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x2f, 0x30, 0x32, 0x6, 0x8, 0x2b, 0x6, 0x1, 0x5, 0x5, 0x7, 0x2, 0x1, 0x16, 0x26, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x2f, 0x30, 0x9, 0x6, 0x3, 0x55, 0x1d, 0x13, 0x4, 0x2, 0x30, 0x0, 0x30, 0x16, 0x6, 0x3, 0x55, 0x1d, 0x25, 0x1, 0x1, 0xff, 0x4, 0xc, 0x30, 0xa, 0x6, 0x8, 0x2b, 0x6, 0x1, 0x5, 0x5, 0x7, 0x3, 0x8, 0x30, 0x40, 0x6, 0x3, 0x55, 0x1d, 0x1f, 0x4, 0x39, 0x30, 0x37, 0x30, 0x35, 0xa0, 0x33, 0xa0, 0x31, 0x86, 0x2f, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x73, 0x2f, 0x67, 0x73, 0x70, 0x72, 0x6d, 0x73, 0x68, 0x61, 0x32, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x52, 0x6, 0x8, 0x2b, 0x6, 0x1, 0x5, 0x5, 0x7, 0x1, 0x1, 0x4, 0x46, 0x30, 0x44, 0x30, 0x42, 0x6, 0x8, 0x2b, 0x6, 0x1, 0x5, 0x5, 0x7, 0x30, 0x2, 0x86, 0x36, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x2e, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x61, 0x63, 0x65, 0x72, 0x74, 0x2f, 0x67, 0x73, 0x70, 0x72, 0x6d, 0x73, 0x68, 0x61, 0x32, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x64, 0x65, 0x72, 0x30, 0x1d, 0x6, 0x3, 0x55, 0x1d, 0xe, 0x4, 0x16, 0x4, 0x14, 0x48, 0x78, 0xeb, 0x96, 0x27, 0x1e, 0x4e, 0xbd, 0xe4, 0x5b, 0x2a, 0x65, 0x11, 0xbb, 0x92, 0x1c, 0xc6, 0x1, 0x96, 0x38, 0x30, 0x1f, 0x6, 0x3, 0x55, 0x1d, 0x23, 0x4, 0x18, 0x30, 0x16, 0x80, 0x14, 0x59, 0xd8, 0x24, 0xc2, 0xcf, 0x6b, 0x6, 0x42, 0xd4, 0x95, 0x76, 0xb5, 0x29, 0x5c, 0xf5, 0xd8, 0x41, 0x2b, 0x24, 0x5f, 0x30, 0xd, 0x6, 0x9, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0xd, 0x1, 0x1, 0xb, 0x5, 0x0, 0x3, 0x82, 0x1, 0x1, 0x0, 0x1b, 0xfa, 0xb9, 0xab, 0x45, 0xab, 0x43, 0x92, 0xf3, 0x67, 0xb2, 0x25, 0xb7, 0x20, 0x94, 0xb2, 0xee, 0x9a, 0xa5, 0xba, 0x78, 0xa4, 0x46, 0xbe, 0x8c, 0x9e, 0x9e, 0xfd, 0xb7, 0xb7, 0x5c, 0x28, 0x65, 0x13, 0xc7, 0x12, 0x38, 0xbf, 0xf6, 0x8c, 0xee, 0xba, 0x21, 0x62, 0x30, 0xa6, 0xbe, 0xfe, 0xb8, 0x16, 0x1f, 0x86, 0x0, 0x1e, 0xa2, 0x65, 0x2c, 0x80, 0xb, 0x15, 0xe2, 0x16, 0x72, 0x5, 0xad, 0x61, 0x9f, 0xd8, 0xca, 0x1d, 0x12, 0xa8, 0x41, 0x5a, 0xc5, 0x3b, 0x3, 0xb9, 0x65, 0xd4, 0xa3, 0x8, 0xcc, 0x4, 0xc0, 0xa8, 0x3, 0x35, 0xe1, 0xfe, 0xfd, 0x3a, 0x98, 0x13, 0x3d, 0x8d, 0xb5, 0x81, 0x7b, 0x36, 0x38, 0xc7, 0xc5, 0x7, 0x29, 0x6d, 0x4, 0x6b, 0x6e, 0x9a, 0xdf, 0x1c, 0x6c, 0x16, 0x73, 0xed, 0x52, 0xfd, 0xf6, 0x24, 0xdf, 0x1, 0x28, 0xae, 0x3, 0xc, 0x66, 0xc5, 0x54, 0x4d, 0xf8, 0x9f, 0xdb, 0x0, 0xa6, 0x94, 0xc4, 0xc7, 0x20, 0x36, 0x49, 0x35, 0x23, 0xbe, 0x1f, 0xbb, 0xa7, 0x17, 0x28, 0xba, 0x1a, 0x27, 0xdf, 0x5f, 0xf4, 0x8e, 0xac, 0x6b, 0xf4, 0x7, 0xa7, 0x8b, 0xf7, 0x1e, 0x90, 0xd7, 0xcc, 0xd, 0xf1, 0x48, 0xec, 0xd5, 0x23, 0xed, 0xcb, 0x5f, 0x11, 0xbe, 0x7, 0x64, 0x67, 0x40, 0x7e, 0xf1, 0x9c, 0x6f, 0xc0, 0xd6, 0xd2, 0xd6, 0x82, 0xb7, 0x39, 0xa1, 0xd3, 0xf7, 0x14, 0xf1, 0x38, 0xdb, 0x86, 0x0, 0xcb, 0x43, 0xdf, 0x3, 0x42, 0x9, 0xd7, 0xaf, 0xed, 0x6, 0xf1, 0xc6, 0x47, 0xe7, 0xbc, 0xae, 0x29, 0xdb, 0x43, 0x7, 0xe2, 0xf5, 0xd1, 0xb3, 0xb0, 0x47, 0xbb, 0x47, 0x6b, 0x3, 0x8f, 0x49, 0x6, 0xc6, 0x8b, 0x92, 0xf5, 0x56, 0x7b, 0xdc, 0xb8, 0x21, 0x5c, 0x52, 0x2, 0x51, 0x1c, 0x7b, 0x9, 0x58, 0x43, 0x59, 0xa9, 0x37, 0x30, 0x82, 0x4, 0xf8, 0x30, 0x82, 0x3, 0xe0, 0xa0, 0x3, 0x2, 0x1, 0x2, 0x2, 0x10, 0x35, 0xfb, 0xe4, 0xfa, 0xdf, 0xe4, 0xb0, 0x92, 0x27, 0x6c, 0x31, 0x9b, 0x99, 0xf8, 0xce, 0xb3, 0x30, 0xd, 0x6, 0x9, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0xd, 0x1, 0x1, 0xb, 0x5, 0x0, 0x30, 0x69, 0x31, 0xb, 0x30, 0x9, 0x6, 0x3, 0x55, 0x4, 0x6, 0x13, 0x2, 0x55, 0x53, 0x31, 0x23, 0x30, 0x21, 0x6, 0x3, 0x55, 0x4, 0xa, 0x13, 0x1a, 0x41, 0x64, 0x6f, 0x62, 0x65, 0x20, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x73, 0x20, 0x49, 0x6e, 0x63, 0x6f, 0x72, 0x70, 0x6f, 0x72, 0x61, 0x74, 0x65, 0x64, 0x31, 0x1d, 0x30, 0x1b, 0x6, 0x3, 0x55, 0x4, 0xb, 0x13, 0x14, 0x41, 0x64, 0x6f, 0x62, 0x65, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x31, 0x16, 0x30, 0x14, 0x6, 0x3, 0x55, 0x4, 0x3, 0x13, 0xd, 0x41, 0x64, 0x6f, 0x62, 0x65, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0xd, 0x31, 0x31, 0x30, 0x35, 0x32, 0x35, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0xd, 0x32, 0x32, 0x30, 0x35, 0x32, 0x34, 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x72, 0x31, 0xb, 0x30, 0x9, 0x6, 0x3, 0x55, 0x4, 0x6, 0x13, 0x2, 0x42, 0x45, 0x31, 0x19, 0x30, 0x17, 0x6, 0x3, 0x55, 0x4, 0xa, 0x13, 0x10, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x6e, 0x76, 0x2d, 0x73, 0x61, 0x31, 0x17, 0x30, 0x15, 0x6, 0x3, 0x55, 0x4, 0xb, 0x13, 0xe, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x44, 0x53, 0x31, 0x2f, 0x30, 0x2d, 0x6, 0x3, 0x55, 0x4, 0x3, 0x13, 0x26, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x20, 0x43, 0x41, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x41, 0x64, 0x6f, 0x62, 0x65, 0x30, 0x82, 0x1, 0x22, 0x30, 0xd, 0x6, 0x9, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0xd, 0x1, 0x1, 0x1, 0x5, 0x0, 0x3, 0x82, 0x1, 0xf, 0x0, 0x30, 0x82, 0x1, 0xa, 0x2, 0x82, 0x1, 0x1, 0x0, 0xc2, 0xc6, 0xb, 0x84, 0x55, 0x5a, 0x96, 0x36, 0x1d, 0x95, 0xe7, 0x88, 0xed, 0xd0, 0x2d, 0x23, 0xb1, 0x2a, 0x37, 0xc4, 0xb, 0x35, 0x7f, 0xc7, 0x4, 0x69, 0x36, 0x90, 0x53, 0xd3, 0x56, 0x5a, 0x13, 0x8, 0x1f, 0xc0, 0xc6, 0x46, 0x38, 0x81, 0x72, 0x76, 0xa7, 0xff, 0x9e, 0x5d, 0xc5, 0x83, 0x52, 0x8a, 0x11, 0x7, 0x5a, 0x8b, 0xb5, 0xb3, 0x1f, 0x37, 0xf4, 0x2f, 0xad, 0x6d, 0x45, 0xef, 0x0, 0x35, 0xad, 0x30, 0xf, 0x3b, 0xda, 0x5c, 0xe2, 0xe6, 0x9f, 0xa9, 0xce, 0xc6, 0x52, 0xc8, 0xf7, 0x56, 0x8b, 0xe1, 0xe1, 0x97, 0x39, 0x66, 0x80, 0x2f, 0x3d, 0x57, 0x2e, 0x6b, 0x89, 0x2d, 0x15, 0x8f, 0x3d, 0x67, 0xe5, 0x51, 0xac, 0x6c, 0xd1, 0x9f, 0xb6, 0xb1, 0x17, 0x84, 0xdb, 0x6c, 0xa0, 0xb2, 0xf4, 0x35, 0x83, 0x36, 0xe6, 0x77, 0x1f, 0x1, 0x67, 0xde, 0x74, 0x37, 0xb9, 0xba, 0x36, 0x40, 0xe5, 0x49, 0x13, 0x4e, 0x33, 0x1a, 0x8c, 0xb2, 0x1, 0x80, 0x8, 0xc0, 0xbc, 0x72, 0xfb, 0x3e, 0x6f, 0x6d, 0x42, 0xa8, 0xe6, 0x64, 0x69, 0xce, 0xbf, 0x15, 0xed, 0xd4, 0x92, 0x89, 0x2d, 0xc0, 0x6e, 0x1b, 0xb, 0x6e, 0x1d, 0xf5, 0xf9, 0x6, 0x9b, 0x8, 0xf2, 0xbf, 0x87, 0xb9, 0xf9, 0xe9, 0xb4, 0x68, 0x55, 0xda, 0x92, 0x24, 0xcc, 0xe5, 0x61, 0x91, 0xee, 0xc6, 0x9e, 0xfc, 0x72, 0x99, 0x72, 0x9, 0x32, 0xf4, 0x3a, 0x63, 0x3d, 0x85, 0xcd, 0x5c, 0x70, 0x57, 0x86, 0x2, 0x4d, 0xa6, 0xf8, 0x63, 0x84, 0xbb, 0x0, 0xc3, 0xe9, 0x7d, 0xda, 0x28, 0xe5, 0xd5, 0x1b, 0x13, 0xf2, 0x96, 0xea, 0x8, 0x91, 0xda, 0x6b, 0xd7, 0x3, 0x40, 0xce, 0x2a, 0x88, 0xfc, 0x9b, 0x9b, 0xf3, 0x2e, 0xfa, 0xab, 0x74, 0x6e, 0x38, 0x55, 0x18, 0x78, 0x9f, 0xf8, 0xa6, 0x64, 0xd2, 0x6d, 0x2, 0x3, 0x1, 0x0, 0x1, 0xa3, 0x82, 0x1, 0x91, 0x30, 0x82, 0x1, 0x8d, 0x30, 0x12, 0x6, 0x3, 0x55, 0x1d, 0x13, 0x1, 0x1, 0xff, 0x4, 0x8, 0x30, 0x6, 0x1, 0x1, 0xff, 0x2, 0x1, 0x1, 0x30, 0x81, 0xe4, 0x6, 0x3, 0x55, 0x1d, 0x20, 0x4, 0x81, 0xdc, 0x30, 0x81, 0xd9, 0x30, 0x81, 0xd6, 0x6, 0x9, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x2f, 0x1, 0x2, 0x1, 0x30, 0x81, 0xc8, 0x30, 0x36, 0x6, 0x8, 0x2b, 0x6, 0x1, 0x5, 0x5, 0x7, 0x2, 0x1, 0x16, 0x2a, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6d, 0x69, 0x73, 0x63, 0x2f, 0x70, 0x6b, 0x69, 0x2f, 0x63, 0x64, 0x73, 0x5f, 0x63, 0x70, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x30, 0x81, 0x8d, 0x6, 0x8, 0x2b, 0x6, 0x1, 0x5, 0x5, 0x7, 0x2, 0x2, 0x30, 0x81, 0x80, 0x1a, 0x7e, 0x54, 0x68, 0x65, 0x20, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x68, 0x61, 0x73, 0x20, 0x62, 0x65, 0x65, 0x6e, 0x20, 0x69, 0x73, 0x73, 0x75, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x20, 0x63, 0x6f, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x20, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0x20, 0x61, 0x74, 0x20, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6d, 0x69, 0x73, 0x63, 0x2f, 0x70, 0x6b, 0x69, 0x2f, 0x63, 0x64, 0x73, 0x5f, 0x63, 0x70, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x30, 0x2d, 0x6, 0x3, 0x55, 0x1d, 0x1f, 0x4, 0x26, 0x30, 0x24, 0x30, 0x22, 0xa0, 0x20, 0xa0, 0x1e, 0x86, 0x1c, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x64, 0x73, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x14, 0x6, 0x3, 0x55, 0x1d, 0x25, 0x4, 0xd, 0x30, 0xb, 0x6, 0x9, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x2f, 0x1, 0x1, 0x5, 0x30, 0xb, 0x6, 0x3, 0x55, 0x1d, 0xf, 0x4, 0x4, 0x3, 0x2, 0x1, 0x6, 0x30, 0x1d, 0x6, 0x3, 0x55, 0x1d, 0xe, 0x4, 0x16, 0x4, 0x14, 0x59, 0xd8, 0x24, 0xc2, 0xcf, 0x6b, 0x6, 0x42, 0xd4, 0x95, 0x76, 0xb5, 0x29, 0x5c, 0xf5, 0xd8, 0x41, 0x2b, 0x24, 0x5f, 0x30, 0x1f, 0x6, 0x3, 0x55, 0x1d, 0x23, 0x4, 0x18, 0x30, 0x16, 0x80, 0x14, 0x82, 0xb7, 0x38, 0x4a, 0x93, 0xaa, 0x9b, 0x10, 0xef, 0x80, 0xbb, 0xd9, 0x54, 0xe2, 0xf1, 0xf, 0xfb, 0x80, 0x9c, 0xde, 0x30, 0xd, 0x6, 0x9, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0xd, 0x1, 0x1, 0xb, 0x5, 0x0, 0x3, 0x82, 0x1, 0x1, 0x0, 0x3, 0x80, 0xd0, 0xb, 0x7e, 0x3e, 0x47, 0x44, 0x8a, 0xc5, 0x38, 0xc5, 0x7e, 0x36, 0x5e, 0xcd, 0x60, 0x82, 0x65, 0x62, 0xf3, 0x86, 0xcc, 0x23, 0xbe, 0x47, 0xd7, 0x75, 0x4, 0xc9, 0xdc, 0x5b, 0x3f, 0x12, 0xd3, 0xdb, 0x26, 0x75, 0x59, 0x1d, 0xb6, 0xd4, 0xa, 0x58, 0x3f, 0x5a, 0xd7, 0x28, 0x14, 0xbf, 0x56, 0x86, 0xbd, 0xba, 0xc2, 0x64, 0x20, 0xc8, 0x6e, 0x7d, 0xa9, 0xe8, 0xde, 0xbd, 0x9f, 0x6, 0xff, 0x18, 0xea, 0x57, 0xa1, 0xd7, 0x80, 0x29, 0x87, 0xe8, 0xd0, 0x7b, 0x57, 0x80, 0x45, 0x68, 0x4f, 0x9, 0xa4, 0x83, 0x4c, 0x2d, 0x73, 0x2a, 0x60, 0xee, 0x55, 0x21, 0x9, 0x2c, 0x95, 0x3f, 0xc3, 0x71, 0xe1, 0xb8, 0xad, 0x9c, 0xab, 0x94, 0x37, 0xec, 0x71, 0x4e, 0x66, 0x4d, 0xe8, 0x20, 0x49, 0x4a, 0xea, 0xc7, 0xd7, 0x3c, 0x96, 0xeb, 0xf, 0xc5, 0xf9, 0xd4, 0x7d, 0x5c, 0x13, 0x81, 0x3a, 0xdf, 0xc3, 0x18, 0xc0, 0x47, 0xae, 0x84, 0xff, 0x12, 0xfd, 0xb8, 0x4, 0xc9, 0x9a, 0x5b, 0x33, 0x83, 0x6e, 0xec, 0x11, 0x2c, 0x35, 0x3, 0x71, 0xac, 0xa5, 0xd1, 0xd3, 0x52, 0xd9, 0x9a, 0x70, 0xcf, 0xfe, 0x9d, 0xc0, 0x7e, 0x3, 0x2d, 0x86, 0xe7, 0x7d, 0x66, 0x10, 0x2c, 0x45, 0x86, 0x37, 0x88, 0x9c, 0xe3, 0xb5, 0x39, 0x9f, 0x1c, 0xb2, 0x67, 0x96, 0x43, 0x3a, 0xc2, 0x2c, 0xcd, 0xfa, 0x3d, 0x9a, 0x4, 0x32, 0x5c, 0xb1, 0x3d, 0xf3, 0x2, 0xb4, 0x31, 0x1, 0x4a, 0xdf, 0x92, 0x5b, 0x7d, 0x5f, 0xb6, 0xd0, 0x7, 0xc, 0x93, 0xae, 0xe5, 0xa9, 0xe2, 0x19, 0xdb, 0xc, 0xa3, 0xf3, 0xc8, 0xb1, 0x14, 0xd, 0x61, 0xb9, 0x3, 0x9e, 0xd3, 0xf4, 0x7, 0x17, 0x2b, 0xd9, 0x4c, 0x70, 0x5e, 0x48, 0x6f, 0xc2, 0xc5, 0x3a, 0x9, 0xb0, 0xed, 0x27, 0x5a, 0x11, 0xcb, 0x31, 0x82, 0x2, 0xc6, 0x30, 0x82, 0x2, 0xc2, 0x2, 0x1, 0x1, 0x30, 0x81, 0x88, 0x30, 0x72, 0x31, 0xb, 0x30, 0x9, 0x6, 0x3, 0x55, 0x4, 0x6, 0x13, 0x2, 0x42, 0x45, 0x31, 0x19, 0x30, 0x17, 0x6, 0x3, 0x55, 0x4, 0xa, 0x13, 0x10, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x6e, 0x76, 0x2d, 0x73, 0x61, 0x31, 0x17, 0x30, 0x15, 0x6, 0x3, 0x55, 0x4, 0xb, 0x13, 0xe, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x44, 0x53, 0x31, 0x2f, 0x30, 0x2d, 0x6, 0x3, 0x55, 0x4, 0x3, 0x13, 0x26, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x20, 0x43, 0x41, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x41, 0x64, 0x6f, 0x62, 0x65, 0x2, 0x12, 0x11, 0x21, 0xd2, 0xd1, 0x82, 0xa, 0xf0, 0xa5, 0xc5, 0x48, 0x14, 0x9a, 0x32, 0x74, 0xdc, 0xc3, 0x43, 0x57, 0x30, 0xd, 0x6, 0x9, 0x60, 0x86, 0x48, 0x1, 0x65, 0x3, 0x4, 0x2, 0x1, 0x5, 0x0, 0xa0, 0x82, 0x1, 0xe, 0x30, 0x1a, 0x6, 0x9, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0xd, 0x1, 0x9, 0x3, 0x31, 0xd, 0x6, 0xb, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0xd, 0x1, 0x9, 0x10, 0x1, 0x4, 0x30, 0x2f, 0x6, 0x9, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0xd, 0x1, 0x9, 0x4, 0x31, 0x22, 0x4, 0x20, 0x98, 0x7a, 0x55, 0x9c, 0x19, 0x83, 0x73, 0xd0, 0xcb, 0xfc, 0xe1, 0x4, 0x40, 0xf, 0x78, 0x77, 0xe, 0xbe, 0x86, 0xe5, 0xe0, 0x67, 0xa, 0x2b, 0xc8, 0x3c, 0x68, 0x75, 0xef, 0x7, 0x6d, 0x99, 0x30, 0x81, 0xbe, 0x6, 0xb, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0xd, 0x1, 0x9, 0x10, 0x2, 0xc, 0x31, 0x81, 0xae, 0x30, 0x81, 0xab, 0x30, 0x81, 0xa8, 0x30, 0x81, 0xa5, 0x4, 0x14, 0xba, 0x64, 0xa3, 0x69, 0x93, 0xb8, 0xb6, 0x4, 0xf7, 0xfe, 0x65, 0xd3, 0x7d, 0x8f, 0x8e, 0x68, 0x96, 0xfc, 0x96, 0xb, 0x30, 0x81, 0x8c, 0x30, 0x76, 0xa4, 0x74, 0x30, 0x72, 0x31, 0xb, 0x30, 0x9, 0x6, 0x3, 0x55, 0x4, 0x6, 0x13, 0x2, 0x42, 0x45, 0x31, 0x19, 0x30, 0x17, 0x6, 0x3, 0x55, 0x4, 0xa, 0x13, 0x10, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x6e, 0x76, 0x2d, 0x73, 0x61, 0x31, 0x17, 0x30, 0x15, 0x6, 0x3, 0x55, 0x4, 0xb, 0x13, 0xe, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x44, 0x53, 0x31, 0x2f, 0x30, 0x2d, 0x6, 0x3, 0x55, 0x4, 0x3, 0x13, 0x26, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x20, 0x43, 0x41, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x41, 0x64, 0x6f, 0x62, 0x65, 0x2, 0x12, 0x11, 0x21, 0xd2, 0xd1, 0x82, 0xa, 0xf0, 0xa5, 0xc5, 0x48, 0x14, 0x9a, 0x32, 0x74, 0xdc, 0xc3, 0x43, 0x57, 0x30, 0xd, 0x6, 0x9, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0xd, 0x1, 0x1, 0x1, 0x5, 0x0, 0x4, 0x82, 0x1, 0x0, 0x92, 0x89, 0xaa, 0x92, 0xf0, 0x29, 0x62, 0x1c, 0xef, 0x19, 0x23, 0xb9, 0x46, 0xc4, 0x7d, 0xe1, 0x89, 0x4e, 0xa3, 0x72, 0xa9, 0xe1, 0xf6, 0xc9, 0x54, 0x8b, 0xc5, 0xab, 0x5a, 0xbb, 0x2c, 0xe, 0x41, 0x63, 0x3, 0x8f, 0xc3, 0xae, 0xf4, 0x46, 0x83, 0x72, 0x96, 0xa0, 0xba, 0xf0, 0xbf, 0x2f, 0xed, 0x47, 0xad, 0xd7, 0x14, 0x6f, 0x57, 0x7d, 0xd3, 0x12, 0xd1, 0xe7, 0x9b, 0xac, 0x48, 0x72, 0xc4, 0x55, 0x3f, 0x55, 0xda, 0xe, 0x91, 0x1d, 0x5b, 0xb3, 0x14, 0x30, 0x2c, 0x29, 0xd3, 0x41, 0x72, 0x17, 0x5e, 0x37, 0x1b, 0xec, 0xfe, 0x6b, 0x4a, 0x98, 0x6b, 0x63, 0x7d, 0x1a, 0x7f, 0x3b, 0x84, 0xc1, 0x55, 0x50, 0x26, 0xa7, 0x1e, 0x5d, 0x9b, 0xea, 0x17, 0x5b, 0xfd, 0x35, 0x41, 0xa1, 0x6a, 0x35, 0xc6, 0xdd, 0x11, 0xc5, 0x4e, 0xae, 0x3c, 0x85, 0x5d, 0x10, 0xb8, 0xe8, 0x8d, 0xf, 0x3d, 0x3c, 0xe8, 0xef, 0x2c, 0xff, 0xac, 0x44, 0x38, 0x85, 0xcc, 0xee, 0xb6, 0xe8, 0xf7, 0xae, 0xaa, 0x97, 0xbd, 0x68, 0x4a, 0xbe, 0x3e, 0xcf, 0xe, 0x71, 0xcd, 0xf3, 0x3e, 0xef, 0xea, 0x20, 0xd5, 0x3c, 0x40, 0xcd, 0x5a, 0x88, 0x7c, 0x16, 0xd4, 0xd8, 0x8, 0xf4, 0x35, 0x6b, 0xca, 0xa8, 0xce, 0x2d, 0x53, 0x99, 0x87, 0xa3, 0x31, 0xd, 0x16, 0xa5, 0x43, 0x1c, 0xff, 0x17, 0x82, 0xd4, 0x39, 0x7, 0xd6, 0xa6, 0xad, 0x2b, 0x1a, 0x48, 0x32, 0x70, 0x5d, 0x8e, 0xfe, 0xe7, 0x54, 0x8b, 0x15, 0xa5, 0x76, 0x2e, 0xa0, 0x2a, 0x9c, 0x4, 0x2e, 0x3e, 0x0, 0x9f, 0xbc, 0x7d, 0xce, 0x71, 0x94, 0x52, 0x5c, 0x6d, 0x78, 0xc5, 0xd2, 0xbc, 0x2e, 0x78, 0x29, 0xb5, 0x95, 0x2a, 0x34, 0x9a, 0x55, 0x60, 0x9a, 0x18, 0x1b, 0xc1, 0x4d, 0x47, 0xc1, 0xa1, 0xe9, 0x16, 0x3b, 0xee, 0x6b, 0xd2} 36 | 37 | // Time-Stamp request without nonce, to create with OpenSSL: 38 | // 39 | // $ openssl ts -query -data data.txt -cert -sha256 -no_nonce -out reqnonoce.tsq 40 | var reqNoNonce = []byte{0x30, 0x39, 0x2, 0x1, 0x1, 0x30, 0x31, 0x30, 0xd, 0x6, 0x9, 0x60, 0x86, 0x48, 0x1, 0x65, 0x3, 0x4, 0x2, 0x1, 0x5, 0x0, 0x4, 0x20, 0xf4, 0x87, 0xd8, 0x81, 0x64, 0xbd, 0xe2, 0x23, 0xb7, 0xfd, 0x3c, 0x71, 0xb3, 0xe9, 0xc6, 0x24, 0xc8, 0xa0, 0xcb, 0x55, 0x9c, 0x85, 0x3b, 0x49, 0x55, 0x8e, 0x7e, 0x5e, 0xf4, 0xce, 0x55, 0xf0, 0x1, 0x1, 0xff} 41 | 42 | var respNoNonce = []byte{0x30, 0x82, 0xe, 0x2b, 0x30, 0x3, 0x2, 0x1, 0x0, 0x30, 0x82, 0xe, 0x22, 0x6, 0x9, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0xd, 0x1, 0x7, 0x2, 0xa0, 0x82, 0xe, 0x13, 0x30, 0x82, 0xe, 0xf, 0x2, 0x1, 0x3, 0x31, 0xf, 0x30, 0xd, 0x6, 0x9, 0x60, 0x86, 0x48, 0x1, 0x65, 0x3, 0x4, 0x2, 0x1, 0x5, 0x0, 0x30, 0x81, 0xe3, 0x6, 0xb, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0xd, 0x1, 0x9, 0x10, 0x1, 0x4, 0xa0, 0x81, 0xd3, 0x4, 0x81, 0xd0, 0x30, 0x81, 0xcd, 0x2, 0x1, 0x1, 0x6, 0x9, 0x2b, 0x6, 0x1, 0x4, 0x1, 0xa0, 0x32, 0x2, 0x1, 0x30, 0x31, 0x30, 0xd, 0x6, 0x9, 0x60, 0x86, 0x48, 0x1, 0x65, 0x3, 0x4, 0x2, 0x1, 0x5, 0x0, 0x4, 0x20, 0xf4, 0x87, 0xd8, 0x81, 0x64, 0xbd, 0xe2, 0x23, 0xb7, 0xfd, 0x3c, 0x71, 0xb3, 0xe9, 0xc6, 0x24, 0xc8, 0xa0, 0xcb, 0x55, 0x9c, 0x85, 0x3b, 0x49, 0x55, 0x8e, 0x7e, 0x5e, 0xf4, 0xce, 0x55, 0xf0, 0x2, 0x14, 0x25, 0x92, 0xb9, 0xa, 0x43, 0x4b, 0x2c, 0x7, 0x99, 0xa6, 0xb0, 0xbc, 0xc4, 0x25, 0x7, 0x9e, 0xa5, 0x6e, 0xe5, 0xf6, 0x18, 0xf, 0x32, 0x30, 0x31, 0x37, 0x30, 0x34, 0x31, 0x39, 0x30, 0x36, 0x32, 0x38, 0x31, 0x33, 0x5a, 0x30, 0x3, 0x2, 0x1, 0x1, 0xa0, 0x5e, 0xa4, 0x5c, 0x30, 0x5a, 0x31, 0xb, 0x30, 0x9, 0x6, 0x3, 0x55, 0x4, 0x6, 0x13, 0x2, 0x53, 0x47, 0x31, 0x1f, 0x30, 0x1d, 0x6, 0x3, 0x55, 0x4, 0xa, 0x13, 0x16, 0x47, 0x4d, 0x4f, 0x20, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x50, 0x74, 0x65, 0x20, 0x4c, 0x74, 0x64, 0x31, 0x2a, 0x30, 0x28, 0x6, 0x3, 0x55, 0x4, 0x3, 0x13, 0x21, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x54, 0x53, 0x41, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x41, 0x64, 0x6f, 0x62, 0x65, 0x20, 0x43, 0x44, 0x53, 0x20, 0x2d, 0x20, 0x47, 0x32, 0xa0, 0x82, 0xa, 0x47, 0x30, 0x82, 0x5, 0x47, 0x30, 0x82, 0x4, 0x2f, 0xa0, 0x3, 0x2, 0x1, 0x2, 0x2, 0x12, 0x11, 0x21, 0xd2, 0xd1, 0x82, 0xa, 0xf0, 0xa5, 0xc5, 0x48, 0x14, 0x9a, 0x32, 0x74, 0xdc, 0xc3, 0x43, 0x57, 0x30, 0xd, 0x6, 0x9, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0xd, 0x1, 0x1, 0xb, 0x5, 0x0, 0x30, 0x72, 0x31, 0xb, 0x30, 0x9, 0x6, 0x3, 0x55, 0x4, 0x6, 0x13, 0x2, 0x42, 0x45, 0x31, 0x19, 0x30, 0x17, 0x6, 0x3, 0x55, 0x4, 0xa, 0x13, 0x10, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x6e, 0x76, 0x2d, 0x73, 0x61, 0x31, 0x17, 0x30, 0x15, 0x6, 0x3, 0x55, 0x4, 0xb, 0x13, 0xe, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x44, 0x53, 0x31, 0x2f, 0x30, 0x2d, 0x6, 0x3, 0x55, 0x4, 0x3, 0x13, 0x26, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x20, 0x43, 0x41, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x41, 0x64, 0x6f, 0x62, 0x65, 0x30, 0x1e, 0x17, 0xd, 0x31, 0x36, 0x30, 0x35, 0x32, 0x34, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0xd, 0x32, 0x32, 0x30, 0x35, 0x32, 0x34, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x5a, 0x31, 0xb, 0x30, 0x9, 0x6, 0x3, 0x55, 0x4, 0x6, 0x13, 0x2, 0x53, 0x47, 0x31, 0x1f, 0x30, 0x1d, 0x6, 0x3, 0x55, 0x4, 0xa, 0x13, 0x16, 0x47, 0x4d, 0x4f, 0x20, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x50, 0x74, 0x65, 0x20, 0x4c, 0x74, 0x64, 0x31, 0x2a, 0x30, 0x28, 0x6, 0x3, 0x55, 0x4, 0x3, 0x13, 0x21, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x54, 0x53, 0x41, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x41, 0x64, 0x6f, 0x62, 0x65, 0x20, 0x43, 0x44, 0x53, 0x20, 0x2d, 0x20, 0x47, 0x32, 0x30, 0x82, 0x1, 0x22, 0x30, 0xd, 0x6, 0x9, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0xd, 0x1, 0x1, 0x1, 0x5, 0x0, 0x3, 0x82, 0x1, 0xf, 0x0, 0x30, 0x82, 0x1, 0xa, 0x2, 0x82, 0x1, 0x1, 0x0, 0xd7, 0xbc, 0xf9, 0x4f, 0xea, 0xab, 0x40, 0xdf, 0x15, 0x5c, 0xd4, 0xe8, 0xa5, 0x8e, 0x7a, 0x8, 0x2e, 0xc6, 0x15, 0xea, 0xa, 0xc, 0x69, 0x94, 0xae, 0x9, 0xc2, 0xe2, 0x86, 0xc, 0xf4, 0xed, 0x18, 0x60, 0x5b, 0x9f, 0x28, 0x9b, 0x6c, 0xdb, 0xf3, 0xa7, 0x55, 0x2b, 0xd7, 0x5, 0x5e, 0x81, 0xd0, 0xed, 0xe6, 0xf4, 0xe2, 0xb8, 0x28, 0x12, 0x46, 0xa7, 0x27, 0xfd, 0x8a, 0x89, 0x65, 0x5e, 0x1a, 0x4b, 0x58, 0x67, 0xbc, 0x10, 0xa9, 0x2b, 0x4c, 0x5e, 0xb0, 0x85, 0xdf, 0x7f, 0x59, 0x6c, 0x9e, 0x8c, 0xe1, 0xb9, 0x5f, 0x8f, 0x70, 0x4f, 0xf9, 0x58, 0x0, 0x70, 0x78, 0x2a, 0xcb, 0xd5, 0x36, 0x15, 0xb1, 0xe8, 0xc0, 0x62, 0xa5, 0x7a, 0xe2, 0x6b, 0xa7, 0x90, 0xa5, 0x1, 0x95, 0x6c, 0xa6, 0x8c, 0xea, 0x2a, 0x8a, 0xe5, 0x2a, 0x3e, 0xd3, 0x42, 0xbc, 0x8e, 0x5a, 0xb1, 0x18, 0x18, 0x71, 0x4c, 0x84, 0x7c, 0xaf, 0xf5, 0xb, 0x49, 0x1c, 0x16, 0xf6, 0x50, 0xf9, 0xaf, 0xb0, 0x20, 0x4f, 0x40, 0x49, 0x35, 0xe5, 0x5, 0x9b, 0xaf, 0x6, 0x6f, 0xca, 0x89, 0xb8, 0xe8, 0xae, 0x92, 0x18, 0xb1, 0xb2, 0x56, 0xf1, 0xad, 0x70, 0x94, 0x96, 0x47, 0xea, 0xeb, 0x4f, 0x26, 0x1, 0x5a, 0xd2, 0x65, 0xeb, 0x25, 0xd0, 0x19, 0xb, 0x22, 0x3c, 0xb0, 0x2e, 0x7b, 0x88, 0x92, 0x9, 0x1a, 0xb3, 0xf9, 0x80, 0xa2, 0x7e, 0x90, 0x78, 0xca, 0x4a, 0x20, 0x8b, 0xc4, 0xd, 0xe9, 0x5f, 0x66, 0xb, 0x5c, 0xac, 0xb2, 0xc4, 0x9c, 0x1b, 0xf7, 0x95, 0x24, 0xdc, 0x13, 0x83, 0x8c, 0x94, 0xc8, 0x57, 0xd8, 0x4f, 0x33, 0xf2, 0xda, 0x5d, 0x73, 0x70, 0x4f, 0x3a, 0xc9, 0xa2, 0x5f, 0x2a, 0x7c, 0x71, 0xc9, 0xc1, 0x4a, 0x5d, 0xe1, 0x98, 0x34, 0x6b, 0xd3, 0xc1, 0x74, 0x15, 0x33, 0x89, 0x93, 0x2, 0x3, 0x1, 0x0, 0x1, 0xa3, 0x82, 0x1, 0xed, 0x30, 0x82, 0x1, 0xe9, 0x30, 0xe, 0x6, 0x3, 0x55, 0x1d, 0xf, 0x1, 0x1, 0xff, 0x4, 0x4, 0x3, 0x2, 0x7, 0x80, 0x30, 0x81, 0xdd, 0x6, 0x3, 0x55, 0x1d, 0x20, 0x4, 0x81, 0xd5, 0x30, 0x81, 0xd2, 0x30, 0x81, 0xcf, 0x6, 0x9, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x2f, 0x1, 0x2, 0x1, 0x30, 0x81, 0xc1, 0x30, 0x81, 0x8a, 0x6, 0x8, 0x2b, 0x6, 0x1, 0x5, 0x5, 0x7, 0x2, 0x2, 0x30, 0x7e, 0xc, 0x7c, 0x54, 0x68, 0x69, 0x73, 0x20, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x68, 0x61, 0x73, 0x20, 0x62, 0x65, 0x65, 0x6e, 0x20, 0x69, 0x73, 0x73, 0x75, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x20, 0x61, 0x63, 0x63, 0x6f, 0x72, 0x64, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x44, 0x53, 0x20, 0x43, 0x50, 0x53, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x65, 0x64, 0x20, 0x61, 0x74, 0x20, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x2f, 0x30, 0x32, 0x6, 0x8, 0x2b, 0x6, 0x1, 0x5, 0x5, 0x7, 0x2, 0x1, 0x16, 0x26, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x2f, 0x30, 0x9, 0x6, 0x3, 0x55, 0x1d, 0x13, 0x4, 0x2, 0x30, 0x0, 0x30, 0x16, 0x6, 0x3, 0x55, 0x1d, 0x25, 0x1, 0x1, 0xff, 0x4, 0xc, 0x30, 0xa, 0x6, 0x8, 0x2b, 0x6, 0x1, 0x5, 0x5, 0x7, 0x3, 0x8, 0x30, 0x40, 0x6, 0x3, 0x55, 0x1d, 0x1f, 0x4, 0x39, 0x30, 0x37, 0x30, 0x35, 0xa0, 0x33, 0xa0, 0x31, 0x86, 0x2f, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x73, 0x2f, 0x67, 0x73, 0x70, 0x72, 0x6d, 0x73, 0x68, 0x61, 0x32, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x52, 0x6, 0x8, 0x2b, 0x6, 0x1, 0x5, 0x5, 0x7, 0x1, 0x1, 0x4, 0x46, 0x30, 0x44, 0x30, 0x42, 0x6, 0x8, 0x2b, 0x6, 0x1, 0x5, 0x5, 0x7, 0x30, 0x2, 0x86, 0x36, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x2e, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x61, 0x63, 0x65, 0x72, 0x74, 0x2f, 0x67, 0x73, 0x70, 0x72, 0x6d, 0x73, 0x68, 0x61, 0x32, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x64, 0x65, 0x72, 0x30, 0x1d, 0x6, 0x3, 0x55, 0x1d, 0xe, 0x4, 0x16, 0x4, 0x14, 0x48, 0x78, 0xeb, 0x96, 0x27, 0x1e, 0x4e, 0xbd, 0xe4, 0x5b, 0x2a, 0x65, 0x11, 0xbb, 0x92, 0x1c, 0xc6, 0x1, 0x96, 0x38, 0x30, 0x1f, 0x6, 0x3, 0x55, 0x1d, 0x23, 0x4, 0x18, 0x30, 0x16, 0x80, 0x14, 0x59, 0xd8, 0x24, 0xc2, 0xcf, 0x6b, 0x6, 0x42, 0xd4, 0x95, 0x76, 0xb5, 0x29, 0x5c, 0xf5, 0xd8, 0x41, 0x2b, 0x24, 0x5f, 0x30, 0xd, 0x6, 0x9, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0xd, 0x1, 0x1, 0xb, 0x5, 0x0, 0x3, 0x82, 0x1, 0x1, 0x0, 0x1b, 0xfa, 0xb9, 0xab, 0x45, 0xab, 0x43, 0x92, 0xf3, 0x67, 0xb2, 0x25, 0xb7, 0x20, 0x94, 0xb2, 0xee, 0x9a, 0xa5, 0xba, 0x78, 0xa4, 0x46, 0xbe, 0x8c, 0x9e, 0x9e, 0xfd, 0xb7, 0xb7, 0x5c, 0x28, 0x65, 0x13, 0xc7, 0x12, 0x38, 0xbf, 0xf6, 0x8c, 0xee, 0xba, 0x21, 0x62, 0x30, 0xa6, 0xbe, 0xfe, 0xb8, 0x16, 0x1f, 0x86, 0x0, 0x1e, 0xa2, 0x65, 0x2c, 0x80, 0xb, 0x15, 0xe2, 0x16, 0x72, 0x5, 0xad, 0x61, 0x9f, 0xd8, 0xca, 0x1d, 0x12, 0xa8, 0x41, 0x5a, 0xc5, 0x3b, 0x3, 0xb9, 0x65, 0xd4, 0xa3, 0x8, 0xcc, 0x4, 0xc0, 0xa8, 0x3, 0x35, 0xe1, 0xfe, 0xfd, 0x3a, 0x98, 0x13, 0x3d, 0x8d, 0xb5, 0x81, 0x7b, 0x36, 0x38, 0xc7, 0xc5, 0x7, 0x29, 0x6d, 0x4, 0x6b, 0x6e, 0x9a, 0xdf, 0x1c, 0x6c, 0x16, 0x73, 0xed, 0x52, 0xfd, 0xf6, 0x24, 0xdf, 0x1, 0x28, 0xae, 0x3, 0xc, 0x66, 0xc5, 0x54, 0x4d, 0xf8, 0x9f, 0xdb, 0x0, 0xa6, 0x94, 0xc4, 0xc7, 0x20, 0x36, 0x49, 0x35, 0x23, 0xbe, 0x1f, 0xbb, 0xa7, 0x17, 0x28, 0xba, 0x1a, 0x27, 0xdf, 0x5f, 0xf4, 0x8e, 0xac, 0x6b, 0xf4, 0x7, 0xa7, 0x8b, 0xf7, 0x1e, 0x90, 0xd7, 0xcc, 0xd, 0xf1, 0x48, 0xec, 0xd5, 0x23, 0xed, 0xcb, 0x5f, 0x11, 0xbe, 0x7, 0x64, 0x67, 0x40, 0x7e, 0xf1, 0x9c, 0x6f, 0xc0, 0xd6, 0xd2, 0xd6, 0x82, 0xb7, 0x39, 0xa1, 0xd3, 0xf7, 0x14, 0xf1, 0x38, 0xdb, 0x86, 0x0, 0xcb, 0x43, 0xdf, 0x3, 0x42, 0x9, 0xd7, 0xaf, 0xed, 0x6, 0xf1, 0xc6, 0x47, 0xe7, 0xbc, 0xae, 0x29, 0xdb, 0x43, 0x7, 0xe2, 0xf5, 0xd1, 0xb3, 0xb0, 0x47, 0xbb, 0x47, 0x6b, 0x3, 0x8f, 0x49, 0x6, 0xc6, 0x8b, 0x92, 0xf5, 0x56, 0x7b, 0xdc, 0xb8, 0x21, 0x5c, 0x52, 0x2, 0x51, 0x1c, 0x7b, 0x9, 0x58, 0x43, 0x59, 0xa9, 0x37, 0x30, 0x82, 0x4, 0xf8, 0x30, 0x82, 0x3, 0xe0, 0xa0, 0x3, 0x2, 0x1, 0x2, 0x2, 0x10, 0x35, 0xfb, 0xe4, 0xfa, 0xdf, 0xe4, 0xb0, 0x92, 0x27, 0x6c, 0x31, 0x9b, 0x99, 0xf8, 0xce, 0xb3, 0x30, 0xd, 0x6, 0x9, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0xd, 0x1, 0x1, 0xb, 0x5, 0x0, 0x30, 0x69, 0x31, 0xb, 0x30, 0x9, 0x6, 0x3, 0x55, 0x4, 0x6, 0x13, 0x2, 0x55, 0x53, 0x31, 0x23, 0x30, 0x21, 0x6, 0x3, 0x55, 0x4, 0xa, 0x13, 0x1a, 0x41, 0x64, 0x6f, 0x62, 0x65, 0x20, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x73, 0x20, 0x49, 0x6e, 0x63, 0x6f, 0x72, 0x70, 0x6f, 0x72, 0x61, 0x74, 0x65, 0x64, 0x31, 0x1d, 0x30, 0x1b, 0x6, 0x3, 0x55, 0x4, 0xb, 0x13, 0x14, 0x41, 0x64, 0x6f, 0x62, 0x65, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x31, 0x16, 0x30, 0x14, 0x6, 0x3, 0x55, 0x4, 0x3, 0x13, 0xd, 0x41, 0x64, 0x6f, 0x62, 0x65, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0xd, 0x31, 0x31, 0x30, 0x35, 0x32, 0x35, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0xd, 0x32, 0x32, 0x30, 0x35, 0x32, 0x34, 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x72, 0x31, 0xb, 0x30, 0x9, 0x6, 0x3, 0x55, 0x4, 0x6, 0x13, 0x2, 0x42, 0x45, 0x31, 0x19, 0x30, 0x17, 0x6, 0x3, 0x55, 0x4, 0xa, 0x13, 0x10, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x6e, 0x76, 0x2d, 0x73, 0x61, 0x31, 0x17, 0x30, 0x15, 0x6, 0x3, 0x55, 0x4, 0xb, 0x13, 0xe, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x44, 0x53, 0x31, 0x2f, 0x30, 0x2d, 0x6, 0x3, 0x55, 0x4, 0x3, 0x13, 0x26, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x20, 0x43, 0x41, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x41, 0x64, 0x6f, 0x62, 0x65, 0x30, 0x82, 0x1, 0x22, 0x30, 0xd, 0x6, 0x9, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0xd, 0x1, 0x1, 0x1, 0x5, 0x0, 0x3, 0x82, 0x1, 0xf, 0x0, 0x30, 0x82, 0x1, 0xa, 0x2, 0x82, 0x1, 0x1, 0x0, 0xc2, 0xc6, 0xb, 0x84, 0x55, 0x5a, 0x96, 0x36, 0x1d, 0x95, 0xe7, 0x88, 0xed, 0xd0, 0x2d, 0x23, 0xb1, 0x2a, 0x37, 0xc4, 0xb, 0x35, 0x7f, 0xc7, 0x4, 0x69, 0x36, 0x90, 0x53, 0xd3, 0x56, 0x5a, 0x13, 0x8, 0x1f, 0xc0, 0xc6, 0x46, 0x38, 0x81, 0x72, 0x76, 0xa7, 0xff, 0x9e, 0x5d, 0xc5, 0x83, 0x52, 0x8a, 0x11, 0x7, 0x5a, 0x8b, 0xb5, 0xb3, 0x1f, 0x37, 0xf4, 0x2f, 0xad, 0x6d, 0x45, 0xef, 0x0, 0x35, 0xad, 0x30, 0xf, 0x3b, 0xda, 0x5c, 0xe2, 0xe6, 0x9f, 0xa9, 0xce, 0xc6, 0x52, 0xc8, 0xf7, 0x56, 0x8b, 0xe1, 0xe1, 0x97, 0x39, 0x66, 0x80, 0x2f, 0x3d, 0x57, 0x2e, 0x6b, 0x89, 0x2d, 0x15, 0x8f, 0x3d, 0x67, 0xe5, 0x51, 0xac, 0x6c, 0xd1, 0x9f, 0xb6, 0xb1, 0x17, 0x84, 0xdb, 0x6c, 0xa0, 0xb2, 0xf4, 0x35, 0x83, 0x36, 0xe6, 0x77, 0x1f, 0x1, 0x67, 0xde, 0x74, 0x37, 0xb9, 0xba, 0x36, 0x40, 0xe5, 0x49, 0x13, 0x4e, 0x33, 0x1a, 0x8c, 0xb2, 0x1, 0x80, 0x8, 0xc0, 0xbc, 0x72, 0xfb, 0x3e, 0x6f, 0x6d, 0x42, 0xa8, 0xe6, 0x64, 0x69, 0xce, 0xbf, 0x15, 0xed, 0xd4, 0x92, 0x89, 0x2d, 0xc0, 0x6e, 0x1b, 0xb, 0x6e, 0x1d, 0xf5, 0xf9, 0x6, 0x9b, 0x8, 0xf2, 0xbf, 0x87, 0xb9, 0xf9, 0xe9, 0xb4, 0x68, 0x55, 0xda, 0x92, 0x24, 0xcc, 0xe5, 0x61, 0x91, 0xee, 0xc6, 0x9e, 0xfc, 0x72, 0x99, 0x72, 0x9, 0x32, 0xf4, 0x3a, 0x63, 0x3d, 0x85, 0xcd, 0x5c, 0x70, 0x57, 0x86, 0x2, 0x4d, 0xa6, 0xf8, 0x63, 0x84, 0xbb, 0x0, 0xc3, 0xe9, 0x7d, 0xda, 0x28, 0xe5, 0xd5, 0x1b, 0x13, 0xf2, 0x96, 0xea, 0x8, 0x91, 0xda, 0x6b, 0xd7, 0x3, 0x40, 0xce, 0x2a, 0x88, 0xfc, 0x9b, 0x9b, 0xf3, 0x2e, 0xfa, 0xab, 0x74, 0x6e, 0x38, 0x55, 0x18, 0x78, 0x9f, 0xf8, 0xa6, 0x64, 0xd2, 0x6d, 0x2, 0x3, 0x1, 0x0, 0x1, 0xa3, 0x82, 0x1, 0x91, 0x30, 0x82, 0x1, 0x8d, 0x30, 0x12, 0x6, 0x3, 0x55, 0x1d, 0x13, 0x1, 0x1, 0xff, 0x4, 0x8, 0x30, 0x6, 0x1, 0x1, 0xff, 0x2, 0x1, 0x1, 0x30, 0x81, 0xe4, 0x6, 0x3, 0x55, 0x1d, 0x20, 0x4, 0x81, 0xdc, 0x30, 0x81, 0xd9, 0x30, 0x81, 0xd6, 0x6, 0x9, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x2f, 0x1, 0x2, 0x1, 0x30, 0x81, 0xc8, 0x30, 0x36, 0x6, 0x8, 0x2b, 0x6, 0x1, 0x5, 0x5, 0x7, 0x2, 0x1, 0x16, 0x2a, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6d, 0x69, 0x73, 0x63, 0x2f, 0x70, 0x6b, 0x69, 0x2f, 0x63, 0x64, 0x73, 0x5f, 0x63, 0x70, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x30, 0x81, 0x8d, 0x6, 0x8, 0x2b, 0x6, 0x1, 0x5, 0x5, 0x7, 0x2, 0x2, 0x30, 0x81, 0x80, 0x1a, 0x7e, 0x54, 0x68, 0x65, 0x20, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x68, 0x61, 0x73, 0x20, 0x62, 0x65, 0x65, 0x6e, 0x20, 0x69, 0x73, 0x73, 0x75, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x20, 0x63, 0x6f, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x20, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0x20, 0x61, 0x74, 0x20, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6d, 0x69, 0x73, 0x63, 0x2f, 0x70, 0x6b, 0x69, 0x2f, 0x63, 0x64, 0x73, 0x5f, 0x63, 0x70, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x30, 0x2d, 0x6, 0x3, 0x55, 0x1d, 0x1f, 0x4, 0x26, 0x30, 0x24, 0x30, 0x22, 0xa0, 0x20, 0xa0, 0x1e, 0x86, 0x1c, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x64, 0x73, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x14, 0x6, 0x3, 0x55, 0x1d, 0x25, 0x4, 0xd, 0x30, 0xb, 0x6, 0x9, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x2f, 0x1, 0x1, 0x5, 0x30, 0xb, 0x6, 0x3, 0x55, 0x1d, 0xf, 0x4, 0x4, 0x3, 0x2, 0x1, 0x6, 0x30, 0x1d, 0x6, 0x3, 0x55, 0x1d, 0xe, 0x4, 0x16, 0x4, 0x14, 0x59, 0xd8, 0x24, 0xc2, 0xcf, 0x6b, 0x6, 0x42, 0xd4, 0x95, 0x76, 0xb5, 0x29, 0x5c, 0xf5, 0xd8, 0x41, 0x2b, 0x24, 0x5f, 0x30, 0x1f, 0x6, 0x3, 0x55, 0x1d, 0x23, 0x4, 0x18, 0x30, 0x16, 0x80, 0x14, 0x82, 0xb7, 0x38, 0x4a, 0x93, 0xaa, 0x9b, 0x10, 0xef, 0x80, 0xbb, 0xd9, 0x54, 0xe2, 0xf1, 0xf, 0xfb, 0x80, 0x9c, 0xde, 0x30, 0xd, 0x6, 0x9, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0xd, 0x1, 0x1, 0xb, 0x5, 0x0, 0x3, 0x82, 0x1, 0x1, 0x0, 0x3, 0x80, 0xd0, 0xb, 0x7e, 0x3e, 0x47, 0x44, 0x8a, 0xc5, 0x38, 0xc5, 0x7e, 0x36, 0x5e, 0xcd, 0x60, 0x82, 0x65, 0x62, 0xf3, 0x86, 0xcc, 0x23, 0xbe, 0x47, 0xd7, 0x75, 0x4, 0xc9, 0xdc, 0x5b, 0x3f, 0x12, 0xd3, 0xdb, 0x26, 0x75, 0x59, 0x1d, 0xb6, 0xd4, 0xa, 0x58, 0x3f, 0x5a, 0xd7, 0x28, 0x14, 0xbf, 0x56, 0x86, 0xbd, 0xba, 0xc2, 0x64, 0x20, 0xc8, 0x6e, 0x7d, 0xa9, 0xe8, 0xde, 0xbd, 0x9f, 0x6, 0xff, 0x18, 0xea, 0x57, 0xa1, 0xd7, 0x80, 0x29, 0x87, 0xe8, 0xd0, 0x7b, 0x57, 0x80, 0x45, 0x68, 0x4f, 0x9, 0xa4, 0x83, 0x4c, 0x2d, 0x73, 0x2a, 0x60, 0xee, 0x55, 0x21, 0x9, 0x2c, 0x95, 0x3f, 0xc3, 0x71, 0xe1, 0xb8, 0xad, 0x9c, 0xab, 0x94, 0x37, 0xec, 0x71, 0x4e, 0x66, 0x4d, 0xe8, 0x20, 0x49, 0x4a, 0xea, 0xc7, 0xd7, 0x3c, 0x96, 0xeb, 0xf, 0xc5, 0xf9, 0xd4, 0x7d, 0x5c, 0x13, 0x81, 0x3a, 0xdf, 0xc3, 0x18, 0xc0, 0x47, 0xae, 0x84, 0xff, 0x12, 0xfd, 0xb8, 0x4, 0xc9, 0x9a, 0x5b, 0x33, 0x83, 0x6e, 0xec, 0x11, 0x2c, 0x35, 0x3, 0x71, 0xac, 0xa5, 0xd1, 0xd3, 0x52, 0xd9, 0x9a, 0x70, 0xcf, 0xfe, 0x9d, 0xc0, 0x7e, 0x3, 0x2d, 0x86, 0xe7, 0x7d, 0x66, 0x10, 0x2c, 0x45, 0x86, 0x37, 0x88, 0x9c, 0xe3, 0xb5, 0x39, 0x9f, 0x1c, 0xb2, 0x67, 0x96, 0x43, 0x3a, 0xc2, 0x2c, 0xcd, 0xfa, 0x3d, 0x9a, 0x4, 0x32, 0x5c, 0xb1, 0x3d, 0xf3, 0x2, 0xb4, 0x31, 0x1, 0x4a, 0xdf, 0x92, 0x5b, 0x7d, 0x5f, 0xb6, 0xd0, 0x7, 0xc, 0x93, 0xae, 0xe5, 0xa9, 0xe2, 0x19, 0xdb, 0xc, 0xa3, 0xf3, 0xc8, 0xb1, 0x14, 0xd, 0x61, 0xb9, 0x3, 0x9e, 0xd3, 0xf4, 0x7, 0x17, 0x2b, 0xd9, 0x4c, 0x70, 0x5e, 0x48, 0x6f, 0xc2, 0xc5, 0x3a, 0x9, 0xb0, 0xed, 0x27, 0x5a, 0x11, 0xcb, 0x31, 0x82, 0x2, 0xc6, 0x30, 0x82, 0x2, 0xc2, 0x2, 0x1, 0x1, 0x30, 0x81, 0x88, 0x30, 0x72, 0x31, 0xb, 0x30, 0x9, 0x6, 0x3, 0x55, 0x4, 0x6, 0x13, 0x2, 0x42, 0x45, 0x31, 0x19, 0x30, 0x17, 0x6, 0x3, 0x55, 0x4, 0xa, 0x13, 0x10, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x6e, 0x76, 0x2d, 0x73, 0x61, 0x31, 0x17, 0x30, 0x15, 0x6, 0x3, 0x55, 0x4, 0xb, 0x13, 0xe, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x44, 0x53, 0x31, 0x2f, 0x30, 0x2d, 0x6, 0x3, 0x55, 0x4, 0x3, 0x13, 0x26, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x20, 0x43, 0x41, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x41, 0x64, 0x6f, 0x62, 0x65, 0x2, 0x12, 0x11, 0x21, 0xd2, 0xd1, 0x82, 0xa, 0xf0, 0xa5, 0xc5, 0x48, 0x14, 0x9a, 0x32, 0x74, 0xdc, 0xc3, 0x43, 0x57, 0x30, 0xd, 0x6, 0x9, 0x60, 0x86, 0x48, 0x1, 0x65, 0x3, 0x4, 0x2, 0x1, 0x5, 0x0, 0xa0, 0x82, 0x1, 0xe, 0x30, 0x1a, 0x6, 0x9, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0xd, 0x1, 0x9, 0x3, 0x31, 0xd, 0x6, 0xb, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0xd, 0x1, 0x9, 0x10, 0x1, 0x4, 0x30, 0x2f, 0x6, 0x9, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0xd, 0x1, 0x9, 0x4, 0x31, 0x22, 0x4, 0x20, 0xb1, 0xcd, 0x2b, 0x8d, 0x14, 0x62, 0xe9, 0x8c, 0x98, 0xa6, 0x47, 0x4c, 0x2d, 0x2d, 0xac, 0x61, 0xbf, 0x32, 0x6a, 0xfb, 0xf5, 0x3b, 0xf8, 0xf1, 0xe7, 0x4a, 0x9a, 0xb7, 0xc3, 0x5b, 0xaa, 0xb, 0x30, 0x81, 0xbe, 0x6, 0xb, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0xd, 0x1, 0x9, 0x10, 0x2, 0xc, 0x31, 0x81, 0xae, 0x30, 0x81, 0xab, 0x30, 0x81, 0xa8, 0x30, 0x81, 0xa5, 0x4, 0x14, 0xba, 0x64, 0xa3, 0x69, 0x93, 0xb8, 0xb6, 0x4, 0xf7, 0xfe, 0x65, 0xd3, 0x7d, 0x8f, 0x8e, 0x68, 0x96, 0xfc, 0x96, 0xb, 0x30, 0x81, 0x8c, 0x30, 0x76, 0xa4, 0x74, 0x30, 0x72, 0x31, 0xb, 0x30, 0x9, 0x6, 0x3, 0x55, 0x4, 0x6, 0x13, 0x2, 0x42, 0x45, 0x31, 0x19, 0x30, 0x17, 0x6, 0x3, 0x55, 0x4, 0xa, 0x13, 0x10, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x6e, 0x76, 0x2d, 0x73, 0x61, 0x31, 0x17, 0x30, 0x15, 0x6, 0x3, 0x55, 0x4, 0xb, 0x13, 0xe, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x44, 0x53, 0x31, 0x2f, 0x30, 0x2d, 0x6, 0x3, 0x55, 0x4, 0x3, 0x13, 0x26, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x20, 0x43, 0x41, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x41, 0x64, 0x6f, 0x62, 0x65, 0x2, 0x12, 0x11, 0x21, 0xd2, 0xd1, 0x82, 0xa, 0xf0, 0xa5, 0xc5, 0x48, 0x14, 0x9a, 0x32, 0x74, 0xdc, 0xc3, 0x43, 0x57, 0x30, 0xd, 0x6, 0x9, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0xd, 0x1, 0x1, 0x1, 0x5, 0x0, 0x4, 0x82, 0x1, 0x0, 0x21, 0xd7, 0xe8, 0x74, 0xba, 0x1, 0xb0, 0xb, 0xc2, 0x57, 0x24, 0x62, 0x7b, 0xbd, 0xfb, 0xf2, 0xaa, 0xeb, 0x30, 0x3b, 0x89, 0x51, 0xb7, 0x7f, 0x96, 0x80, 0x84, 0xff, 0x55, 0xbf, 0x0, 0x36, 0x4c, 0xaf, 0xa2, 0x65, 0x36, 0x26, 0x53, 0xda, 0x4c, 0x19, 0xa4, 0x61, 0x97, 0x6a, 0x8, 0xd1, 0xd9, 0x6d, 0x61, 0x8b, 0x67, 0x6b, 0xc7, 0xc5, 0xbe, 0x46, 0x10, 0x8a, 0xf, 0x53, 0x5e, 0xa8, 0x7, 0x67, 0xe8, 0xf3, 0x3c, 0x3f, 0x95, 0x47, 0xf8, 0xca, 0x50, 0xbe, 0x9e, 0xf7, 0x2f, 0xc2, 0x4d, 0x50, 0xf8, 0xe6, 0xde, 0xe2, 0x9b, 0x61, 0xe0, 0x52, 0xc0, 0x2e, 0x45, 0x4a, 0x29, 0x4f, 0xe2, 0xbb, 0x7, 0xa6, 0xd5, 0xd4, 0xa8, 0x17, 0x90, 0xad, 0xf3, 0xf7, 0xfd, 0x31, 0x2d, 0x29, 0x26, 0x2, 0xd2, 0x9e, 0xdd, 0x9e, 0xd1, 0x8a, 0xa1, 0x25, 0x9b, 0x36, 0x0, 0xbf, 0xe1, 0x96, 0x96, 0xe8, 0x8f, 0x89, 0x57, 0xa3, 0x6f, 0x7f, 0xb0, 0x84, 0x7a, 0x63, 0x63, 0x9c, 0xf1, 0xc6, 0x26, 0x60, 0x97, 0x64, 0xf7, 0xbc, 0x70, 0x69, 0x1b, 0xa5, 0x9d, 0x6d, 0x33, 0x50, 0x58, 0x9e, 0x41, 0xa4, 0x21, 0x5c, 0x2a, 0x53, 0x9c, 0x4c, 0xae, 0x27, 0xfc, 0x8b, 0x92, 0xaf, 0x68, 0xb, 0x58, 0xab, 0x3b, 0x51, 0x9, 0xc, 0xc3, 0x7f, 0xcc, 0x6b, 0x47, 0x7e, 0xb5, 0xe, 0xf8, 0x6e, 0x11, 0xb4, 0x38, 0xdf, 0xeb, 0xfa, 0xaa, 0x33, 0x1e, 0xe2, 0xd6, 0xba, 0x93, 0x2e, 0xf2, 0x2a, 0x8f, 0xaf, 0x5, 0xb7, 0x21, 0x57, 0xda, 0x47, 0x93, 0xc1, 0xc4, 0x52, 0x4e, 0xce, 0xb1, 0x87, 0xc5, 0x56, 0x16, 0x4d, 0x18, 0x6d, 0xcb, 0xde, 0x82, 0xd1, 0x81, 0x80, 0x2f, 0xa8, 0x45, 0x9a, 0x41, 0xe3, 0x29, 0x49, 0x50, 0xbf, 0x9e, 0x32, 0xc0, 0xb7, 0x7e, 0x35, 0x32, 0x8, 0xd5, 0x2a} 43 | 44 | // Time-Stamp request without certificate, to create with OpenSSL: 45 | // 46 | // $ openssl ts -query -data data.txt -sha256 -out reqnonoce.tsq 47 | var reqNoCert = []byte{0x30, 0x41, 0x2, 0x1, 0x1, 0x30, 0x31, 0x30, 0xd, 0x6, 0x9, 0x60, 0x86, 0x48, 0x1, 0x65, 0x3, 0x4, 0x2, 0x1, 0x5, 0x0, 0x4, 0x20, 0xf4, 0x87, 0xd8, 0x81, 0x64, 0xbd, 0xe2, 0x23, 0xb7, 0xfd, 0x3c, 0x71, 0xb3, 0xe9, 0xc6, 0x24, 0xc8, 0xa0, 0xcb, 0x55, 0x9c, 0x85, 0x3b, 0x49, 0x55, 0x8e, 0x7e, 0x5e, 0xf4, 0xce, 0x55, 0xf0, 0x2, 0x9, 0x0, 0xb1, 0xfc, 0x81, 0xde, 0xc9, 0x57, 0x49, 0xd9} 48 | 49 | var respNoCert = []byte{0x30, 0x82, 0x3, 0xeb, 0x30, 0x3, 0x2, 0x1, 0x0, 0x30, 0x82, 0x3, 0xe2, 0x6, 0x9, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0xd, 0x1, 0x7, 0x2, 0xa0, 0x82, 0x3, 0xd3, 0x30, 0x82, 0x3, 0xcf, 0x2, 0x1, 0x3, 0x31, 0xf, 0x30, 0xd, 0x6, 0x9, 0x60, 0x86, 0x48, 0x1, 0x65, 0x3, 0x4, 0x2, 0x1, 0x5, 0x0, 0x30, 0x81, 0xee, 0x6, 0xb, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0xd, 0x1, 0x9, 0x10, 0x1, 0x4, 0xa0, 0x81, 0xde, 0x4, 0x81, 0xdb, 0x30, 0x81, 0xd8, 0x2, 0x1, 0x1, 0x6, 0x9, 0x2b, 0x6, 0x1, 0x4, 0x1, 0xa0, 0x32, 0x2, 0x1, 0x30, 0x31, 0x30, 0xd, 0x6, 0x9, 0x60, 0x86, 0x48, 0x1, 0x65, 0x3, 0x4, 0x2, 0x1, 0x5, 0x0, 0x4, 0x20, 0xf4, 0x87, 0xd8, 0x81, 0x64, 0xbd, 0xe2, 0x23, 0xb7, 0xfd, 0x3c, 0x71, 0xb3, 0xe9, 0xc6, 0x24, 0xc8, 0xa0, 0xcb, 0x55, 0x9c, 0x85, 0x3b, 0x49, 0x55, 0x8e, 0x7e, 0x5e, 0xf4, 0xce, 0x55, 0xf0, 0x2, 0x14, 0x48, 0xf7, 0x9a, 0x1f, 0xa2, 0x58, 0x61, 0xe1, 0xc4, 0xea, 0x9d, 0x48, 0x9e, 0x6, 0xb9, 0xce, 0xf9, 0xaa, 0xcc, 0x1d, 0x18, 0xf, 0x32, 0x30, 0x31, 0x37, 0x30, 0x34, 0x31, 0x39, 0x30, 0x36, 0x33, 0x32, 0x34, 0x33, 0x5a, 0x30, 0x3, 0x2, 0x1, 0x1, 0x2, 0x9, 0x0, 0xb1, 0xfc, 0x81, 0xde, 0xc9, 0x57, 0x49, 0xd9, 0xa0, 0x5e, 0xa4, 0x5c, 0x30, 0x5a, 0x31, 0xb, 0x30, 0x9, 0x6, 0x3, 0x55, 0x4, 0x6, 0x13, 0x2, 0x53, 0x47, 0x31, 0x1f, 0x30, 0x1d, 0x6, 0x3, 0x55, 0x4, 0xa, 0x13, 0x16, 0x47, 0x4d, 0x4f, 0x20, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x50, 0x74, 0x65, 0x20, 0x4c, 0x74, 0x64, 0x31, 0x2a, 0x30, 0x28, 0x6, 0x3, 0x55, 0x4, 0x3, 0x13, 0x21, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x54, 0x53, 0x41, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x41, 0x64, 0x6f, 0x62, 0x65, 0x20, 0x43, 0x44, 0x53, 0x20, 0x2d, 0x20, 0x47, 0x32, 0x31, 0x82, 0x2, 0xc6, 0x30, 0x82, 0x2, 0xc2, 0x2, 0x1, 0x1, 0x30, 0x81, 0x88, 0x30, 0x72, 0x31, 0xb, 0x30, 0x9, 0x6, 0x3, 0x55, 0x4, 0x6, 0x13, 0x2, 0x42, 0x45, 0x31, 0x19, 0x30, 0x17, 0x6, 0x3, 0x55, 0x4, 0xa, 0x13, 0x10, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x6e, 0x76, 0x2d, 0x73, 0x61, 0x31, 0x17, 0x30, 0x15, 0x6, 0x3, 0x55, 0x4, 0xb, 0x13, 0xe, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x44, 0x53, 0x31, 0x2f, 0x30, 0x2d, 0x6, 0x3, 0x55, 0x4, 0x3, 0x13, 0x26, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x20, 0x43, 0x41, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x41, 0x64, 0x6f, 0x62, 0x65, 0x2, 0x12, 0x11, 0x21, 0xd2, 0xd1, 0x82, 0xa, 0xf0, 0xa5, 0xc5, 0x48, 0x14, 0x9a, 0x32, 0x74, 0xdc, 0xc3, 0x43, 0x57, 0x30, 0xd, 0x6, 0x9, 0x60, 0x86, 0x48, 0x1, 0x65, 0x3, 0x4, 0x2, 0x1, 0x5, 0x0, 0xa0, 0x82, 0x1, 0xe, 0x30, 0x1a, 0x6, 0x9, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0xd, 0x1, 0x9, 0x3, 0x31, 0xd, 0x6, 0xb, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0xd, 0x1, 0x9, 0x10, 0x1, 0x4, 0x30, 0x2f, 0x6, 0x9, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0xd, 0x1, 0x9, 0x4, 0x31, 0x22, 0x4, 0x20, 0x6e, 0x24, 0x6d, 0x44, 0xcb, 0xa4, 0x33, 0x6c, 0xb7, 0xe5, 0x58, 0x1a, 0x54, 0x5f, 0xcc, 0x50, 0x7c, 0x5, 0x3, 0x56, 0x20, 0x31, 0xb4, 0x2d, 0x3c, 0xbf, 0x9c, 0xc8, 0x1a, 0xf4, 0xb8, 0x39, 0x30, 0x81, 0xbe, 0x6, 0xb, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0xd, 0x1, 0x9, 0x10, 0x2, 0xc, 0x31, 0x81, 0xae, 0x30, 0x81, 0xab, 0x30, 0x81, 0xa8, 0x30, 0x81, 0xa5, 0x4, 0x14, 0xba, 0x64, 0xa3, 0x69, 0x93, 0xb8, 0xb6, 0x4, 0xf7, 0xfe, 0x65, 0xd3, 0x7d, 0x8f, 0x8e, 0x68, 0x96, 0xfc, 0x96, 0xb, 0x30, 0x81, 0x8c, 0x30, 0x76, 0xa4, 0x74, 0x30, 0x72, 0x31, 0xb, 0x30, 0x9, 0x6, 0x3, 0x55, 0x4, 0x6, 0x13, 0x2, 0x42, 0x45, 0x31, 0x19, 0x30, 0x17, 0x6, 0x3, 0x55, 0x4, 0xa, 0x13, 0x10, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x6e, 0x76, 0x2d, 0x73, 0x61, 0x31, 0x17, 0x30, 0x15, 0x6, 0x3, 0x55, 0x4, 0xb, 0x13, 0xe, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x44, 0x53, 0x31, 0x2f, 0x30, 0x2d, 0x6, 0x3, 0x55, 0x4, 0x3, 0x13, 0x26, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x20, 0x43, 0x41, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x41, 0x64, 0x6f, 0x62, 0x65, 0x2, 0x12, 0x11, 0x21, 0xd2, 0xd1, 0x82, 0xa, 0xf0, 0xa5, 0xc5, 0x48, 0x14, 0x9a, 0x32, 0x74, 0xdc, 0xc3, 0x43, 0x57, 0x30, 0xd, 0x6, 0x9, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0xd, 0x1, 0x1, 0x1, 0x5, 0x0, 0x4, 0x82, 0x1, 0x0, 0xb5, 0xa5, 0x55, 0x83, 0xf, 0x16, 0xe4, 0x78, 0x99, 0xfe, 0xc7, 0x52, 0x68, 0x90, 0xe4, 0x1e, 0xc8, 0xc7, 0xb0, 0x45, 0xf3, 0xa5, 0x2d, 0xc, 0xd1, 0x5f, 0xad, 0x71, 0x7c, 0x6, 0x7d, 0x65, 0xc2, 0x8f, 0x47, 0x12, 0x43, 0x4e, 0x3d, 0x5d, 0xa3, 0x52, 0x4e, 0x18, 0x98, 0x6d, 0x60, 0x47, 0xda, 0x60, 0x5c, 0x33, 0xfc, 0xda, 0x5b, 0x27, 0x5d, 0x1a, 0x8, 0xec, 0xc4, 0xbe, 0xb8, 0x4e, 0x31, 0x8e, 0xf9, 0x84, 0x8b, 0x7c, 0x57, 0xe4, 0x5b, 0x13, 0xca, 0xed, 0x44, 0x2f, 0x24, 0x29, 0x5d, 0x76, 0x75, 0x34, 0x6, 0x36, 0x1c, 0x0, 0x8, 0x4, 0x8d, 0x3d, 0x2d, 0x14, 0xfb, 0xc8, 0xb3, 0x92, 0x9b, 0x88, 0x14, 0x61, 0x44, 0xf4, 0x82, 0xbd, 0xb, 0x61, 0x36, 0xd2, 0x4e, 0x2b, 0xc8, 0xae, 0x75, 0x77, 0x2e, 0x54, 0xe7, 0x2d, 0xd5, 0x42, 0xe5, 0x23, 0xc, 0x1e, 0xb3, 0x80, 0xc7, 0x13, 0xe3, 0x13, 0xb5, 0x63, 0x59, 0x5a, 0x95, 0x4e, 0x33, 0x3, 0xe6, 0x31, 0x82, 0xbc, 0x85, 0xa6, 0x66, 0x48, 0xfa, 0x42, 0x47, 0x6a, 0x76, 0x9a, 0x97, 0x56, 0x6e, 0x1a, 0x33, 0xaa, 0x7d, 0xe5, 0x5e, 0xf9, 0xd, 0x24, 0x19, 0xed, 0xf8, 0x37, 0xe, 0xd0, 0x91, 0xa5, 0x9, 0x72, 0x58, 0x66, 0xf8, 0x13, 0x6c, 0x77, 0x99, 0x8f, 0x1c, 0xd9, 0xad, 0x17, 0x3f, 0xa3, 0xd7, 0x2a, 0x91, 0x93, 0xf9, 0x36, 0x36, 0x6f, 0x6, 0x53, 0x0, 0x23, 0xce, 0x18, 0x5d, 0xd, 0x98, 0x8a, 0x24, 0x94, 0x7f, 0x6d, 0xb9, 0x13, 0xcc, 0xa7, 0xcb, 0x89, 0x5f, 0x3, 0x23, 0x1a, 0x49, 0x70, 0x9b, 0x75, 0x9f, 0xf9, 0x64, 0x42, 0x75, 0xcb, 0x76, 0x2f, 0xb9, 0x82, 0x5e, 0x1c, 0xa9, 0x41, 0xd4, 0x6d, 0x84, 0x4e, 0xf8, 0x2d, 0x93, 0x2c, 0x4c, 0x4f, 0x21, 0x82, 0x6b, 0x5b, 0x95, 0xe3} 50 | 51 | // TimeStampToken excluding response struct 52 | var timeStampToken = []byte{0x30, 0x82, 0xc, 0xdc, 0x6, 0x9, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0xd, 0x1, 0x7, 0x2, 0xa0, 0x82, 0xc, 0xcd, 0x30, 0x82, 0xc, 0xc9, 0x2, 0x1, 0x3, 0x31, 0xf, 0x30, 0xd, 0x6, 0x9, 0x60, 0x86, 0x48, 0x1, 0x65, 0x3, 0x4, 0x2, 0x1, 0x5, 0x0, 0x30, 0x81, 0xf1, 0x6, 0xb, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0xd, 0x1, 0x9, 0x10, 0x1, 0x4, 0xa0, 0x81, 0xe1, 0x4, 0x81, 0xde, 0x30, 0x81, 0xdb, 0x2, 0x1, 0x1, 0x6, 0x9, 0x2b, 0x6, 0x1, 0x4, 0x1, 0xa0, 0x32, 0x1, 0x1f, 0x30, 0x31, 0x30, 0xd, 0x6, 0x9, 0x60, 0x86, 0x48, 0x1, 0x65, 0x3, 0x4, 0x2, 0x1, 0x5, 0x0, 0x4, 0x20, 0x2d, 0xa8, 0x2c, 0x15, 0x72, 0xff, 0x2, 0x5, 0x24, 0xe0, 0x50, 0x69, 0x21, 0x99, 0x75, 0xc9, 0xba, 0x90, 0x72, 0x3f, 0x1a, 0x4d, 0xd5, 0xb9, 0x72, 0x2a, 0xee, 0x8e, 0xc5, 0x47, 0xa2, 0xff, 0x2, 0x14, 0x6d, 0x43, 0xbe, 0x1c, 0xa9, 0xbc, 0x92, 0x5, 0x4c, 0x31, 0xc9, 0x7, 0x2c, 0xd2, 0x42, 0x49, 0x74, 0x1d, 0x1e, 0x7e, 0x18, 0xf, 0x32, 0x30, 0x31, 0x37, 0x30, 0x32, 0x30, 0x31, 0x31, 0x35, 0x33, 0x39, 0x35, 0x30, 0x5a, 0x30, 0x3, 0x2, 0x1, 0x1, 0x2, 0x8, 0x3f, 0x2b, 0x95, 0xd0, 0x72, 0x8b, 0xed, 0x57, 0xa0, 0x62, 0xa4, 0x60, 0x30, 0x5e, 0x31, 0xb, 0x30, 0x9, 0x6, 0x3, 0x55, 0x4, 0x6, 0x13, 0x2, 0x53, 0x47, 0x31, 0x1f, 0x30, 0x1d, 0x6, 0x3, 0x55, 0x4, 0xa, 0x13, 0x16, 0x47, 0x4d, 0x4f, 0x20, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x50, 0x74, 0x65, 0x20, 0x4c, 0x74, 0x64, 0x31, 0x2e, 0x30, 0x2c, 0x6, 0x3, 0x55, 0x4, 0x3, 0x13, 0x25, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x73, 0x69, 0x67, 0x6e, 0x20, 0x54, 0x53, 0x41, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x41, 0x41, 0x54, 0x4c, 0x20, 0x2d, 0x20, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x20, 0x2d, 0x20, 0x47, 0x32, 0xa0, 0x82, 0x9, 0x2c, 0x30, 0x82, 0x4, 0xd1, 0x30, 0x82, 0x3, 0xb9, 0xa0, 0x3, 0x2, 0x1, 0x2, 0x2, 0x12, 0x11, 0x21, 0x12, 0x42, 0x28, 0x72, 0xda, 0x4f, 0xa5, 0x6c, 0x1, 0x3b, 0x29, 0x7c, 0xaf, 0x65, 0xf1, 0xfb, 0x30, 0xd, 0x6, 0x9, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0xd, 0x1, 0x1, 0xb, 0x5, 0x0, 0x30, 0x57, 0x31, 0xb, 0x30, 0x9, 0x6, 0x3, 0x55, 0x4, 0x6, 0x13, 0x2, 0x42, 0x45, 0x31, 0x19, 0x30, 0x17, 0x6, 0x3, 0x55, 0x4, 0xa, 0x13, 0x10, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x6e, 0x76, 0x2d, 0x73, 0x61, 0x31, 0x2d, 0x30, 0x2b, 0x6, 0x3, 0x55, 0x4, 0x3, 0x13, 0x24, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x41, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x41, 0x41, 0x54, 0x4c, 0x20, 0x2d, 0x20, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x20, 0x2d, 0x20, 0x47, 0x32, 0x30, 0x1e, 0x17, 0xd, 0x31, 0x36, 0x30, 0x35, 0x32, 0x34, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0xd, 0x32, 0x37, 0x30, 0x36, 0x32, 0x34, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x5e, 0x31, 0xb, 0x30, 0x9, 0x6, 0x3, 0x55, 0x4, 0x6, 0x13, 0x2, 0x53, 0x47, 0x31, 0x1f, 0x30, 0x1d, 0x6, 0x3, 0x55, 0x4, 0xa, 0x13, 0x16, 0x47, 0x4d, 0x4f, 0x20, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x50, 0x74, 0x65, 0x20, 0x4c, 0x74, 0x64, 0x31, 0x2e, 0x30, 0x2c, 0x6, 0x3, 0x55, 0x4, 0x3, 0x13, 0x25, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x73, 0x69, 0x67, 0x6e, 0x20, 0x54, 0x53, 0x41, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x41, 0x41, 0x54, 0x4c, 0x20, 0x2d, 0x20, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x20, 0x2d, 0x20, 0x47, 0x32, 0x30, 0x82, 0x1, 0x22, 0x30, 0xd, 0x6, 0x9, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0xd, 0x1, 0x1, 0x1, 0x5, 0x0, 0x3, 0x82, 0x1, 0xf, 0x0, 0x30, 0x82, 0x1, 0xa, 0x2, 0x82, 0x1, 0x1, 0x0, 0xc3, 0xcf, 0xdd, 0x35, 0xb0, 0x13, 0xc1, 0xdb, 0xae, 0xdd, 0x96, 0xef, 0x26, 0xfb, 0x6a, 0x1e, 0x78, 0xf, 0x1a, 0x44, 0x98, 0x0, 0x70, 0x60, 0x31, 0x8, 0xde, 0x32, 0x7c, 0x1b, 0xad, 0x6a, 0xa0, 0xa9, 0xf7, 0xd6, 0x60, 0x0, 0x50, 0x69, 0x33, 0x59, 0x9c, 0x7c, 0x14, 0xa6, 0x93, 0x2a, 0xba, 0xaf, 0xfe, 0xec, 0x14, 0x82, 0x1c, 0x9b, 0x7c, 0xd2, 0x8e, 0xb8, 0xc1, 0x36, 0x1f, 0xcc, 0xfa, 0x62, 0xef, 0x59, 0xc0, 0xd2, 0x38, 0x8b, 0x33, 0x4b, 0x35, 0x3f, 0x56, 0xfc, 0x2c, 0xd5, 0x27, 0x8d, 0x18, 0xfd, 0x7d, 0x35, 0x9e, 0xf1, 0x64, 0x7e, 0x90, 0xd2, 0x92, 0x78, 0xcc, 0x23, 0xc6, 0xa8, 0x23, 0x25, 0x40, 0x17, 0x18, 0x22, 0x24, 0xd0, 0x44, 0x61, 0x48, 0x9d, 0x18, 0xba, 0xd8, 0x20, 0x2c, 0x21, 0x18, 0x2c, 0xcf, 0xcf, 0x1c, 0x28, 0x7b, 0xb2, 0xf3, 0xde, 0x8e, 0xa8, 0xd8, 0xc4, 0xd9, 0xe1, 0x63, 0x6e, 0x3e, 0xa, 0x0, 0x4e, 0x1d, 0x89, 0x5d, 0xa1, 0x5a, 0x64, 0x0, 0xb4, 0x16, 0x63, 0x30, 0xf7, 0xa6, 0x42, 0xfc, 0x27, 0x7b, 0xae, 0xea, 0x2b, 0x3d, 0x78, 0x3, 0x3, 0xd3, 0x8b, 0x69, 0xd5, 0x8a, 0xf4, 0xff, 0x55, 0x0, 0xfa, 0xfe, 0xd3, 0xff, 0xc6, 0x58, 0xca, 0x6a, 0x1d, 0x60, 0x78, 0x15, 0xdf, 0x1c, 0xb0, 0xff, 0xe2, 0xd8, 0x21, 0x17, 0x45, 0xce, 0xb9, 0xc9, 0x30, 0xc7, 0x0, 0x46, 0xde, 0x35, 0xe1, 0x1f, 0x74, 0x1b, 0xe4, 0x3d, 0x25, 0xf3, 0xdd, 0xfb, 0xb2, 0xd0, 0xeb, 0x5b, 0xe3, 0x51, 0x13, 0x38, 0x1b, 0x4, 0x8b, 0xc8, 0x0, 0x83, 0x83, 0x58, 0xb8, 0x64, 0xbe, 0xd3, 0xc1, 0xb5, 0xc4, 0xce, 0xeb, 0x70, 0xcd, 0x9a, 0x91, 0x5, 0x6b, 0x61, 0xbd, 0xd2, 0xd7, 0xbc, 0x29, 0x5d, 0xb7, 0xc5, 0x56, 0xf0, 0x6, 0x1, 0xaf, 0x2, 0x3, 0x1, 0x0, 0x1, 0xa3, 0x82, 0x1, 0x8e, 0x30, 0x82, 0x1, 0x8a, 0x30, 0xe, 0x6, 0x3, 0x55, 0x1d, 0xf, 0x1, 0x1, 0xff, 0x4, 0x4, 0x3, 0x2, 0x7, 0x80, 0x30, 0x4c, 0x6, 0x3, 0x55, 0x1d, 0x20, 0x4, 0x45, 0x30, 0x43, 0x30, 0x41, 0x6, 0x9, 0x2b, 0x6, 0x1, 0x4, 0x1, 0xa0, 0x32, 0x1, 0x1f, 0x30, 0x34, 0x30, 0x32, 0x6, 0x8, 0x2b, 0x6, 0x1, 0x5, 0x5, 0x7, 0x2, 0x1, 0x16, 0x26, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x2f, 0x30, 0x9, 0x6, 0x3, 0x55, 0x1d, 0x13, 0x4, 0x2, 0x30, 0x0, 0x30, 0x16, 0x6, 0x3, 0x55, 0x1d, 0x25, 0x1, 0x1, 0xff, 0x4, 0xc, 0x30, 0xa, 0x6, 0x8, 0x2b, 0x6, 0x1, 0x5, 0x5, 0x7, 0x3, 0x8, 0x30, 0x3e, 0x6, 0x3, 0x55, 0x1d, 0x1f, 0x4, 0x37, 0x30, 0x35, 0x30, 0x33, 0xa0, 0x31, 0xa0, 0x2f, 0x86, 0x2d, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x73, 0x2f, 0x67, 0x73, 0x61, 0x61, 0x74, 0x6c, 0x73, 0x68, 0x61, 0x32, 0x67, 0x32, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x81, 0x86, 0x6, 0x8, 0x2b, 0x6, 0x1, 0x5, 0x5, 0x7, 0x1, 0x1, 0x4, 0x7a, 0x30, 0x78, 0x30, 0x40, 0x6, 0x8, 0x2b, 0x6, 0x1, 0x5, 0x5, 0x7, 0x30, 0x2, 0x86, 0x34, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x2e, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x61, 0x63, 0x65, 0x72, 0x74, 0x2f, 0x67, 0x73, 0x61, 0x61, 0x74, 0x6c, 0x73, 0x68, 0x61, 0x32, 0x67, 0x32, 0x2e, 0x63, 0x72, 0x74, 0x30, 0x34, 0x6, 0x8, 0x2b, 0x6, 0x1, 0x5, 0x5, 0x7, 0x30, 0x1, 0x86, 0x28, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x32, 0x2e, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x73, 0x61, 0x61, 0x74, 0x6c, 0x73, 0x68, 0x61, 0x32, 0x67, 0x32, 0x30, 0x1d, 0x6, 0x3, 0x55, 0x1d, 0xe, 0x4, 0x16, 0x4, 0x14, 0xf4, 0xd4, 0xc1, 0x17, 0x61, 0x17, 0x11, 0x1e, 0xc, 0x4e, 0x6e, 0xa1, 0x3b, 0x40, 0xb8, 0x87, 0xb6, 0x94, 0x87, 0x3a, 0x30, 0x1f, 0x6, 0x3, 0x55, 0x1d, 0x23, 0x4, 0x18, 0x30, 0x16, 0x80, 0x14, 0x60, 0xc2, 0xf1, 0x52, 0x3e, 0xad, 0x8c, 0x13, 0xdc, 0xdb, 0xca, 0xe, 0xfa, 0xa, 0xe6, 0x2a, 0x2c, 0x99, 0x4b, 0xd8, 0x30, 0xd, 0x6, 0x9, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0xd, 0x1, 0x1, 0xb, 0x5, 0x0, 0x3, 0x82, 0x1, 0x1, 0x0, 0xea, 0x88, 0x3f, 0xd2, 0xef, 0x94, 0xf, 0x5d, 0x54, 0xc2, 0x52, 0x68, 0x91, 0x23, 0xe7, 0x12, 0xe2, 0x72, 0xc3, 0x4, 0xe7, 0xea, 0x88, 0x68, 0xa1, 0xba, 0x20, 0xde, 0x25, 0x77, 0x49, 0x3b, 0x7b, 0x10, 0xf7, 0xa3, 0x60, 0x24, 0xc9, 0xe5, 0xcd, 0x38, 0x9e, 0xc7, 0x1a, 0xf6, 0xa, 0xe6, 0x14, 0x83, 0xfc, 0x7c, 0x38, 0x73, 0x12, 0x40, 0xfc, 0xbe, 0x2e, 0xb8, 0x39, 0xb4, 0x47, 0xaa, 0x75, 0x2c, 0x6a, 0x71, 0x53, 0x6e, 0x4c, 0x3c, 0xc5, 0xda, 0xbe, 0x90, 0xca, 0x66, 0x83, 0x1f, 0x44, 0x1a, 0xf1, 0xf5, 0x80, 0xa0, 0x70, 0x1d, 0xe2, 0xb, 0xb6, 0x6f, 0x4a, 0x34, 0xf9, 0x66, 0xd6, 0x3a, 0xb, 0x9d, 0x57, 0xb7, 0xef, 0x9b, 0x0, 0xb7, 0x5f, 0x2, 0x2e, 0xc4, 0xd9, 0x38, 0x45, 0xa2, 0x45, 0xcb, 0xe8, 0x1, 0x23, 0xaf, 0x64, 0xf, 0x3b, 0x4a, 0x33, 0x24, 0xa7, 0x19, 0x94, 0xb4, 0x52, 0x30, 0x31, 0x89, 0x21, 0x35, 0x3c, 0xe6, 0xee, 0xa0, 0xe7, 0xdd, 0xcf, 0x1c, 0xaa, 0x3, 0x87, 0xe8, 0x3b, 0xb0, 0x54, 0xae, 0x9a, 0x37, 0x3c, 0xd4, 0x23, 0xb4, 0x94, 0xce, 0x7e, 0xc0, 0xa1, 0xc, 0x6c, 0x63, 0x70, 0x33, 0x45, 0xec, 0xc7, 0xe8, 0xf2, 0xfc, 0x2b, 0x64, 0xdd, 0xd6, 0xe1, 0xd7, 0x69, 0xe8, 0x2, 0xb0, 0x96, 0xac, 0xb7, 0x13, 0x34, 0x78, 0xb8, 0x94, 0x90, 0x6c, 0x55, 0x8e, 0x4e, 0x55, 0xe3, 0xb6, 0xc5, 0x6, 0xee, 0x15, 0xd7, 0x1, 0xc2, 0xca, 0xae, 0x42, 0xf6, 0x59, 0x7b, 0xd1, 0x59, 0xa4, 0x2f, 0x73, 0xb0, 0x16, 0x9a, 0x5e, 0xd7, 0xb, 0x8a, 0xfb, 0x74, 0x3c, 0x89, 0x33, 0x77, 0x57, 0x46, 0xc4, 0x63, 0x3b, 0x31, 0xa4, 0x5, 0xb, 0x67, 0x5b, 0xca, 0x10, 0x5e, 0x51, 0xd7, 0xea, 0x4b, 0xbb, 0xcd, 0x73, 0x9f, 0x81, 0xb2, 0x38, 0x30, 0x82, 0x4, 0x53, 0x30, 0x82, 0x3, 0x3b, 0xa0, 0x3, 0x2, 0x1, 0x2, 0x2, 0xb, 0x4, 0x0, 0x0, 0x0, 0x0, 0x1, 0x44, 0x4f, 0x2, 0x36, 0xb6, 0x30, 0xd, 0x6, 0x9, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0xd, 0x1, 0x1, 0xb, 0x5, 0x0, 0x30, 0x4c, 0x31, 0x20, 0x30, 0x1e, 0x6, 0x3, 0x55, 0x4, 0xb, 0x13, 0x17, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, 0x20, 0x2d, 0x20, 0x52, 0x33, 0x31, 0x13, 0x30, 0x11, 0x6, 0x3, 0x55, 0x4, 0xa, 0x13, 0xa, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x31, 0x13, 0x30, 0x11, 0x6, 0x3, 0x55, 0x4, 0x3, 0x13, 0xa, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x30, 0x1e, 0x17, 0xd, 0x31, 0x34, 0x30, 0x32, 0x32, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0xd, 0x32, 0x39, 0x30, 0x33, 0x31, 0x38, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x57, 0x31, 0xb, 0x30, 0x9, 0x6, 0x3, 0x55, 0x4, 0x6, 0x13, 0x2, 0x42, 0x45, 0x31, 0x19, 0x30, 0x17, 0x6, 0x3, 0x55, 0x4, 0xa, 0x13, 0x10, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x6e, 0x76, 0x2d, 0x73, 0x61, 0x31, 0x2d, 0x30, 0x2b, 0x6, 0x3, 0x55, 0x4, 0x3, 0x13, 0x24, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x41, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x41, 0x41, 0x54, 0x4c, 0x20, 0x2d, 0x20, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x20, 0x2d, 0x20, 0x47, 0x32, 0x30, 0x82, 0x1, 0x22, 0x30, 0xd, 0x6, 0x9, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0xd, 0x1, 0x1, 0x1, 0x5, 0x0, 0x3, 0x82, 0x1, 0xf, 0x0, 0x30, 0x82, 0x1, 0xa, 0x2, 0x82, 0x1, 0x1, 0x0, 0xf9, 0xfc, 0x9e, 0x98, 0x63, 0xd3, 0xe, 0xca, 0x30, 0xe8, 0xfa, 0xab, 0xd0, 0x83, 0x18, 0x53, 0x51, 0x3f, 0x92, 0x8d, 0xc3, 0x1b, 0x75, 0xf, 0x5d, 0x3, 0xa5, 0x14, 0xc7, 0x25, 0x31, 0xbb, 0x1d, 0x33, 0xd0, 0xa9, 0xb9, 0xe1, 0x41, 0xeb, 0x38, 0x3e, 0xa1, 0x45, 0xef, 0x35, 0x7c, 0x2d, 0x5b, 0xf0, 0xad, 0xa8, 0xe4, 0x8b, 0xe3, 0xe4, 0x5f, 0x2b, 0x2c, 0xe5, 0x78, 0x4b, 0x87, 0x32, 0x81, 0xd5, 0x16, 0x50, 0x93, 0xb8, 0x96, 0xc2, 0x6a, 0xc, 0x81, 0xed, 0x57, 0x1, 0x84, 0x86, 0xb9, 0x0, 0xa3, 0x38, 0x7, 0x9a, 0xc8, 0x45, 0x5c, 0xc0, 0xca, 0x56, 0xdc, 0x14, 0x8e, 0xb3, 0xda, 0x97, 0x61, 0xaa, 0xb5, 0x99, 0x23, 0x22, 0x95, 0xbe, 0x70, 0xd6, 0x11, 0xd9, 0x83, 0x82, 0xae, 0xaf, 0xc9, 0xc5, 0x2b, 0x4b, 0xc, 0x6a, 0xcd, 0x62, 0x56, 0x2a, 0x28, 0x61, 0xcf, 0x64, 0x8b, 0xc5, 0xee, 0x57, 0xda, 0x3f, 0xc, 0x6e, 0x2d, 0x6e, 0x31, 0x31, 0x97, 0x7c, 0x54, 0x9d, 0xf6, 0x12, 0x61, 0x4d, 0xe8, 0x77, 0xa8, 0xe8, 0x2, 0x73, 0x20, 0xa6, 0x4c, 0x15, 0xe8, 0xf1, 0x23, 0xee, 0x86, 0x86, 0x52, 0xab, 0x83, 0xb9, 0x52, 0x3a, 0xc7, 0xe7, 0xad, 0x9b, 0x40, 0x1f, 0xa2, 0x18, 0x17, 0x53, 0xff, 0xff, 0x6f, 0xd, 0x74, 0xfb, 0xc5, 0xdc, 0xd1, 0x6a, 0x57, 0x8, 0xdc, 0x67, 0x81, 0xd7, 0xa8, 0x2c, 0xb8, 0xa3, 0xb6, 0xe1, 0x54, 0xab, 0xf3, 0xc5, 0xfb, 0xe4, 0x41, 0x21, 0x4, 0x6, 0xcb, 0xb4, 0x6d, 0xf9, 0x43, 0xc2, 0xd9, 0x45, 0x4c, 0x94, 0x53, 0xc6, 0xa5, 0x28, 0xef, 0xc3, 0xde, 0xf, 0xda, 0xf7, 0xea, 0x38, 0x5c, 0x26, 0xbd, 0x54, 0x2a, 0xea, 0xe0, 0x60, 0xbf, 0x58, 0x9f, 0x2c, 0x2c, 0x60, 0x6c, 0xa4, 0x40, 0x7e, 0x3a, 0x4d, 0x19, 0x41, 0x2, 0x3, 0x1, 0x0, 0x1, 0xa3, 0x82, 0x1, 0x29, 0x30, 0x82, 0x1, 0x25, 0x30, 0xe, 0x6, 0x3, 0x55, 0x1d, 0xf, 0x1, 0x1, 0xff, 0x4, 0x4, 0x3, 0x2, 0x1, 0x6, 0x30, 0x12, 0x6, 0x3, 0x55, 0x1d, 0x13, 0x1, 0x1, 0xff, 0x4, 0x8, 0x30, 0x6, 0x1, 0x1, 0xff, 0x2, 0x1, 0x1, 0x30, 0x1d, 0x6, 0x3, 0x55, 0x1d, 0xe, 0x4, 0x16, 0x4, 0x14, 0x60, 0xc2, 0xf1, 0x52, 0x3e, 0xad, 0x8c, 0x13, 0xdc, 0xdb, 0xca, 0xe, 0xfa, 0xa, 0xe6, 0x2a, 0x2c, 0x99, 0x4b, 0xd8, 0x30, 0x47, 0x6, 0x3, 0x55, 0x1d, 0x20, 0x4, 0x40, 0x30, 0x3e, 0x30, 0x3c, 0x6, 0x4, 0x55, 0x1d, 0x20, 0x0, 0x30, 0x34, 0x30, 0x32, 0x6, 0x8, 0x2b, 0x6, 0x1, 0x5, 0x5, 0x7, 0x2, 0x1, 0x16, 0x26, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x2f, 0x30, 0x36, 0x6, 0x3, 0x55, 0x1d, 0x1f, 0x4, 0x2f, 0x30, 0x2d, 0x30, 0x2b, 0xa0, 0x29, 0xa0, 0x27, 0x86, 0x25, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x6e, 0x65, 0x74, 0x2f, 0x72, 0x6f, 0x6f, 0x74, 0x2d, 0x72, 0x33, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x3e, 0x6, 0x8, 0x2b, 0x6, 0x1, 0x5, 0x5, 0x7, 0x1, 0x1, 0x4, 0x32, 0x30, 0x30, 0x30, 0x2e, 0x6, 0x8, 0x2b, 0x6, 0x1, 0x5, 0x5, 0x7, 0x30, 0x1, 0x86, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x32, 0x2e, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x6f, 0x6f, 0x74, 0x72, 0x33, 0x30, 0x1f, 0x6, 0x3, 0x55, 0x1d, 0x23, 0x4, 0x18, 0x30, 0x16, 0x80, 0x14, 0x8f, 0xf0, 0x4b, 0x7f, 0xa8, 0x2e, 0x45, 0x24, 0xae, 0x4d, 0x50, 0xfa, 0x63, 0x9a, 0x8b, 0xde, 0xe2, 0xdd, 0x1b, 0xbc, 0x30, 0xd, 0x6, 0x9, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0xd, 0x1, 0x1, 0xb, 0x5, 0x0, 0x3, 0x82, 0x1, 0x1, 0x0, 0x13, 0xa2, 0xa9, 0xae, 0x72, 0x73, 0x5b, 0x11, 0x5f, 0x37, 0x47, 0xd0, 0xff, 0xf4, 0x4, 0x82, 0xe4, 0xfc, 0xf1, 0x36, 0x5d, 0xb2, 0x4d, 0xa7, 0x13, 0x87, 0x94, 0xe4, 0x3e, 0xda, 0x73, 0xec, 0x27, 0x7e, 0xa8, 0xa1, 0xbb, 0x7a, 0x12, 0x41, 0x23, 0x9e, 0x36, 0x18, 0xdd, 0x22, 0x62, 0x56, 0x52, 0x9d, 0x1c, 0x7d, 0xf3, 0x96, 0x18, 0x25, 0x97, 0x12, 0xe0, 0x2e, 0xf3, 0xf8, 0x4a, 0x42, 0x3b, 0xa1, 0x1e, 0x82, 0x1c, 0xe7, 0x73, 0xe4, 0x73, 0x77, 0xae, 0x40, 0x23, 0x46, 0x20, 0x8d, 0x10, 0xfb, 0x8d, 0x3a, 0xd7, 0xcd, 0x3d, 0x10, 0x2d, 0x5f, 0xf3, 0x22, 0xda, 0x50, 0xfb, 0x31, 0xef, 0xd7, 0x72, 0xc4, 0x50, 0xd3, 0x94, 0x89, 0x0, 0x60, 0xda, 0xde, 0x2, 0x9d, 0xa8, 0x5e, 0x9c, 0x39, 0x79, 0xeb, 0xb2, 0x8, 0x3c, 0xc4, 0xdb, 0xac, 0x2b, 0x7a, 0xcd, 0x61, 0xf8, 0xee, 0xfc, 0xbd, 0x20, 0xbf, 0x71, 0x94, 0x5d, 0xa, 0x7a, 0x99, 0xda, 0x79, 0xa8, 0x3d, 0xe, 0x97, 0x1, 0x3d, 0x0, 0x3c, 0x3f, 0x39, 0xa7, 0x63, 0x1f, 0xa3, 0xaf, 0x4f, 0xed, 0x6f, 0x7, 0x1d, 0x7f, 0x3b, 0x77, 0xca, 0xd0, 0x43, 0xac, 0xa0, 0x29, 0x49, 0x2d, 0x4, 0x29, 0x36, 0xc2, 0xb9, 0x44, 0x7f, 0xe7, 0xb3, 0xa9, 0xf7, 0x84, 0xd6, 0x9, 0x3f, 0x7b, 0x2e, 0x87, 0x95, 0xe3, 0xbd, 0xb7, 0xfe, 0xf7, 0x96, 0x8b, 0xc5, 0x1c, 0x45, 0xae, 0xc, 0x2e, 0x29, 0x85, 0x83, 0x30, 0x50, 0xf, 0x3a, 0x41, 0xdb, 0x45, 0x7d, 0x4f, 0x34, 0x40, 0x7e, 0x50, 0xcf, 0x12, 0xa2, 0x78, 0x61, 0x16, 0x1f, 0x37, 0x3c, 0xfe, 0x51, 0x67, 0xe3, 0xd, 0xd6, 0xbb, 0x14, 0x50, 0xf3, 0x9c, 0x7, 0x42, 0x2c, 0xbd, 0x7f, 0x7d, 0x90, 0xc, 0x70, 0xe8, 0x5c, 0x13, 0x5c, 0x5b, 0x23, 0x83, 0x6, 0x31, 0x82, 0x2, 0x8d, 0x30, 0x82, 0x2, 0x89, 0x2, 0x1, 0x1, 0x30, 0x6d, 0x30, 0x57, 0x31, 0xb, 0x30, 0x9, 0x6, 0x3, 0x55, 0x4, 0x6, 0x13, 0x2, 0x42, 0x45, 0x31, 0x19, 0x30, 0x17, 0x6, 0x3, 0x55, 0x4, 0xa, 0x13, 0x10, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x6e, 0x76, 0x2d, 0x73, 0x61, 0x31, 0x2d, 0x30, 0x2b, 0x6, 0x3, 0x55, 0x4, 0x3, 0x13, 0x24, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x41, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x41, 0x41, 0x54, 0x4c, 0x20, 0x2d, 0x20, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x20, 0x2d, 0x20, 0x47, 0x32, 0x2, 0x12, 0x11, 0x21, 0x12, 0x42, 0x28, 0x72, 0xda, 0x4f, 0xa5, 0x6c, 0x1, 0x3b, 0x29, 0x7c, 0xaf, 0x65, 0xf1, 0xfb, 0x30, 0xd, 0x6, 0x9, 0x60, 0x86, 0x48, 0x1, 0x65, 0x3, 0x4, 0x2, 0x1, 0x5, 0x0, 0xa0, 0x81, 0xf2, 0x30, 0x1a, 0x6, 0x9, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0xd, 0x1, 0x9, 0x3, 0x31, 0xd, 0x6, 0xb, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0xd, 0x1, 0x9, 0x10, 0x1, 0x4, 0x30, 0x2f, 0x6, 0x9, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0xd, 0x1, 0x9, 0x4, 0x31, 0x22, 0x4, 0x20, 0xc5, 0x8f, 0x24, 0x84, 0xc4, 0x8c, 0xca, 0x82, 0x2b, 0xd3, 0x26, 0xf5, 0xef, 0xf6, 0xa0, 0x3f, 0x15, 0xef, 0xd8, 0x23, 0xd7, 0x74, 0xf9, 0x4d, 0x2, 0x48, 0x59, 0x9f, 0x73, 0x2, 0xe5, 0xe0, 0x30, 0x81, 0xa2, 0x6, 0xb, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0xd, 0x1, 0x9, 0x10, 0x2, 0xc, 0x31, 0x81, 0x92, 0x30, 0x81, 0x8f, 0x30, 0x81, 0x8c, 0x30, 0x81, 0x89, 0x4, 0x14, 0x97, 0xc4, 0xb7, 0x95, 0x36, 0x8d, 0xb5, 0xae, 0x1a, 0x6, 0xc5, 0x44, 0x83, 0x80, 0xaa, 0xeb, 0x1a, 0xc0, 0x9b, 0x8b, 0x30, 0x71, 0x30, 0x5b, 0xa4, 0x59, 0x30, 0x57, 0x31, 0xb, 0x30, 0x9, 0x6, 0x3, 0x55, 0x4, 0x6, 0x13, 0x2, 0x42, 0x45, 0x31, 0x19, 0x30, 0x17, 0x6, 0x3, 0x55, 0x4, 0xa, 0x13, 0x10, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x6e, 0x76, 0x2d, 0x73, 0x61, 0x31, 0x2d, 0x30, 0x2b, 0x6, 0x3, 0x55, 0x4, 0x3, 0x13, 0x24, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x41, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x41, 0x41, 0x54, 0x4c, 0x20, 0x2d, 0x20, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x20, 0x2d, 0x20, 0x47, 0x32, 0x2, 0x12, 0x11, 0x21, 0x12, 0x42, 0x28, 0x72, 0xda, 0x4f, 0xa5, 0x6c, 0x1, 0x3b, 0x29, 0x7c, 0xaf, 0x65, 0xf1, 0xfb, 0x30, 0xd, 0x6, 0x9, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0xd, 0x1, 0x1, 0x1, 0x5, 0x0, 0x4, 0x82, 0x1, 0x0, 0xb6, 0x24, 0xfe, 0xeb, 0x50, 0x44, 0xb4, 0xc, 0xf1, 0xc9, 0x55, 0x46, 0x90, 0xa4, 0xad, 0x91, 0xfa, 0xb0, 0x79, 0x60, 0x54, 0xb2, 0x57, 0x31, 0xcf, 0xee, 0xae, 0xf7, 0x5d, 0xb0, 0xa9, 0x8e, 0x4d, 0x58, 0x25, 0x22, 0x6d, 0x82, 0x2a, 0xe2, 0xf6, 0x72, 0xde, 0x96, 0xc2, 0xdc, 0x42, 0x62, 0x1a, 0x0, 0x69, 0x5b, 0x6e, 0x51, 0x5b, 0x59, 0x39, 0xba, 0x3f, 0xad, 0xa2, 0xfd, 0x7f, 0x87, 0x28, 0x6e, 0x7f, 0x5b, 0xfd, 0x26, 0x98, 0x37, 0xaa, 0xfd, 0x98, 0x47, 0x8c, 0xb1, 0xab, 0x8c, 0xd2, 0xe0, 0x49, 0x48, 0x68, 0x35, 0x86, 0xbf, 0x7, 0x22, 0x7c, 0xf4, 0x56, 0xe8, 0x71, 0xe5, 0x8a, 0x19, 0x68, 0x99, 0xb7, 0x4a, 0x10, 0xb8, 0x5a, 0x49, 0xee, 0x10, 0x45, 0x76, 0xd1, 0x7f, 0xaa, 0x29, 0x6d, 0x4a, 0x31, 0x6d, 0x3e, 0xfb, 0xf, 0xfc, 0x5e, 0x12, 0xc6, 0x1b, 0x57, 0x16, 0xd8, 0x72, 0xbd, 0x6e, 0xdd, 0x5e, 0xd, 0xaf, 0x7f, 0x35, 0x4b, 0xf0, 0xaa, 0x14, 0xf9, 0x37, 0xc, 0x39, 0x50, 0x81, 0x46, 0xdc, 0x1f, 0x81, 0xb, 0xc0, 0x15, 0xef, 0xbe, 0xa0, 0x48, 0x84, 0x19, 0xb0, 0xf7, 0x96, 0xd4, 0x8a, 0x22, 0x5d, 0x9, 0xc2, 0x56, 0xc5, 0x42, 0xe6, 0x93, 0xa, 0xd, 0x88, 0x21, 0x87, 0x4f, 0x48, 0x7b, 0xd5, 0x76, 0xb9, 0xfa, 0x2a, 0x37, 0x94, 0xd, 0xa7, 0x2e, 0x23, 0x8c, 0xd1, 0xd7, 0xef, 0x7c, 0x22, 0xab, 0x22, 0x94, 0x6f, 0x2, 0x48, 0xa, 0xc0, 0x8d, 0x4f, 0xfc, 0x1d, 0x6a, 0x11, 0x19, 0xb3, 0x96, 0xd7, 0x50, 0x8a, 0xe, 0x3f, 0xe2, 0xfd, 0x78, 0x5d, 0xa7, 0x3a, 0xa5, 0x57, 0xab, 0x4f, 0x62, 0xf4, 0x2b, 0x3f, 0xb1, 0xd8, 0x77, 0xf2, 0xfe, 0x67, 0x95, 0xfd, 0x6, 0x10, 0x7, 0x4b, 0xd9, 0x1, 0x2a, 0xb4, 0x2b, 0x6f, 0xd3, 0x9c} 53 | 54 | var respRejection = []byte{0x30, 0x35, 0x30, 0x33, 0x2, 0x1, 0x2, 0x30, 0x28, 0xc, 0x26, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x20, 0x64, 0x75, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x20, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x3, 0x4, 0x6, 0x0, 0x0, 0x40} 55 | 56 | type testData struct { 57 | name string 58 | request []byte 59 | response []byte 60 | certificates bool 61 | nonce *big.Int 62 | time time.Time 63 | accuracy time.Duration 64 | hashedMessage []byte 65 | hashAlgorithm crypto.Hash 66 | } 67 | 68 | var testCases = []testData{ 69 | { 70 | name: "Including nonce", 71 | request: reqNonce, 72 | response: respNonce, 73 | certificates: true, 74 | nonce: big.NewInt(0).SetBytes([]byte{0x9, 0x2e, 0xf1, 0x9f, 0xfb, 0x5d, 0x2a, 0xe8}), 75 | time: time.Date(2017, 4, 19, 6, 29, 53, 0, time.UTC), 76 | accuracy: time.Second, 77 | hashedMessage: hashedMessage, 78 | hashAlgorithm: crypto.SHA256, 79 | }, 80 | { 81 | name: "Containing no nonce", 82 | request: reqNoNonce, 83 | response: respNoNonce, 84 | certificates: true, 85 | nonce: nil, 86 | time: time.Date(2017, 4, 19, 6, 28, 13, 0, time.UTC), 87 | accuracy: time.Second, 88 | hashedMessage: hashedMessage, 89 | hashAlgorithm: crypto.SHA256, 90 | }, 91 | { 92 | name: "Containing no certificates", 93 | request: reqNoCert, 94 | response: respNoCert, 95 | certificates: false, 96 | nonce: big.NewInt(0).SetBytes([]byte{0xb1, 0xfc, 0x81, 0xde, 0xc9, 0x57, 0x49, 0xd9}), 97 | time: time.Date(2017, 4, 19, 6, 32, 43, 0, time.UTC), 98 | accuracy: time.Second, 99 | hashedMessage: hashedMessage, 100 | hashAlgorithm: crypto.SHA256, 101 | }, 102 | } 103 | 104 | // Send the timestamp request to our timestamp server and save the response 105 | // $ curl --globoff -s -S -H Content-Type:application/timestamp-query -H Host:${HOST} --data-binary @request-sha256.tsq -o ts-output.tsr ${URL} 106 | 107 | func TestParseRequest(t *testing.T) { 108 | for _, tc := range testCases { 109 | t.Run(tc.name, func(t *testing.T) { 110 | if tc.request == nil { 111 | return 112 | } 113 | 114 | req, err := ParseRequest(tc.request) 115 | if err != nil { 116 | t.Errorf("failed to parse request: %s", err.Error()) 117 | return 118 | } 119 | 120 | if !bytes.Equal(req.HashedMessage, tc.hashedMessage) { 121 | t.Errorf("req.HashedMessage: got %x, want %x", req.HashedMessage, tc.hashedMessage) 122 | } 123 | 124 | if (tc.nonce != nil && tc.nonce.CmpAbs(req.Nonce) != 0) || (req.Nonce != nil && tc.nonce == nil) { 125 | t.Errorf("req.Nonce: got %v, want %v", req.Nonce, tc.nonce) 126 | } 127 | 128 | if req.HashAlgorithm != tc.hashAlgorithm { 129 | t.Errorf("req.HashAlgorithm: got %v, want %v", req.HashAlgorithm, tc.hashAlgorithm) 130 | } 131 | 132 | if req.Certificates != tc.certificates { 133 | t.Errorf("req.Certificates: got %v, want %v", req.Certificates, tc.certificates) 134 | } 135 | }) 136 | } 137 | } 138 | 139 | func TestParseResponse(t *testing.T) { 140 | for _, tc := range testCases { 141 | t.Run(tc.name, func(t *testing.T) { 142 | if tc.response == nil { 143 | return 144 | } 145 | 146 | resp, err := ParseResponse(tc.response) 147 | if err != nil { 148 | t.Errorf("failed to parse response: %s", err.Error()) 149 | return 150 | } 151 | 152 | if !bytes.Equal(resp.HashedMessage, tc.hashedMessage) { 153 | t.Errorf("resp.HashedMessage: got %x, want %x", resp.HashedMessage, tc.hashedMessage) 154 | } 155 | 156 | if resp.HashAlgorithm != tc.hashAlgorithm { 157 | t.Errorf("resp.HashAlgorithm: got %v, want %v", resp.HashAlgorithm, tc.hashAlgorithm) 158 | } 159 | 160 | if !resp.Time.Equal(tc.time) { 161 | t.Errorf("resp.Time: got %v, want %v", resp.Time, tc.time) 162 | } 163 | 164 | if resp.Accuracy != tc.accuracy { 165 | t.Errorf("resp.Accuracy: got %v, want %v", resp.Accuracy, tc.accuracy) 166 | } 167 | 168 | if tc.certificates && len(resp.Certificates) == 0 { 169 | t.Errorf("resp.Certificates: got %v, want %v", len(resp.Certificates), tc.certificates) 170 | } 171 | 172 | /* 173 | if !(resp.Nonce == nil && tc.nonce == nil && resp.Nonce.Cmp(tc.nonce) != 0 { 174 | t.Errorf("resp.Nonce: got %v, want %v", resp.Nonce, tc.nonce) 175 | } 176 | */ 177 | }) 178 | } 179 | } 180 | 181 | func TestParse(t *testing.T) { 182 | ts, err := Parse(timeStampToken) 183 | if err != nil { 184 | t.Errorf("failed to parse timeStampToken: %s", err.Error()) 185 | } 186 | 187 | hashedMessage := []byte{0x2d, 0xa8, 0x2c, 0x15, 0x72, 0xff, 0x2, 0x5, 0x24, 0xe0, 0x50, 0x69, 0x21, 0x99, 0x75, 0xc9, 0xba, 0x90, 0x72, 0x3f, 0x1a, 0x4d, 0xd5, 0xb9, 0x72, 0x2a, 0xee, 0x8e, 0xc5, 0x47, 0xa2, 0xff} 188 | if !bytes.Equal(ts.HashedMessage, hashedMessage) { 189 | t.Errorf("ts.HashedMessage: got %x, want %x", ts.HashedMessage, hashedMessage) 190 | } 191 | 192 | tsTime := time.Date(2017, 2, 1, 15, 39, 50, 0, time.UTC) 193 | if !ts.Time.Equal(tsTime) { 194 | t.Errorf("ts.Time: got %v, want %v", ts.Time, tsTime) 195 | } 196 | 197 | if ts.Accuracy != time.Second { 198 | t.Errorf("ts.Accuracy: got %v, want %v", ts.Accuracy, time.Second) 199 | } 200 | } 201 | 202 | func TestParseResponseRejection(t *testing.T) { 203 | _, err := ParseResponse(respRejection) 204 | if err == nil { 205 | t.Errorf("failed to parse response with rejection: %s", err.Error()) 206 | } 207 | expected := "the request is rejected: Error during serial number generation. (the additional information requested could not be understood or is not available)" 208 | if err.Error() != expected { 209 | t.Errorf("unexpected error message:\n\t%s\nexpected:\n\t%s\n", err.Error(), expected) 210 | } 211 | } 212 | 213 | func TestCreateErrorResponse(t *testing.T) { 214 | resp, err := CreateErrorResponse(Rejection, TimeNotAvailable) 215 | if err != nil { 216 | t.Errorf("failed to create error: %s", err.Error()) 217 | } 218 | 219 | expected := "the request is rejected: (the TSA's time source is not available)" 220 | _, err = ParseResponse(resp) 221 | if err.Error() != expected { 222 | t.Errorf("unexpected error message:\n\t%s\nexpected:\n\t%s\n", err.Error(), expected) 223 | } 224 | } 225 | 226 | func TestMarshalRequest(t *testing.T) { 227 | req, err := ParseRequest(reqNoNonce) 228 | if err != nil { 229 | t.Fatal(err) 230 | } 231 | 232 | reqByes, err := req.Marshal() 233 | if err != nil { 234 | t.Fatal(err) 235 | } 236 | 237 | if !bytes.Equal(reqByes, reqNoNonce) { 238 | t.Error("Marshalled response bytes are not the same as parsed") 239 | } 240 | } 241 | 242 | func TestCreateRequest(t *testing.T) { 243 | var testHashes = []crypto.Hash{crypto.SHA1, crypto.SHA256, crypto.SHA384, crypto.SHA512} 244 | 245 | nonce := big.NewInt(0) 246 | nonce = nonce.SetBytes([]byte{0x1, 0x2, 0x3}) 247 | 248 | for _, th := range testHashes { 249 | t.Run(fmt.Sprintf("%d", th), func(t *testing.T) { 250 | msg := "Content to by timestamped" 251 | 252 | h := th.New() 253 | _, err := h.Write([]byte(msg)) 254 | if err != nil { 255 | t.Fatal(err) 256 | } 257 | hashedMsg := h.Sum(nil) 258 | 259 | req, err := CreateRequest(strings.NewReader(msg), &RequestOptions{ 260 | Hash: th, 261 | Nonce: nonce, 262 | TSAPolicyOID: asn1.ObjectIdentifier{2, 5, 6, 7}, 263 | Certificates: true, 264 | }) 265 | if err != nil { 266 | t.Fatal(err) 267 | } 268 | 269 | if len(req) == 0 { 270 | t.Error("request contains no bytes") 271 | } 272 | 273 | reqCheck, err := ParseRequest(req) 274 | if err != nil { 275 | t.Fatal(err) 276 | } 277 | 278 | if !bytes.Equal(reqCheck.HashedMessage, hashedMsg) { 279 | t.Errorf("reqCheck.HashedMessage: got %x, want %x", reqCheck.HashedMessage, hashedMsg) 280 | } 281 | 282 | if reqCheck.Nonce.Cmp(nonce) != 0 { 283 | t.Errorf("reqCheck.Nonce: got %x, want %x", reqCheck.Nonce, nonce) 284 | } 285 | 286 | if reqCheck.Certificates != true { 287 | t.Errorf("reqCheck.Certificates: got %t, want %t", reqCheck.Certificates, true) 288 | } 289 | 290 | if !reqCheck.TSAPolicyOID.Equal(asn1.ObjectIdentifier{2, 5, 6, 7}) { 291 | t.Errorf("reqCheck.TSAPolicyOID: got %x, want %x", reqCheck.TSAPolicyOID, asn1.ObjectIdentifier{2, 5, 6, 7}) 292 | } 293 | }) 294 | } 295 | } 296 | 297 | func BenchmarkCreateRequest(b *testing.B) { 298 | reader := strings.NewReader("Content to be time-stamped") 299 | 300 | for n := 0; n < b.N; n++ { 301 | _, _ = CreateRequest(reader, nil) 302 | } 303 | } 304 | 305 | func BenchmarkParseRequest(b *testing.B) { 306 | for n := 0; n < b.N; n++ { 307 | _, _ = ParseRequest(reqNonce) 308 | } 309 | } 310 | 311 | func BenchmarkParseResponse(b *testing.B) { 312 | for n := 0; n < b.N; n++ { 313 | _, _ = ParseResponse(respNonce) 314 | } 315 | } 316 | 317 | // ExampleCreateRequest demonstrates how to create a new time-stamping request 318 | // for an io.Reader. 319 | func ExampleCreateRequest() { 320 | _, err := CreateRequest(strings.NewReader("Content to be time-stamped"), nil) 321 | if err != nil { 322 | panic(err) 323 | } 324 | } 325 | 326 | // ExampleCreateRequest_customHashingAlgorithm demonstrates how to create a new 327 | // time-stamping request with options 328 | func ExampleCreateRequest_customHashingAlgorithm() { 329 | _, err := CreateRequest( 330 | strings.NewReader("Content to be time-stamped"), 331 | &RequestOptions{ 332 | Hash: crypto.SHA512, 333 | }) 334 | if err != nil { 335 | panic(err) 336 | } 337 | } 338 | 339 | // ExampleParseRequest demonstrates how to parse a raw der time-stamping request 340 | func ExampleParseRequest() { 341 | // CreateRequest returns the request in der bytes 342 | createdRequest, err := CreateRequest(strings.NewReader("Content to be time-stamped"), nil) 343 | if err != nil { 344 | panic(err) 345 | } 346 | 347 | // ParseRequest parses a request in der bytes 348 | parsedRequest, err := ParseRequest(createdRequest) 349 | if err != nil { 350 | panic(err) 351 | } 352 | 353 | fmt.Printf("%x\n", parsedRequest.HashedMessage) 354 | // Output: 51a3620a3b62ffaff41a434e932223b31bc69e86490c365fa1186033904f1132 355 | } 356 | 357 | func TestCreateResponseWithNoTSACertificate(t *testing.T) { 358 | tsakey := getTSARSAKey() 359 | tsaCert := getTSACert() 360 | 361 | h := sha256.New() 362 | _, err := h.Write([]byte("Hello World")) 363 | if err != nil { 364 | t.Fatal(err) 365 | } 366 | 367 | genTime := time.Now().UTC() 368 | 369 | nonce := big.NewInt(0) 370 | nonce = nonce.SetBytes([]byte{0x1, 0x2, 0x3}) 371 | 372 | duration, _ := time.ParseDuration("1s") 373 | 374 | timestamp := Timestamp{ 375 | HashAlgorithm: crypto.SHA256, 376 | HashedMessage: h.Sum(nil), 377 | Time: genTime, 378 | Nonce: nonce, 379 | Policy: asn1.ObjectIdentifier{2, 4, 5, 6}, 380 | Ordering: true, 381 | Accuracy: duration, 382 | Qualified: false, 383 | AddTSACertificate: false, 384 | } 385 | timestampBytes, err := timestamp.CreateResponse(tsaCert, tsakey) 386 | if err != nil { 387 | t.Errorf("unable to generate time stamp response: %s", err.Error()) 388 | } 389 | timestampRes, err := ParseResponse(timestampBytes) 390 | if err != nil { 391 | t.Fatalf("unable to parse time stamp response: %s", err.Error()) 392 | } 393 | 394 | if timestampRes.HashAlgorithm.HashFunc() != crypto.SHA256 { 395 | t.Errorf("expected hash algorithm is SHA256") 396 | } 397 | if len(timestampRes.HashedMessage) != 32 { 398 | t.Errorf("got %d: expected: %d", len(timestampRes.HashedMessage), 32) 399 | } 400 | 401 | if timestampRes.Qualified { 402 | t.Errorf("got %t: expected: %t", timestampRes.Qualified, true) 403 | } 404 | 405 | if timestampRes.AddTSACertificate { 406 | t.Error("TSA certificate must not be included in timestamp response") 407 | } 408 | } 409 | 410 | func TestCreateResponseWithIncludeTSACertificate(t *testing.T) { 411 | tsakey := getTSARSAKey() 412 | tsaCert := getTSACert() 413 | 414 | h := sha256.New() 415 | _, err := h.Write([]byte("Hello World")) 416 | if err != nil { 417 | t.Fatal(err) 418 | } 419 | 420 | genTime := time.Now().UTC() 421 | 422 | nonce := big.NewInt(0) 423 | nonce = nonce.SetBytes([]byte{0x1, 0x2, 0x3}) 424 | 425 | duration, _ := time.ParseDuration("1s") 426 | 427 | timestamp := Timestamp{ 428 | HashAlgorithm: crypto.SHA256, 429 | HashedMessage: h.Sum(nil), 430 | Time: genTime, 431 | Nonce: nonce, 432 | Policy: asn1.ObjectIdentifier{2, 4, 5, 6}, 433 | Ordering: true, 434 | Accuracy: duration, 435 | Qualified: true, 436 | AddTSACertificate: true, 437 | } 438 | timestampBytes, err := timestamp.CreateResponse(tsaCert, tsakey) 439 | if err != nil { 440 | t.Errorf("unable to generate time stamp response: %s", err.Error()) 441 | } 442 | 443 | // To verify the reponse using OpenSSL 444 | // openssl ts -reply -in timestamp.tsr -text 445 | // _ = os.WriteFile("timestamp.tsr", timestampBytes, 0644) 446 | 447 | timestampRes, err := ParseResponse(timestampBytes) 448 | if err != nil { 449 | t.Errorf("unable to parse time stamp response: %s", err.Error()) 450 | } 451 | 452 | if timestampRes.HashAlgorithm.HashFunc() != crypto.SHA256 { 453 | t.Errorf("expected hash algorithm is SHA256") 454 | } 455 | if len(timestampRes.HashedMessage) != 32 { 456 | t.Errorf("got %d: expected: %d", len(timestampRes.HashedMessage), 32) 457 | } 458 | 459 | if timestampRes.Accuracy != duration { 460 | t.Errorf("got accuracy %s: expected: %s", timestampRes.Accuracy, duration) 461 | } 462 | 463 | if !timestampRes.Qualified { 464 | t.Errorf("got %t: expected: %t", timestampRes.Qualified, true) 465 | } 466 | 467 | if !timestampRes.AddTSACertificate { 468 | t.Error("TSA certificate must be included in timestamp response") 469 | } 470 | } 471 | 472 | // Sign with TSU and do not embed certificates 473 | func TestSignWithTSUNoCertificate(t *testing.T) { 474 | tsukey := getTSURSAKey() 475 | tsuCert := getTSUCert() 476 | 477 | h := sha256.New() 478 | _, err := h.Write([]byte("Hello World")) 479 | if err != nil { 480 | t.Fatal(err) 481 | } 482 | 483 | genTime := time.Now().UTC() 484 | 485 | nonce := big.NewInt(0) 486 | nonce = nonce.SetBytes([]byte{0x1, 0x2, 0x3}) 487 | 488 | duration, _ := time.ParseDuration("1s") 489 | 490 | timestamp := Timestamp{ 491 | HashAlgorithm: crypto.SHA256, 492 | HashedMessage: h.Sum(nil), 493 | Time: genTime, 494 | Nonce: nonce, 495 | Policy: asn1.ObjectIdentifier{2, 4, 5, 6}, 496 | Ordering: true, 497 | Accuracy: duration, 498 | Qualified: false, 499 | AddTSACertificate: false, 500 | } 501 | timestampBytes, err := timestamp.CreateResponse(tsuCert, tsukey) 502 | if err != nil { 503 | t.Errorf("unable to generate time stamp response: %s", err.Error()) 504 | } 505 | timestampRes, err := ParseResponse(timestampBytes) 506 | if err != nil { 507 | t.Fatalf("unable to parse time stamp response: %s", err.Error()) 508 | } 509 | 510 | if timestampRes.HashAlgorithm.HashFunc() != crypto.SHA256 { 511 | t.Errorf("expected hash algorithm is SHA256") 512 | } 513 | if len(timestampRes.HashedMessage) != 32 { 514 | t.Errorf("got %d: expected: %d", len(timestampRes.HashedMessage), 32) 515 | } 516 | 517 | if timestampRes.Qualified { 518 | t.Errorf("got %t: expected: %t", timestampRes.Qualified, true) 519 | } 520 | 521 | if timestampRes.AddTSACertificate { 522 | t.Error("TSU certificate must not be included in timestamp response") 523 | } 524 | } 525 | 526 | // Sign with TSU and only embed TSU certificate 527 | func TestSignWithTSUEmbedTSUCertificate(t *testing.T) { 528 | tsukey := getTSURSAKey() 529 | tsuCert := getTSUCert() 530 | 531 | h := sha256.New() 532 | _, err := h.Write([]byte("Hello World")) 533 | if err != nil { 534 | t.Fatal(err) 535 | } 536 | 537 | genTime := time.Now().UTC() 538 | 539 | nonce := big.NewInt(0) 540 | nonce = nonce.SetBytes([]byte{0x1, 0x2, 0x3}) 541 | 542 | duration, _ := time.ParseDuration("1s") 543 | 544 | timestamp := Timestamp{ 545 | HashAlgorithm: crypto.SHA256, 546 | HashedMessage: h.Sum(nil), 547 | Time: genTime, 548 | Nonce: nonce, 549 | Policy: asn1.ObjectIdentifier{2, 4, 5, 6}, 550 | Ordering: true, 551 | Accuracy: duration, 552 | Qualified: true, 553 | AddTSACertificate: true, 554 | } 555 | timestampBytes, err := timestamp.CreateResponse(tsuCert, tsukey) 556 | if err != nil { 557 | t.Errorf("unable to generate time stamp response: %s", err.Error()) 558 | } 559 | 560 | timestampRes, err := ParseResponse(timestampBytes) 561 | if err != nil { 562 | t.Fatalf("unable to parse time stamp response: %s", err.Error()) 563 | } 564 | 565 | if timestampRes.HashAlgorithm.HashFunc() != crypto.SHA256 { 566 | t.Errorf("expected hash algorithm is SHA256") 567 | } 568 | if len(timestampRes.HashedMessage) != 32 { 569 | t.Errorf("got %d: expected: %d", len(timestampRes.HashedMessage), 32) 570 | } 571 | 572 | if timestampRes.Accuracy != duration { 573 | t.Errorf("got accuracy %s: expected: %s", timestampRes.Accuracy, duration) 574 | } 575 | 576 | if !timestampRes.Qualified { 577 | t.Errorf("got %t: expected: %t", timestampRes.Qualified, true) 578 | } 579 | 580 | if !timestampRes.AddTSACertificate { 581 | t.Error("TSU certificate must be included in timestamp response") 582 | } 583 | } 584 | 585 | // Sign with TSU and include certificate chain 586 | func TestSignWithTSUIncludeCertificateChain(t *testing.T) { 587 | tsuKey := getTSURSAKey() 588 | tsuCert := getTSUCert() 589 | tsaCert := getTSACert() 590 | 591 | h := sha256.New() 592 | _, err := h.Write([]byte("Hello World")) 593 | if err != nil { 594 | t.Fatal(err) 595 | } 596 | 597 | genTime := time.Now().UTC() 598 | 599 | nonce := big.NewInt(0) 600 | nonce = nonce.SetBytes([]byte{0x1, 0x2, 0x3}) 601 | 602 | duration, _ := time.ParseDuration("1s") 603 | 604 | timestamp := Timestamp{ 605 | HashAlgorithm: crypto.SHA256, 606 | HashedMessage: h.Sum(nil), 607 | Time: genTime, 608 | Nonce: nonce, 609 | Policy: asn1.ObjectIdentifier{2, 4, 5, 6}, 610 | Ordering: true, 611 | Accuracy: duration, 612 | Qualified: true, 613 | AddTSACertificate: true, 614 | Certificates: []*x509.Certificate{tsaCert}, // add parent certificate 615 | } 616 | timestampBytes, err := timestamp.CreateResponse(tsuCert, tsuKey) 617 | if err != nil { 618 | t.Fatalf("unable to generate time stamp response: %s", err.Error()) 619 | } 620 | 621 | timestampRes, err := ParseResponse(timestampBytes) 622 | if err != nil { 623 | t.Fatalf("unable to parse time stamp response: %s", err.Error()) 624 | } 625 | 626 | if timestampRes.HashAlgorithm.HashFunc() != crypto.SHA256 { 627 | t.Errorf("expected hash algorithm is SHA256") 628 | } 629 | if len(timestampRes.HashedMessage) != 32 { 630 | t.Errorf("got %d: expected: %d", len(timestampRes.HashedMessage), 32) 631 | } 632 | 633 | if timestampRes.Accuracy != duration { 634 | t.Errorf("got accuracy %s: expected: %s", timestampRes.Accuracy, duration) 635 | } 636 | 637 | if !timestampRes.Qualified { 638 | t.Errorf("got %t: expected: %t", timestampRes.Qualified, true) 639 | } 640 | 641 | if !timestampRes.AddTSACertificate { 642 | t.Error("TSA certificate must be included in timestamp response") 643 | } 644 | 645 | if !timestamp.Certificates[0].Equal(tsaCert) { 646 | t.Errorf("got certificate %X: expected: %X", timestamp.Certificates[0].SubjectKeyId, tsaCert.SubjectKeyId) 647 | } 648 | } 649 | 650 | func getTSURSAKey() *rsa.PrivateKey { 651 | tsuRSAKeyPEM := ` 652 | -----BEGIN RSA PRIVATE KEY----- 653 | MIIEowIBAAKCAQEA7FzZ2Uff6dPKEgJNgUi3EL21y3CzY3zGE3Wi2pTM1oGAMetP 654 | ecEdFnMM2x76lnGuBk0VW04TdOMymXtW6L7X75Yr73/88b4Ycmrg2Xh/HqiCrtQZ 655 | PrCwOn3V8UFulySqJItBUZ1ih6a0A1NNX6lMmQTbbuxLlyP4iz1HveFmOa/gkLh9 656 | Y1I9yIRTb4Mlm6yISLQkDZn2YMXqlZUv4tyNUmFlSYrMu6lsIwBn2eaBKzQYPZM0 657 | ExuTDD+d7RnrDr1tcfd5cNOq7XDNP2nIDE4rZSwRhOerDKPL9jqd60FKH40oX51/ 658 | WssiO1zVmi43uX8gr7iaJrzpkVNDN9m41zLheQIDAQABAoIBAQDA21odghnfjqGY 659 | ZCydSpmknUaSgpi8mnh8NEX3F+azN+ND1/53F+0F/kYFHJfW3VbjaU39vA0AGMmW 660 | lh7ptZ43rU6YEtRu427LHQ3uI/WFLHXE9ObMUhrY/wfr3DnCNXZmbwGS+FoG2SyU 661 | cgn1/guz51Ssgz2CSyVnZ078Tce9VISolxGnxZVhEVcssFazEWLaOe/8t2rMg4e+ 662 | RRGiaTcIkTdNTFgk15JrkSRyvU/538vVwNJ67hAwlA011l3XDpVybwEQQ46bG09J 663 | uSNOEm4XMNRxjPS6A2Fd+jtSiP4iYEwVoJU+/P7IRdoVvBjwcXnl7tX9i7o8xwhr 664 | es+NzS8BAoGBAOxxSLk8QVYGoHn+H/I+SHBY8ipY/3mwCzH3shodfAejZ+eoMVI+ 665 | cWJl67QKhsFzlAfRj1YF92h5Hx8oXVR7te7KcjXVyStPlAUigls253GaczSnXjA0 666 | 0WxpFthES8TSbSfD1VTbU1JB6evUe8KkemEw+9vbl573U3FgEeu67LnxAoGBAP/p 667 | 4HNC2JTFGox7IJoEvO2qeJfxtlyJ5vb/RwlJu/kn7mAFzzjIE1xYFDbImKN8OYA4 668 | BWXyZ+5WP+HZOBW16HXoYybT02ufFC3lp9p8xOSBs2DQKfrhqgJTOVjq7b4ovSj5 669 | 3DOnR1YojbiDHQpK2IVIj1Iz0DiIFqPhtB7CzdgJAoGANC3f7bkldhWqTqHNbQlf 670 | tSN79eqEHtfB8LoIHQlKuOjP4mjU0aCkJyH0/VuhV4npLjyKFGLmsbChNKAU0LMo 671 | eFVHFShj5+H8+ZEfEYAxXXnHWORiveK6IOGkP//6dKo3mqH2L27jmXCgbgILee4Q 672 | b+h+fIuej19nk8quycYLvhECgYAwoJsyq6AF3NInoXnXalEQBBV4IcjaGqYVhvpT 673 | jHw4YtsLye7PRk1PfbkRk9pVLlSqxXpZHc+b3S20V5ctoOw0A11b0mJZD9hAxGO5 674 | w32SQgb4vXVMo7avTGsYN0PHn2waLigmdIG8oGYVimxpOUGdSeVZ5FiLdWh/6XJV 675 | agS9KQKBgGn6Gfp9/67F0zgJ5gh5DsuY6At9VcGnSPmKaO//ME05KMazF6XW2gWs 676 | /VmHEjBRBqXPylh3xmr5DMm95OeQm3QUsNf75aPFnkukRmgmeVIfICjx0twzls4O 677 | vwxcYS6/uRJ1O1K0U2KZgqY9HGSg4Mm4Zs8mAe86evHEGX7g7N6y 678 | -----END RSA PRIVATE KEY----- 679 | ` 680 | 681 | tsuKeyPEMBlock, _ := pem.Decode([]byte(tsuRSAKeyPEM)) 682 | pvtKey, _ := x509.ParsePKCS1PrivateKey(tsuKeyPEMBlock.Bytes) 683 | 684 | return pvtKey 685 | } 686 | func getTSARSAKey() *rsa.PrivateKey { 687 | tsaRSAKeyPEM := ` 688 | -----BEGIN RSA PRIVATE KEY----- 689 | MIIEpAIBAAKCAQEApeencH+4Wo3Ry65t2/FdZkHLyQcizv8Xu+4NTEGF502fPV2y 690 | May4/ZU+GXeVTPhwfJuFj1D8Id6skgZ1DlAz+cpIqQQoaUuVM6M5MMJ6Ycf27KAs 691 | knQiEMI7BcyJBni1c/aspLMd3AwPn/4XVweX+KL8FtbNouakKOvKT9MH23hUqJuY 692 | aKxyxRABtuRYaq3PrAvR55gb/f/zLHvPh57vALi4J3WSIePXNpNzpOpZIj+J+UMQ 693 | NQVWVPzRW7Wf057o9cvSl/P/eChKWIeMAsYE5+7Rybj7MnRi5XqDFDCdPLmHaT6/ 694 | ZcE6ijHSjoETi/Ut9BMOyIUqpQAs0uZH39FFwwIDAQABAoIBADuncUh9VD+TUQWJ 695 | Ac2dGzVioTD2lOiTRuh3L2blBI3oFkMNhr5f2eCsojisDA4yIthbX4np188h7zFO 696 | ixaLdjTyLHBBo3pBCDQaE71ZoIG6UipBaeV7Rqh5/pkWM4sVKkG5R9is4ya1W4Tu 697 | 61uKynVHvZdEw4o4nnxsVEGhouih5q/fmETi7XTCYSCe4gljVDtRpvFQBOrrhye/ 698 | BT38SvrXQR2WmgLLpfo+1VR5zcm9bXJXrkOKYNXWDxl9kpY+hwXD0IhTXl4GkqEe 699 | 8CP4WFHtX5WA4s9qLATp/zT7fme2Ojh+NkIdU0FMI9lf4pNX+URxii+hn15vrtCi 700 | UxaSVtECgYEA0FobH8XOw7SWjJRs9wfLoF/Wl3s4ET9neJwx047Xlop8QAwHYzo7 701 | CiEH+aodgr/UC8KM62+3y4pZgn3Bmt3/p/WyKOsfG3TZXqvuSGqTXO9sn3T1Z552 702 | jVT/1/3qapHODL4ct52FHxrr243Jp2vfeMciU0tLdsx5FIgRCScqm0sCgYEAy9h/ 703 | qnDAC1fI4eEDYgj+kIUDyQegeKbi79U3aF5QjYSgvYm1pev/Zac8+x9X/zQupObB 704 | FmgbtPYrXTY5J38qG/ELjDu7aHfXqgHcVTda0MsGsaoSCmaJ3y19ewxsmK9pFaEl 705 | BUTmFd2hywK34RG00dyYcrvmP6M4OP/Do1+WPGkCgYEAv9lYhIcl/rr4rXW2aDk7 706 | XO8ir9V8KRWS91IL51vuU+YsxuTMoKfr2UXVDCWCivSMElAQZnI2cStxhGC7txiX 707 | 4lawuFDYEfYkebIi9Xd9PeQQxztxBPq6+yS7eG2MPpkHfGBKHSDkhWHKsB39Azan 708 | TZU/nCcG09sv2qH33c+8wcUCgYEAli3TqKNWqUSsZ9WZ43ES8zA8ILAwxpLVILKq 709 | Foddu1VaAyngnPQofiDe6XgnIYq1TqH+4V4kA4dVXV/kbbffMyS8SD19jbK1PbgP 710 | Nu0ISEk7jkro7aarrrPZ/XyiyT56IghNuPsQtE1LtMA07mlYGUD3Q5gxQvMiKcQs 711 | w0FZ8vkCgYA7wuwLs7d9LJ4KqMNmOe0eRvIxp+Y8psxykMd1wz3PjdPz30U03xe2 712 | o40r2ZNTK/OGYPmAOcwma7SjenBQve19eVUaECUVREmbvaJqVzz0uSrfqXrUVIiJ 713 | YyOfhPUI5XhkyUlunO5pSAd0CtRv7NVW1wKDjMbJvgV0MlbVvGraAg== 714 | -----END RSA PRIVATE KEY----- 715 | ` 716 | 717 | tsaKeyPEMBlock, _ := pem.Decode([]byte(tsaRSAKeyPEM)) 718 | pvtKey, _ := x509.ParsePKCS1PrivateKey(tsaKeyPEMBlock.Bytes) 719 | 720 | return pvtKey 721 | } 722 | func getTSUCert() *x509.Certificate { 723 | tsaCertPEM := ` 724 | -----BEGIN CERTIFICATE----- 725 | MIIDrTCCApWgAwIBAgITHtUKVw2T5tfI4jk7zfJvKj39MDANBgkqhkiG9w0BAQsF 726 | ADBdMQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwY 727 | SW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMRYwFAYDVQQDDA1UZXN0IFJTQSBDZXJ0 728 | MB4XDTIyMTAxODA2MzYxNloXDTQyMTAxODA2MzYxNlowYzELMAkGA1UEBhMCQVUx 729 | EzARBgNVBAgTClNvbWUtU3RhdGUxITAfBgNVBAsTGEludGVybmV0IFdpZGdpdHMg 730 | UHR5IEx0ZDEcMBoGA1UEAxMTVGVzdCBSU0EgQ2hpbGQgQ2VydDCCASIwDQYJKoZI 731 | hvcNAQEBBQADggEPADCCAQoCggEBAOxc2dlH3+nTyhICTYFItxC9tctws2N8xhN1 732 | otqUzNaBgDHrT3nBHRZzDNse+pZxrgZNFVtOE3TjMpl7Vui+1++WK+9//PG+GHJq 733 | 4Nl4fx6ogq7UGT6wsDp91fFBbpckqiSLQVGdYoemtANTTV+pTJkE227sS5cj+Is9 734 | R73hZjmv4JC4fWNSPciEU2+DJZusiEi0JA2Z9mDF6pWVL+LcjVJhZUmKzLupbCMA 735 | Z9nmgSs0GD2TNBMbkww/ne0Z6w69bXH3eXDTqu1wzT9pyAxOK2UsEYTnqwyjy/Y6 736 | netBSh+NKF+df1rLIjtc1ZouN7l/IK+4mia86ZFTQzfZuNcy4XkCAwEAAaNgMF4w 737 | DgYDVR0PAQH/BAQDAgeAMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFCFNxjsFpw4I 738 | 5p+o62/J17zDEa8FMB8GA1UdIwQYMBaAFIjUWTfL8OkBDBFeGipGGN5BGygKMA0G 739 | CSqGSIb3DQEBCwUAA4IBAQCYdgikay21S2fYz+mk3dnhUPLnXI9Gg6U9ox2js+Yf 740 | dYOMXX5RlG2HKOEnVI7mOPEaEiSAuvE8x6mQ52xVOw4FWjPO7S5pCBO8YPyyZCer 741 | 5bOFhz/zbv7xpZISvTTPfOXqSM1MvkcX9kfPDRagGfB6viVQwhWMQK4Sd0d5wSf2 742 | FHsUAuq+EauBDgTe4bdCMS/AQSF/xhFL1KUwvkI8HjDE+JGu7hexWtlxwD/dnvpD 743 | 6ZrUnRLuSF3jebNb2DwIXb05ub+YJoBx/0I/zYe3vWISDtO/onNAZz9hnmAzL32f 744 | 69EW22PQaOUDtTbfT2PD09uTUfmA+zZggjPgaWjbw+gf 745 | -----END CERTIFICATE----- 746 | ` 747 | certPEMBlock, _ := pem.Decode([]byte(tsaCertPEM)) 748 | tsaCert, _ := x509.ParseCertificate(certPEMBlock.Bytes) 749 | 750 | return tsaCert 751 | } 752 | func getTSACert() *x509.Certificate { 753 | tsaCertPEM := ` 754 | -----BEGIN CERTIFICATE----- 755 | MIIDmzCCAoOgAwIBAgIUTrgB1p7WpwYXjwGs/uwfKJt4cFcwDQYJKoZIhvcNAQEL 756 | BQAwXTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM 757 | GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEWMBQGA1UEAwwNVGVzdCBSU0EgQ2Vy 758 | dDAeFw0yMDAzMDQyMjA4MDVaFw00MDAyMjgyMjA4MDVaMF0xCzAJBgNVBAYTAkFV 759 | MRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRz 760 | IFB0eSBMdGQxFjAUBgNVBAMMDVRlc3QgUlNBIENlcnQwggEiMA0GCSqGSIb3DQEB 761 | AQUAA4IBDwAwggEKAoIBAQCl56dwf7hajdHLrm3b8V1mQcvJByLO/xe77g1MQYXn 762 | TZ89XbIxrLj9lT4Zd5VM+HB8m4WPUPwh3qySBnUOUDP5ykipBChpS5Uzozkwwnph 763 | x/bsoCySdCIQwjsFzIkGeLVz9qyksx3cDA+f/hdXB5f4ovwW1s2i5qQo68pP0wfb 764 | eFSom5horHLFEAG25Fhqrc+sC9HnmBv9//Mse8+Hnu8AuLgndZIh49c2k3Ok6lki 765 | P4n5QxA1BVZU/NFbtZ/Tnuj1y9KX8/94KEpYh4wCxgTn7tHJuPsydGLleoMUMJ08 766 | uYdpPr9lwTqKMdKOgROL9S30Ew7IhSqlACzS5kff0UXDAgMBAAGjUzBRMB0GA1Ud 767 | DgQWBBSI1Fk3y/DpAQwRXhoqRhjeQRsoCjAfBgNVHSMEGDAWgBSI1Fk3y/DpAQwR 768 | XhoqRhjeQRsoCjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQAP 769 | +jK6M/zPFrO/hrXOXlfEntbKwxFWoil/BRVMkgMp6JO44wn9QS+oRIVKcMToTPe5 770 | XaU4D8YgHPFiyhaTOQ95RDVZuy5VPf1li1oujPHXP6Y9Ps5RF9AKtLYdJa8ZBmRx 771 | Cg3mHV4f6VJWziWz3s5n6DVQ5DDrSkQ0dIRs5Tu9W4+aHJUMwdkSP0klvBnlzPhq 772 | kl++ygWDU5bJMbwD53eGieJyo5wL0SR08ijiGxCTmYOUuPl/C62MTPJU+oR8qRd3 773 | I/rCr/gywfHmAbgupBo9ikC9rrYD5maaC59xr4NjjI1vSeS3nrO9qmd9KnGD98P8 774 | wA4N9tN/F776b2RG2RZD 775 | -----END CERTIFICATE----- 776 | ` 777 | certPEMBlock, _ := pem.Decode([]byte(tsaCertPEM)) 778 | tsaCert, _ := x509.ParseCertificate(certPEMBlock.Bytes) 779 | 780 | return tsaCert 781 | } 782 | 783 | func TestCreateResponseSHA384(t *testing.T) { 784 | tsakey := getTSARSAKey() 785 | tsaCert := getTSACert() 786 | 787 | h := sha256.New() 788 | _, err := h.Write([]byte("Hello World")) 789 | if err != nil { 790 | t.Fatal(err) 791 | } 792 | 793 | genTime := time.Now().UTC() 794 | 795 | nonce := big.NewInt(0) 796 | nonce = nonce.SetBytes([]byte{0x1, 0x2, 0x3}) 797 | 798 | duration, _ := time.ParseDuration("1s") 799 | 800 | timestamp := Timestamp{ 801 | HashAlgorithm: crypto.SHA256, 802 | HashedMessage: h.Sum(nil), 803 | Time: genTime, 804 | Nonce: nonce, 805 | Policy: asn1.ObjectIdentifier{2, 4, 5, 6}, 806 | Ordering: true, 807 | Accuracy: duration, 808 | Qualified: false, 809 | AddTSACertificate: false, 810 | } 811 | timestampBytes, err := timestamp.CreateResponseWithOpts(tsaCert, tsakey, crypto.SHA384) 812 | if err != nil { 813 | t.Errorf("unable to generate time stamp response: %s", err.Error()) 814 | } 815 | timestampRes, err := ParseResponse(timestampBytes) 816 | if err != nil { 817 | t.Fatalf("unable to parse time stamp response: %s", err.Error()) 818 | } 819 | 820 | p7, err := pkcs7.Parse(timestampRes.RawToken) 821 | if err != nil { 822 | t.Fatal(err) 823 | } 824 | if got := p7.Signers[0].DigestAlgorithm; !got.Algorithm.Equal(pkcs7.OIDDigestAlgorithmSHA384) { 825 | t.Fatalf("unexpected digest algorithm: want SHA384(%s), got %s", pkcs7.OIDDigestAlgorithmSHA384, got.Algorithm.String()) 826 | } 827 | } 828 | --------------------------------------------------------------------------------