Skip to content

Commit

Permalink
feat: enhanced output of TSTInfo Validate (#23)
Browse files Browse the repository at this point in the history
Signed-off-by: Patrick Zheng <[email protected]>
  • Loading branch information
Two-Hearts authored Jul 2, 2024
1 parent dcff9b7 commit 0bcf659
Show file tree
Hide file tree
Showing 9 changed files with 232 additions and 56 deletions.
18 changes: 9 additions & 9 deletions conformance_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,17 +113,17 @@ func TestTSATimestampGranted(t *testing.T) {
if err != nil {
t.Fatal("SignedToken.Info() error =", err)
}
ts, accuracy, err := info.Validate(message)
timestamp, err := info.Validate(message)
if err != nil {
t.Errorf("TSTInfo.Timestamp() error = %v", err)
}
wantTimestamp := now
if ts != wantTimestamp {
t.Errorf("TSTInfo.Timestamp() Timestamp = %v, want %v", ts, wantTimestamp)
wantTimestampValue := time.Date(2021, 9, 18, 11, 54, 34, 0, time.UTC)
wantTimestampAccuracy := time.Second
if timestamp.Value != wantTimestampValue {
t.Fatalf("TSTInfo.Timestamp() Timestamp = %v, want %v", wantTimestampValue, timestamp.Value)
}
wantAccuracy := time.Second
if accuracy != wantAccuracy {
t.Errorf("TSTInfo.Timestamp() Accuracy = %v, want %v", accuracy, wantAccuracy)
if timestamp.Accuracy != wantTimestampAccuracy {
t.Fatalf("TSTInfo.Timestamp() Timestamp Accuracy = %v, want %v", wantTimestampAccuracy, timestamp.Accuracy)
}
}

Expand Down Expand Up @@ -328,7 +328,7 @@ func newTestTSA(malformedExtKeyUsage, criticalTimestampingExtKeyUsage bool) (*te
BasicConstraintsValid: true,
}
if criticalTimestampingExtKeyUsage {
extValue, err := asn1.Marshal([]asn1.ObjectIdentifier{oid.TimeStamping})
extValue, err := asn1.Marshal([]asn1.ObjectIdentifier{oid.Timestamping})
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -414,7 +414,7 @@ func (tsa *testTSA) Timestamp(_ context.Context, req *Request) (*Response, error
Status: pki.StatusInfo{
Status: pki.StatusGranted,
},
TimeStampToken: token,
TimestampToken: token,
}, nil
}

Expand Down
38 changes: 19 additions & 19 deletions http_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,10 @@ func TestHTTPTimestampGranted(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
const wantContentType = MediaTypeTimestampQuery
if got := r.Header.Get("Content-Type"); got != wantContentType {
t.Fatalf("TimeStampRequest.ContentType = %v, want %v", err, wantContentType)
t.Fatalf("TimestampRequest.ContentType = %v, want %v", err, wantContentType)
}
if _, err := io.ReadAll(r.Body); err != nil {
t.Fatalf("TimeStampRequest.Body read error = %v", err)
t.Fatalf("TimestampRequest.Body read error = %v", err)
}

// write reply
Expand Down Expand Up @@ -122,17 +122,17 @@ func TestHTTPTimestampGranted(t *testing.T) {
if err != nil {
t.Fatal("SignedToken.Info() error =", err)
}
timestamp, accuracy, err := info.Validate(message)
timestamp, err := info.Validate(message)
if err != nil {
t.Errorf("TSTInfo.Timestamp() error = %v", err)
}
wantTimestamp := time.Date(2021, 9, 18, 11, 54, 34, 0, time.UTC)
if timestamp != wantTimestamp {
t.Errorf("TSTInfo.Timestamp() Timestamp = %v, want %v", timestamp, wantTimestamp)
wantTimestampValue := time.Date(2021, 9, 18, 11, 54, 34, 0, time.UTC)
wantTimestampAccuracy := time.Second
if timestamp.Value != wantTimestampValue {
t.Fatalf("TSTInfo.Timestamp() Timestamp = %v, want %v", wantTimestampValue, timestamp.Value)
}
wantAccuracy := time.Second
if accuracy != wantAccuracy {
t.Errorf("TSTInfo.Timestamp() Accuracy = %v, want %v", accuracy, wantAccuracy)
if timestamp.Accuracy != wantTimestampAccuracy {
t.Fatalf("TSTInfo.Timestamp() Timestamp Accuracy = %v, want %v", wantTimestampAccuracy, timestamp.Accuracy)
}
}

Expand All @@ -145,10 +145,10 @@ func TestHTTPTimestampRejection(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
const wantContentType = MediaTypeTimestampQuery
if got := r.Header.Get("Content-Type"); got != wantContentType {
t.Fatalf("TimeStampRequest.ContentType = %v, want %v", err, wantContentType)
t.Fatalf("TimestampRequest.ContentType = %v, want %v", err, wantContentType)
}
if _, err := io.ReadAll(r.Body); err != nil {
t.Fatalf("TimeStampRequest.Body read error = %v", err)
t.Fatalf("TimestampRequest.Body read error = %v", err)
}

// write reply
Expand Down Expand Up @@ -267,10 +267,10 @@ func TestHttpTimestamperTimestamp(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
const wantContentType = MediaTypeTimestampQuery
if got := r.Header.Get("Content-Type"); got != wantContentType {
t.Fatalf("TimeStampRequest.ContentType = %v, want %v", err, wantContentType)
t.Fatalf("TimestampRequest.ContentType = %v, want %v", err, wantContentType)
}
if _, err := io.ReadAll(r.Body); err != nil {
t.Fatalf("TimeStampRequest.Body read error = %v", err)
t.Fatalf("TimestampRequest.Body read error = %v", err)
}

// write reply
Expand Down Expand Up @@ -308,10 +308,10 @@ func TestHttpTimestamperTimestamp(t *testing.T) {
ts2 := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
const wantContentType = MediaTypeTimestampQuery
if got := r.Header.Get("Content-Type"); got != wantContentType {
t.Fatalf("TimeStampRequest.ContentType = %v, want %v", err, wantContentType)
t.Fatalf("TimestampRequest.ContentType = %v, want %v", err, wantContentType)
}
if _, err := io.ReadAll(r.Body); err != nil {
t.Fatalf("TimeStampRequest.Body read error = %v", err)
t.Fatalf("TimestampRequest.Body read error = %v", err)
}

// write reply
Expand All @@ -334,10 +334,10 @@ func TestHttpTimestamperTimestamp(t *testing.T) {
ts3 := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
const wantContentType = MediaTypeTimestampQuery
if got := r.Header.Get("Content-Type"); got != wantContentType {
t.Fatalf("TimeStampRequest.ContentType = %v, want %v", err, wantContentType)
t.Fatalf("TimestampRequest.ContentType = %v, want %v", err, wantContentType)
}
if _, err := io.ReadAll(r.Body); err != nil {
t.Fatalf("TimeStampRequest.Body read error = %v", err)
t.Fatalf("TimestampRequest.Body read error = %v", err)
}

// write reply
Expand All @@ -363,10 +363,10 @@ func TestHttpTimestamperTimestamp(t *testing.T) {
ts4 := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
const wantContentType = MediaTypeTimestampQuery
if got := r.Header.Get("Content-Type"); got != wantContentType {
t.Fatalf("TimeStampRequest.ContentType = %v, want %v", err, wantContentType)
t.Fatalf("TimestampRequest.ContentType = %v, want %v", err, wantContentType)
}
if _, err := io.ReadAll(r.Body); err != nil {
t.Fatalf("TimeStampRequest.Body read error = %v", err)
t.Fatalf("TimestampRequest.Body read error = %v", err)
}

// write reply
Expand Down
13 changes: 11 additions & 2 deletions internal/oid/oid.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,17 @@ var (
// Reference: https://www.rfc-editor.org/rfc/rfc5280.html#section-4.2.1.12
ExtKeyUsage = asn1.ObjectIdentifier{2, 5, 29, 37}

// TimeStamping (id-kp-timeStamping) is defined in RFC 3161 2.3
// Timestamping (id-kp-timeStamping) is defined in RFC 3161 2.3
//
// Reference: https://datatracker.ietf.org/doc/html/rfc3161#section-2.3
TimeStamping = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 8}
Timestamping = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 8}
)

// OIDs for RFC 3628 Policy Requirements for Time-Stamping Authorities (TSAs)
var (
// BaselineTimestampPolicy (baseline time-stamp policy) is defined in
// RFC 3628
//
// Referene: https://datatracker.ietf.org/doc/html/rfc3628#section-5.2
BaselineTimestampPolicy = asn1.ObjectIdentifier{0, 4, 0, 2023, 1, 1}
)
4 changes: 2 additions & 2 deletions response.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ type generalNames struct {
// timeStampToken TimeStampToken OPTIONAL }
type Response struct {
Status pki.StatusInfo
TimeStampToken asn1.RawValue `asn1:"optional"`
TimestampToken asn1.RawValue `asn1:"optional"`
}

// MarshalBinary encodes the response to binary form.
Expand Down Expand Up @@ -138,7 +138,7 @@ func (r *Response) SignedToken() (*SignedToken, error) {
if err := r.validateStatus(); err != nil {
return nil, err
}
return ParseSignedToken(r.TimeStampToken.FullBytes)
return ParseSignedToken(r.TimestampToken.FullBytes)
}

// Validate checks if resp is a successful timestamp response against
Expand Down
18 changes: 9 additions & 9 deletions response_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ func TestValidateResponse(t *testing.T) {
Status: pki.StatusInfo{
Status: pki.StatusGranted,
},
TimeStampToken: asn1.RawValue{
TimestampToken: asn1.RawValue{
FullBytes: token,
},
}
Expand All @@ -187,7 +187,7 @@ func TestValidateResponse(t *testing.T) {
Status: pki.StatusInfo{
Status: pki.StatusGranted,
},
TimeStampToken: asn1.RawValue{
TimestampToken: asn1.RawValue{
FullBytes: token,
},
}
Expand All @@ -208,7 +208,7 @@ func TestValidateResponse(t *testing.T) {
Status: pki.StatusInfo{
Status: pki.StatusGranted,
},
TimeStampToken: asn1.RawValue{
TimestampToken: asn1.RawValue{
FullBytes: token,
},
}
Expand All @@ -227,7 +227,7 @@ func TestValidateResponse(t *testing.T) {
Status: pki.StatusInfo{
Status: pki.StatusGranted,
},
TimeStampToken: asn1.RawValue{
TimestampToken: asn1.RawValue{
FullBytes: token,
},
}
Expand Down Expand Up @@ -264,7 +264,7 @@ func TestValidateResponse(t *testing.T) {
Status: pki.StatusInfo{
Status: pki.StatusGranted,
},
TimeStampToken: asn1.RawValue{
TimestampToken: asn1.RawValue{
FullBytes: token,
},
}
Expand All @@ -286,7 +286,7 @@ func TestValidateResponse(t *testing.T) {
Status: pki.StatusInfo{
Status: pki.StatusGranted,
},
TimeStampToken: asn1.RawValue{
TimestampToken: asn1.RawValue{
FullBytes: token,
},
}
Expand All @@ -308,7 +308,7 @@ func TestValidateResponse(t *testing.T) {
Status: pki.StatusInfo{
Status: pki.StatusGranted,
},
TimeStampToken: asn1.RawValue{
TimestampToken: asn1.RawValue{
FullBytes: token,
},
}
Expand All @@ -332,7 +332,7 @@ func TestValidateResponse(t *testing.T) {
Status: pki.StatusInfo{
Status: pki.StatusGranted,
},
TimeStampToken: asn1.RawValue{
TimestampToken: asn1.RawValue{
FullBytes: token,
},
}
Expand All @@ -355,7 +355,7 @@ func TestValidateResponse(t *testing.T) {
Status: pki.StatusInfo{
Status: pki.StatusGranted,
},
TimeStampToken: asn1.RawValue{
TimestampToken: asn1.RawValue{
FullBytes: token,
},
}
Expand Down
45 changes: 45 additions & 0 deletions timestamp.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// Copyright The Notary Project Authors.
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package tspclient

import "time"

// Timestamp denotes the time at which the timestamp token was created by the TSA
//
// Reference: RFC 3161 2.4.2
type Timestamp struct {
// Value is the GenTime of TSTInfo
Value time.Time

// Accuracy is the Accuracy of TSTInfo
Accuracy time.Duration
}

// BoundedBefore returns true if the upper limit of the time at which the
// timestamp token was created is before or equal to u.
//
// Reference: RFC 3161 2.4.2
func (t *Timestamp) BoundedBefore(u time.Time) bool {
timestampUpperLimit := t.Value.Add(t.Accuracy)
return timestampUpperLimit.Before(u) || timestampUpperLimit.Equal(u)
}

// BoundedAfter returns true if the lower limit of the time at which the
// timestamp token was created is after or equal to u.
//
// Reference: RFC 3161 2.4.2
func (t *Timestamp) BoundedAfter(u time.Time) bool {
timestampLowerLimit := t.Value.Add(-t.Accuracy)
return timestampLowerLimit.After(u) || timestampLowerLimit.Equal(u)
}
85 changes: 85 additions & 0 deletions timestamp_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
// Copyright The Notary Project Authors.
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package tspclient

import (
"testing"
"time"
)

func TestTimestamp(t *testing.T) {
// timestamp range:
// [time.Date(2021, time.September, 17, 14, 9, 8, 0, time.UTC),
// time.Date(2021, time.September, 17, 14, 9, 12, 0, time.UTC)]
timestamp := Timestamp{
Value: time.Date(2021, time.September, 17, 14, 9, 10, 0, time.UTC),
Accuracy: 2 * time.Second,
}
u1 := time.Date(2021, time.September, 17, 14, 9, 7, 0, time.UTC)
u2 := time.Date(2021, time.September, 17, 14, 9, 8, 0, time.UTC)
u3 := time.Date(2021, time.September, 17, 14, 9, 9, 0, time.UTC)
u4 := time.Date(2021, time.September, 17, 14, 9, 10, 0, time.UTC)
u5 := time.Date(2021, time.September, 17, 14, 9, 11, 0, time.UTC)
u6 := time.Date(2021, time.September, 17, 14, 9, 12, 0, time.UTC)
u7 := time.Date(2021, time.September, 17, 14, 9, 13, 0, time.UTC)

if timestamp.BoundedBefore(u1) {
t.Fatal("timestamp.BoundedBefore expected false, but got true")
}
if !timestamp.BoundedAfter(u1) {
t.Fatal("timestamp.BoundedAfter expected true, but got false")
}

if timestamp.BoundedBefore(u2) {
t.Fatal("timestamp.BoundedBefore expected false, but got true")
}
if !timestamp.BoundedAfter(u2) {
t.Fatal("timestamp.BoundedAfter expected true, but got false")
}

if timestamp.BoundedBefore(u3) {
t.Fatal("timestamp.BoundedBefore expected false, but got true")
}
if timestamp.BoundedAfter(u3) {
t.Fatal("timestamp.BoundedAfter expected false, but got true")
}

if timestamp.BoundedBefore(u4) {
t.Fatal("timestamp.BoundedBefore expected false, but got true")
}
if timestamp.BoundedAfter(u4) {
t.Fatal("timestamp.BoundedAfter expected false, but got true")
}

if timestamp.BoundedBefore(u5) {
t.Fatal("timestamp.BoundedBefore expected false, but got true")
}
if timestamp.BoundedAfter(u5) {
t.Fatal("timestamp.BoundedAfter expected false, but got true")
}

if !timestamp.BoundedBefore(u6) {
t.Fatal("timestamp.BoundedBefore expected true, but got false")
}
if timestamp.BoundedAfter(u6) {
t.Fatal("timestamp.BoundedAfter expected false, but got true")
}

if !timestamp.BoundedBefore(u7) {
t.Fatal("timestamp.BoundedBefore expected true, but got false")
}
if timestamp.BoundedAfter(u7) {
t.Fatal("timestamp.BoundedAfter expected false, but got true")
}
}
Loading

0 comments on commit 0bcf659

Please sign in to comment.