github.com/aliyun/credentials-go@v1.4.7/credentials/rsa_key_pair_credentials_provider.go (about)

     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  }