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