Skip to content

Commit

Permalink
Merge branch 'notaryproject:main' into nonce
Browse files Browse the repository at this point in the history
  • Loading branch information
Two-Hearts authored Oct 29, 2024
2 parents 14d077f + 718b4b8 commit 3fa2921
Show file tree
Hide file tree
Showing 7 changed files with 44 additions and 9 deletions.
9 changes: 8 additions & 1 deletion http.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,16 @@ func NewHTTPTimestamper(httpClient *http.Client, endpoint string) (Timestamper,
if httpClient == nil {
httpClient = &http.Client{Timeout: 5 * time.Second}
}
if _, err := url.Parse(endpoint); err != nil {
tsaURL, err := url.Parse(endpoint)
if err != nil {
return nil, err
}
if tsaURL.Scheme != "http" && tsaURL.Scheme != "https" {
return nil, fmt.Errorf("endpoint %q: scheme must be http or https, but got %q", endpoint, tsaURL.Scheme)
}
if tsaURL.Host == "" {
return nil, fmt.Errorf("endpoint %q: host cannot be empty", endpoint)
}
return &httpTimestamper{
httpClient: httpClient,
endpoint: endpoint,
Expand Down
18 changes: 18 additions & 0 deletions http_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,24 @@ func TestNewHTTPTimestamper(t *testing.T) {
if _, err := NewHTTPTimestamper(nil, malformedURL); err == nil || err.Error() != expectedErrMsg {
t.Fatalf("expected error %s, but got %v", expectedErrMsg, err)
}

malformedURL = "invalid"
expectedErrMsg = `endpoint "invalid": scheme must be http or https, but got ""`
if _, err := NewHTTPTimestamper(nil, malformedURL); err == nil || err.Error() != expectedErrMsg {
t.Fatalf("expected error %s, but got %v", expectedErrMsg, err)
}

malformedURL = "invalid://"
expectedErrMsg = `endpoint "invalid://": scheme must be http or https, but got "invalid"`
if _, err := NewHTTPTimestamper(nil, malformedURL); err == nil || err.Error() != expectedErrMsg {
t.Fatalf("expected error %s, but got %v", expectedErrMsg, err)
}

malformedURL = "https://"
expectedErrMsg = `endpoint "https://": host cannot be empty`
if _, err := NewHTTPTimestamper(nil, malformedURL); err == nil || err.Error() != expectedErrMsg {
t.Fatalf("expected error %s, but got %v", expectedErrMsg, err)
}
}

func TestHttpTimestamperTimestamp(t *testing.T) {
Expand Down
15 changes: 10 additions & 5 deletions internal/cms/signed.go
Original file line number Diff line number Diff line change
Expand Up @@ -248,14 +248,19 @@ func (d *ParsedSignedData) verifySignedAttributes(signerInfo *SignerInfo, chains

// verify attributes if present
if len(signerInfo.SignedAttributes) == 0 {
if d.ContentType.Equal(oid.Data) {
return nil, nil
}
// signed attributes MUST be present if the content type of the
// EncapsulatedContentInfo value being signed is not id-data.
// According to RFC 5652, if the Content Type is id-data, signed
// attributes can be empty. However, this cms package is designed for
// timestamp (RFC 3161) and the content type must be id-ct-TSTInfo,
// so we require signed attributes to be present.
return nil, VerificationError{Message: "missing signed attributes"}
}

// this CMS package is designed for timestamping (RFC 3161), so checking the
// content type to be id-ct-TSTInfo is an optimization for tspclient to
// fail fast.
if !oid.TSTInfo.Equal(d.ContentType) {
return nil, fmt.Errorf("unexpected content type: %v. Expected to be id-ct-TSTInfo (%v)", d.ContentType, oid.TSTInfo)
}
var contentType asn1.ObjectIdentifier
if err := signerInfo.SignedAttributes.Get(oid.ContentType, &contentType); err != nil {
return nil, VerificationError{Message: "invalid content type", Detail: err}
Expand Down
7 changes: 6 additions & 1 deletion internal/cms/signed_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,12 @@ func TestVerify(t *testing.T) {
{
name: "id-data content type without signed attributes",
filePath: "testdata/SignedDataWithoutSignedAttributes.p7s",
wantErr: false,
wantErr: true,
},
{
name: "invalid content type",
filePath: "testdata/TimeStampTokenWithInvalidContentType.p7s",
wantErr: true,
},
{
name: "an invalid and a valid signer info",
Expand Down
Binary file not shown.
2 changes: 1 addition & 1 deletion token.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ func ParseSignedToken(berData []byte) (*SignedToken, error) {
return nil, err
}
if !oid.TSTInfo.Equal(signed.ContentType) {
return nil, fmt.Errorf("unexpected content type: %v", signed.ContentType)
return nil, fmt.Errorf("unexpected content type: %v. Expected to be id-ct-TSTInfo (%v)", signed.ContentType, oid.TSTInfo)
}
return (*SignedToken)(signed), nil
}
Expand Down
2 changes: 1 addition & 1 deletion token_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ func TestParseSignedToken(t *testing.T) {
if err != nil {
t.Fatal(err)
}
expectedErrMsg := fmt.Sprintf("unexpected content type: %v", oid.Data)
expectedErrMsg := fmt.Sprintf("unexpected content type: %v. Expected to be id-ct-TSTInfo (1.2.840.113549.1.9.16.1.4)", oid.Data)
_, err = ParseSignedToken(timestampToken)
if err == nil || err.Error() != expectedErrMsg {
t.Fatalf("expected error %s, but got %v", expectedErrMsg, err)
Expand Down

0 comments on commit 3fa2921

Please sign in to comment.