rsa_key_pair_credentials_provider.go raw

   1  package credentials
   2  
   3  import (
   4  	"encoding/json"
   5  	"errors"
   6  	"fmt"
   7  	"strconv"
   8  	"time"
   9  
  10  	"github.com/alibabacloud-go/tea/tea"
  11  	"github.com/aliyun/credentials-go/credentials/internal/utils"
  12  	"github.com/aliyun/credentials-go/credentials/request"
  13  )
  14  
  15  // Deprecated: no more recommend to use it
  16  // RsaKeyPairCredentialsProvider is a kind of credentials provider
  17  type RsaKeyPairCredentialsProvider struct {
  18  	*credentialUpdater
  19  	PrivateKey        string
  20  	PublicKeyId       string
  21  	SessionExpiration int
  22  	sessionCredential *sessionCredential
  23  	runtime           *utils.Runtime
  24  }
  25  
  26  type rsaKeyPairResponse struct {
  27  	SessionAccessKey *sessionAccessKey `json:"SessionAccessKey" xml:"SessionAccessKey"`
  28  }
  29  
  30  type sessionAccessKey struct {
  31  	SessionAccessKeyId     string `json:"SessionAccessKeyId" xml:"SessionAccessKeyId"`
  32  	SessionAccessKeySecret string `json:"SessionAccessKeySecret" xml:"SessionAccessKeySecret"`
  33  	Expiration             string `json:"Expiration" xml:"Expiration"`
  34  }
  35  
  36  func newRsaKeyPairCredential(privateKey, publicKeyId string, sessionExpiration int, runtime *utils.Runtime) *RsaKeyPairCredentialsProvider {
  37  	return &RsaKeyPairCredentialsProvider{
  38  		PrivateKey:        privateKey,
  39  		PublicKeyId:       publicKeyId,
  40  		SessionExpiration: sessionExpiration,
  41  		credentialUpdater: new(credentialUpdater),
  42  		runtime:           runtime,
  43  	}
  44  }
  45  
  46  func (e *RsaKeyPairCredentialsProvider) GetCredential() (*CredentialModel, error) {
  47  	if e.sessionCredential == nil || e.needUpdateCredential() {
  48  		err := e.updateCredential()
  49  		if err != nil {
  50  			return nil, err
  51  		}
  52  	}
  53  	credential := &CredentialModel{
  54  		AccessKeyId:     tea.String(e.sessionCredential.AccessKeyId),
  55  		AccessKeySecret: tea.String(e.sessionCredential.AccessKeySecret),
  56  		SecurityToken:   tea.String(e.sessionCredential.SecurityToken),
  57  		Type:            tea.String("rsa_key_pair"),
  58  	}
  59  	return credential, nil
  60  }
  61  
  62  // GetAccessKeyId reutrns RsaKeyPairCredential's AccessKeyId
  63  // if AccessKeyId is not exist or out of date, the function will update it.
  64  func (r *RsaKeyPairCredentialsProvider) GetAccessKeyId() (accessKeyId *string, err error) {
  65  	c, err := r.GetCredential()
  66  	if err != nil {
  67  		return
  68  	}
  69  	accessKeyId = c.AccessKeyId
  70  	return
  71  }
  72  
  73  // GetAccessSecret reutrns  RsaKeyPairCredential's AccessKeySecret
  74  // if AccessKeySecret is not exist or out of date, the function will update it.
  75  func (r *RsaKeyPairCredentialsProvider) GetAccessKeySecret() (accessKeySecret *string, err error) {
  76  	c, err := r.GetCredential()
  77  	if err != nil {
  78  		return
  79  	}
  80  	accessKeySecret = c.AccessKeySecret
  81  	return
  82  }
  83  
  84  // GetSecurityToken is useless  RsaKeyPairCredential
  85  func (r *RsaKeyPairCredentialsProvider) GetSecurityToken() (*string, error) {
  86  	return tea.String(""), nil
  87  }
  88  
  89  // GetBearerToken is useless for  RsaKeyPairCredential
  90  func (r *RsaKeyPairCredentialsProvider) GetBearerToken() *string {
  91  	return tea.String("")
  92  }
  93  
  94  // GetType reutrns  RsaKeyPairCredential's type
  95  func (r *RsaKeyPairCredentialsProvider) GetType() *string {
  96  	return tea.String("rsa_key_pair")
  97  }
  98  
  99  func (r *RsaKeyPairCredentialsProvider) updateCredential() (err error) {
 100  	if r.runtime == nil {
 101  		r.runtime = new(utils.Runtime)
 102  	}
 103  	request := request.NewCommonRequest()
 104  	request.Domain = "sts.aliyuncs.com"
 105  	if r.runtime.Host != "" {
 106  		request.Domain = r.runtime.Host
 107  	} else if r.runtime.STSEndpoint != "" {
 108  		request.Domain = r.runtime.STSEndpoint
 109  	}
 110  	request.Scheme = "HTTPS"
 111  	request.Method = "GET"
 112  	request.QueryParams["AccessKeyId"] = r.PublicKeyId
 113  	request.QueryParams["Action"] = "GenerateSessionAccessKey"
 114  	request.QueryParams["Format"] = "JSON"
 115  	if r.SessionExpiration > 0 {
 116  		if r.SessionExpiration >= 900 && r.SessionExpiration <= 3600 {
 117  			request.QueryParams["DurationSeconds"] = strconv.Itoa(r.SessionExpiration)
 118  		} else {
 119  			err = errors.New("[InvalidParam]:Key Pair session duration should be in the range of 15min - 1Hr")
 120  			return
 121  		}
 122  	} else {
 123  		request.QueryParams["DurationSeconds"] = strconv.Itoa(defaultDurationSeconds)
 124  	}
 125  	request.QueryParams["SignatureMethod"] = "SHA256withRSA"
 126  	request.QueryParams["SignatureType"] = "PRIVATEKEY"
 127  	request.QueryParams["SignatureVersion"] = "1.0"
 128  	request.QueryParams["Version"] = "2015-04-01"
 129  	request.QueryParams["Timestamp"] = utils.GetTimeInFormatISO8601()
 130  	request.QueryParams["SignatureNonce"] = utils.GetUUID()
 131  	signature := utils.Sha256WithRsa(request.BuildStringToSign(), r.PrivateKey)
 132  	request.QueryParams["Signature"] = signature
 133  	request.Headers["Host"] = request.Domain
 134  	request.Headers["Accept-Encoding"] = "identity"
 135  	request.URL = request.BuildURL()
 136  	content, err := doAction(request, r.runtime)
 137  	if err != nil {
 138  		return fmt.Errorf("refresh KeyPair err: %s", err.Error())
 139  	}
 140  	var resp *rsaKeyPairResponse
 141  	err = json.Unmarshal(content, &resp)
 142  	if err != nil {
 143  		return fmt.Errorf("refresh KeyPair err: Json Unmarshal fail: %s", err.Error())
 144  	}
 145  	if resp == nil || resp.SessionAccessKey == nil {
 146  		return fmt.Errorf("refresh KeyPair err: SessionAccessKey is empty")
 147  	}
 148  	sessionAccessKey := resp.SessionAccessKey
 149  	if sessionAccessKey.SessionAccessKeyId == "" || sessionAccessKey.SessionAccessKeySecret == "" || sessionAccessKey.Expiration == "" {
 150  		return fmt.Errorf("refresh KeyPair err: SessionAccessKeyId: %v, SessionAccessKeySecret: %v, Expiration: %v", sessionAccessKey.SessionAccessKeyId, sessionAccessKey.SessionAccessKeySecret, sessionAccessKey.Expiration)
 151  	}
 152  
 153  	expirationTime, err := time.Parse("2006-01-02T15:04:05Z", sessionAccessKey.Expiration)
 154  	r.lastUpdateTimestamp = time.Now().Unix()
 155  	r.credentialExpiration = int(expirationTime.Unix() - time.Now().Unix())
 156  	r.sessionCredential = &sessionCredential{
 157  		AccessKeyId:     sessionAccessKey.SessionAccessKeyId,
 158  		AccessKeySecret: sessionAccessKey.SessionAccessKeySecret,
 159  	}
 160  
 161  	return
 162  }
 163