Merge branch '18051-blob-signing'
authorTom Clegg <tom@curii.com>
Tue, 21 Sep 2021 15:34:56 +0000 (11:34 -0400)
committerTom Clegg <tom@curii.com>
Tue, 21 Sep 2021 15:34:56 +0000 (11:34 -0400)
refs #18051

Arvados-DCO-1.1-Signed-off-by: Tom Clegg <tom@curii.com>

sdk/go/arvados/blob_signature.go
sdk/go/arvados/blob_signature_test.go

index 2202016bcc6b8a607c7f7d8241c80166247b87b4..47b31a18e893d0a848f39d0b9a16e5e736c84c71 100644 (file)
@@ -9,13 +9,13 @@
 package arvados
 
 import (
+       "bytes"
        "crypto/hmac"
        "crypto/sha1"
        "errors"
        "fmt"
        "regexp"
        "strconv"
-       "strings"
        "time"
 )
 
@@ -33,9 +33,9 @@ var (
 
 // makePermSignature generates a SHA-1 HMAC digest for the given blob,
 // token, expiry, and site secret.
-func makePermSignature(blobHash, apiToken, expiry, blobSignatureTTL string, permissionSecret []byte) string {
+func makePermSignature(blobHash []byte, apiToken, expiry, blobSignatureTTL string, permissionSecret []byte) string {
        hmac := hmac.New(sha1.New, permissionSecret)
-       hmac.Write([]byte(blobHash))
+       hmac.Write(blobHash)
        hmac.Write([]byte("@"))
        hmac.Write([]byte(apiToken))
        hmac.Write([]byte("@"))
@@ -73,7 +73,10 @@ func SignLocator(blobLocator, apiToken string, expiry time.Time, blobSignatureTT
                return blobLocator
        }
        // Strip off all hints: only the hash is used to sign.
-       blobHash := strings.Split(blobLocator, "+")[0]
+       blobHash := []byte(blobLocator)
+       if hints := bytes.IndexRune(blobHash, '+'); hints > 0 {
+               blobHash = blobHash[:hints]
+       }
        timestampHex := fmt.Sprintf("%08x", expiry.Unix())
        blobSignatureTTLHex := strconv.FormatInt(int64(blobSignatureTTL.Seconds()), 16)
        return blobLocator +
@@ -100,7 +103,7 @@ func VerifySignature(signedLocator, apiToken string, blobSignatureTTL time.Durat
        if matches == nil {
                return ErrSignatureMissing
        }
-       blobHash := matches[1]
+       blobHash := []byte(matches[1])
        signatureHex := matches[6]
        expiryHex := matches[7]
        if expiryTime, err := parseHexTimestamp(expiryHex); err != nil {
index 847f9a8ae2ef08f5fbee1548af3528fc2d9f90d7..d23a18ac74ba5b976812e72fcb919b5e12345f3f 100644 (file)
@@ -32,6 +32,17 @@ var _ = check.Suite(&BlobSignatureSuite{})
 
 type BlobSignatureSuite struct{}
 
+func (s *BlobSignatureSuite) BenchmarkSignManifest(c *check.C) {
+       DebugLocksPanicMode = false
+       ts, err := parseHexTimestamp(knownTimestamp)
+       c.Check(err, check.IsNil)
+       c.Logf("test manifest is %d bytes", len(bigmanifest))
+       for i := 0; i < c.N; i++ {
+               m := SignManifest(bigmanifest, knownToken, ts, blobSignatureTTL, []byte(knownKey))
+               c.Check(m, check.Not(check.Equals), "")
+       }
+}
+
 func (s *BlobSignatureSuite) TestSignLocator(c *check.C) {
        ts, err := parseHexTimestamp(knownTimestamp)
        c.Check(err, check.IsNil)