github.com/machinefi/w3bstream@v1.6.5-rc9.0.20240426031326-b8c7c4876e72/pkg/depends/conf/filesystem/s3/client_cos.go (about)

     1  package confs3
     2  
     3  import (
     4  	"crypto/hmac"
     5  	"crypto/md5"
     6  	"crypto/sha1"
     7  	"fmt"
     8  	"hash"
     9  	"net/url"
    10  	"strings"
    11  	"time"
    12  )
    13  
    14  func COSPresignedValues(db *ObjectDB, key string, exp time.Duration) url.Values {
    15  	authTime := NewAuthTime(exp)
    16  	signTime := authTime.signString()
    17  	keyTime := authTime.keyString()
    18  	signKey := calSignKey(db.SecretAccessKey.String(), keyTime)
    19  	formatString := genFormatString("get", "/"+key, "", "")
    20  	stringToSign := calStringToSign(sha1SignAlgorithm, keyTime, formatString)
    21  	signature := calSignature(signKey, stringToSign)
    22  	signedHeaderList := make([]string, 0)
    23  	signedParameterList := make([]string, 0)
    24  
    25  	values := url.Values{}
    26  
    27  	values.Set("q-sign-algorithm", sha1SignAlgorithm)
    28  	values.Set("q-ak", db.AccessKeyID)
    29  	values.Set("q-sign-time", signTime)
    30  	values.Set("q-objectKey-time", keyTime)
    31  	values.Set("q-header-list", strings.Join(signedHeaderList, ";"))
    32  	values.Set("q-url-param-list", strings.Join(signedParameterList, ";"))
    33  	values.Set("q-signature", signature)
    34  
    35  	return values
    36  }
    37  
    38  func NewAuthTime(du time.Duration) *AuthTime {
    39  	if du == time.Duration(0) {
    40  		du = defaultAuthExpire
    41  	}
    42  	signStartTime := time.Now()
    43  	keyStartTime := signStartTime
    44  	signEndTime := signStartTime.Add(du)
    45  	keyEndTime := signEndTime
    46  	return &AuthTime{
    47  		SignStartTime: signStartTime,
    48  		SignEndTime:   signEndTime,
    49  		KeyStartTime:  keyStartTime,
    50  		KeyEndTime:    keyEndTime,
    51  	}
    52  }
    53  
    54  const (
    55  	sha1SignAlgorithm = "sha1"
    56  	md5SignAlgorithm  = "md5"
    57  )
    58  const defaultAuthExpire = time.Hour
    59  
    60  // AuthTime is a struct storing the q-signSearch-time and q-key-time which are needed to generate signature
    61  type AuthTime struct {
    62  	SignStartTime time.Time
    63  	SignEndTime   time.Time
    64  	KeyStartTime  time.Time
    65  	KeyEndTime    time.Time
    66  }
    67  
    68  func (a *AuthTime) signString() string {
    69  	return fmt.Sprintf("%d;%d", a.SignStartTime.Unix(), a.SignEndTime.Unix())
    70  }
    71  
    72  func (a *AuthTime) keyString() string {
    73  	return fmt.Sprintf("%d;%d", a.KeyStartTime.Unix(), a.KeyEndTime.Unix())
    74  }
    75  
    76  func calSignKey(secretKey, keyTime string) string {
    77  	digest := HMAC(secretKey, keyTime, sha1SignAlgorithm)
    78  	return fmt.Sprintf("%x", digest)
    79  }
    80  
    81  func calStringToSign(signAlgorithm, signTime, formatString string) string {
    82  	h := sha1.New()
    83  	h.Write([]byte(formatString))
    84  	return fmt.Sprintf("%s\n%s\n%x\n", signAlgorithm, signTime, h.Sum(nil))
    85  }
    86  
    87  func calSignature(signKey, stringToSign string) string {
    88  	digest := HMAC(signKey, stringToSign, sha1SignAlgorithm)
    89  	return fmt.Sprintf("%x", digest)
    90  }
    91  
    92  func genFormatString(method string, url string, formatParameters, formatHeaders string) string {
    93  	return fmt.Sprintf("%s\n%s\n%s\n%s\n", method, url,
    94  		formatParameters, formatHeaders,
    95  	)
    96  }
    97  
    98  func HMAC(key, msg, signMethod string) []byte {
    99  	var hashFn func() hash.Hash
   100  	switch signMethod {
   101  	case sha1SignAlgorithm:
   102  		hashFn = sha1.New
   103  	case md5SignAlgorithm:
   104  		hashFn = md5.New
   105  	default:
   106  		hashFn = sha1.New
   107  	}
   108  	h := hmac.New(hashFn, []byte(key))
   109  	h.Write([]byte(msg))
   110  	return h.Sum(nil)
   111  }