X-Git-Url: https://git.arvados.org/arvados.git/blobdiff_plain/c8b119d10b41cd507a6677d4feab7974362a153e..57b2caac6b7bf858a946c22bb70ca220ca84ac6a:/sdk/go/arvados/blob_signature.go diff --git a/sdk/go/arvados/blob_signature.go b/sdk/go/arvados/blob_signature.go index 132939547a..9a031face2 100644 --- a/sdk/go/arvados/blob_signature.go +++ b/sdk/go/arvados/blob_signature.go @@ -9,6 +9,7 @@ package arvados import ( + "bytes" "crypto/hmac" "crypto/sha1" "errors" @@ -33,9 +34,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("@")) @@ -57,9 +58,8 @@ func SignManifest(manifest string, apiToken string, expiry time.Time, ttl time.D return regexp.MustCompile(`\S+`).ReplaceAllStringFunc(manifest, func(tok string) string { if mBlkRe.MatchString(tok) { return SignLocator(mPermHintRe.ReplaceAllString(tok, ""), apiToken, expiry, ttl, permissionSecret) - } else { - return tok } + return tok }) } @@ -74,7 +74,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 + @@ -101,7 +104,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 { @@ -124,3 +127,21 @@ func parseHexTimestamp(timestampHex string) (ts time.Time, err error) { } return ts, err } + +var errNoSignature = errors.New("locator has no signature") + +func signatureExpiryTime(signedLocator string) (time.Time, error) { + matches := SignedLocatorRe.FindStringSubmatch(signedLocator) + if matches == nil { + return time.Time{}, errNoSignature + } + expiryHex := matches[7] + return parseHexTimestamp(expiryHex) +} + +func stripAllHints(locator string) string { + if i := strings.IndexRune(locator, '+'); i > 0 { + return locator[:i] + } + return locator +}