@@ -5,16 +5,19 @@ package ca
55
66import (
77 "bytes"
8+ "context"
89 "crypto/x509"
910 "encoding/pem"
11+ "errors"
1012 "fmt"
1113 "sync/atomic"
1214 "time"
1315
14- "github.com/aws/aws-sdk-go/aws"
15- "github.com/aws/aws-sdk-go/aws/awserr"
16- "github.com/aws/aws-sdk-go/aws/session"
17- "github.com/aws/aws-sdk-go/service/acmpca"
16+ "github.com/aws/aws-sdk-go-v2/aws"
17+ awsconfig "github.com/aws/aws-sdk-go-v2/config"
18+ "github.com/aws/aws-sdk-go-v2/service/acmpca"
19+ "github.com/aws/aws-sdk-go-v2/service/acmpca/types"
20+ "github.com/aws/smithy-go"
1821
1922 "github.com/go-viper/mapstructure/v2"
2023 "github.com/hashicorp/go-hclog"
@@ -65,8 +68,8 @@ type AWSProvider struct {
6568 stopCh chan struct {}
6669
6770 config * structs.AWSCAProviderConfig
68- session * session. Session
69- client * acmpca.ACMPCA
71+ awsConfig * aws. Config
72+ client * acmpca.Client
7073 isPrimary bool
7174 datacenter string
7275 clusterID string
@@ -99,19 +102,19 @@ func (a *AWSProvider) Configure(cfg ProviderConfig) error {
99102 // another place or sending them via API call and persisting them in state
100103 // store in a new place on disk. One of the existing standard solutions seems
101104 // better in all cases.
102- awsSession , err := session . NewSessionWithOptions (session. Options {
103- SharedConfigState : session . SharedConfigEnable ,
104- } )
105+ awsConfig , err := awsconfig . LoadDefaultConfig ( context . Background (),
106+ awsconfig . WithSharedConfigProfile ( "" ) ,
107+ )
105108 if err != nil {
106109 return err
107110 }
108111
109112 a .config = config
110- a .session = awsSession
113+ a .awsConfig = & awsConfig
111114 a .isPrimary = cfg .IsPrimary
112115 a .clusterID = cfg .ClusterID
113116 a .datacenter = cfg .Datacenter
114- a .client = acmpca .New ( awsSession )
117+ a .client = acmpca .NewFromConfig ( awsConfig )
115118 a .stopCh = make (chan struct {})
116119
117120 // Load the ARN from config or previous state.
@@ -171,14 +174,14 @@ func (a *AWSProvider) ensureCA() error {
171174 input := & acmpca.DescribeCertificateAuthorityInput {
172175 CertificateAuthorityArn : aws .String (a .arn ),
173176 }
174- output , err := a .client .DescribeCertificateAuthority (input )
177+ output , err := a .client .DescribeCertificateAuthority (context . Background (), input )
175178 if err != nil {
176179 return err
177180 }
178181 // Allow it to be active or pending a certificate (leadership might have
179182 // changed during a secondary initialization for example).
180- if * output .CertificateAuthority .Status != acmpca .CertificateAuthorityStatusActive &&
181- * output .CertificateAuthority .Status != acmpca .CertificateAuthorityStatusPendingCertificate {
183+ if output .CertificateAuthority .Status != types .CertificateAuthorityStatusActive &&
184+ output .CertificateAuthority .Status != types .CertificateAuthorityStatusPendingCertificate {
182185 verb := "configured"
183186 if a .caCreated {
184187 verb = "created"
@@ -189,7 +192,7 @@ func (a *AWSProvider) ensureCA() error {
189192 // but this is simpler and less surprising default behavior if user
190193 // disabled a CA due to a security concern and we just work around it.
191194 return fmt .Errorf ("the %s PCA is not active: status is %s" , verb ,
192- * output .CertificateAuthority .Status )
195+ output .CertificateAuthority .Status )
193196 }
194197
195198 // Load the certs
@@ -233,7 +236,7 @@ func (a *AWSProvider) ensureCA() error {
233236 }
234237
235238 a .logger .Debug ("uploading certificate for ARN" , "arn" , a .arn )
236- _ , err = a .client .ImportCertificateAuthorityCertificate (& input )
239+ _ , err = a .client .ImportCertificateAuthorityCertificate (context . Background (), & input )
237240 if err != nil {
238241 return err
239242 }
@@ -247,9 +250,9 @@ func keyTypeToAlgos(keyType string, keyBits int) (string, string, error) {
247250 case "rsa" :
248251 switch keyBits {
249252 case 2048 :
250- return acmpca .KeyAlgorithmRsa2048 , acmpca .SigningAlgorithmSha256withrsa , nil
253+ return string ( types .KeyAlgorithmRsa2048 ), string ( types .SigningAlgorithmSha256withrsa ) , nil
251254 case 4096 :
252- return acmpca .KeyAlgorithmRsa4096 , acmpca .SigningAlgorithmSha256withrsa , nil
255+ return string ( types .KeyAlgorithmRsa4096 ), string ( types .SigningAlgorithmSha256withrsa ) , nil
253256 default :
254257 return "" , "" , fmt .Errorf ("AWS PCA only supports RSA key lengths 2048" +
255258 " and 4096, PrivateKeyBits of %d configured" , keyBits )
@@ -258,7 +261,7 @@ func keyTypeToAlgos(keyType string, keyBits int) (string, string, error) {
258261 if keyBits != 256 {
259262 return "" , "" , fmt .Errorf ("AWS PCA only supports P256 EC curve, keyBits of %d configured" , keyBits )
260263 }
261- return acmpca .KeyAlgorithmEcPrime256v1 , acmpca .SigningAlgorithmSha256withecdsa , nil
264+ return string ( types .KeyAlgorithmEcPrime256v1 ), string ( types .SigningAlgorithmSha256withecdsa ) , nil
262265 default :
263266 return "" , "" , fmt .Errorf ("AWS PCA only supports P256 EC curve, or RSA" +
264267 " 2048/4096. %s, %d configured" , keyType , keyBits )
@@ -268,7 +271,7 @@ func keyTypeToAlgos(keyType string, keyBits int) (string, string, error) {
268271func (a * AWSProvider ) createPCA () error {
269272 pcaType := "ROOT" // For some reason there is no constant for this in the SDK
270273 if ! a .isPrimary {
271- pcaType = acmpca .CertificateAuthorityTypeSubordinate
274+ pcaType = string ( types .CertificateAuthorityTypeSubordinate )
272275 }
273276
274277 keyAlg , signAlg , err := keyTypeToAlgos (a .config .PrivateKeyType , a .config .PrivateKeyBits )
@@ -283,32 +286,32 @@ func (a *AWSProvider) createPCA() error {
283286 commonName := connect .CACN ("aws" , uid , a .clusterID , a .isPrimary )
284287
285288 createInput := acmpca.CreateCertificateAuthorityInput {
286- CertificateAuthorityType : aws . String (pcaType ),
287- CertificateAuthorityConfiguration : & acmpca .CertificateAuthorityConfiguration {
288- Subject : & acmpca .ASN1Subject {
289+ CertificateAuthorityType : types . CertificateAuthorityType (pcaType ),
290+ CertificateAuthorityConfiguration : & types .CertificateAuthorityConfiguration {
291+ Subject : & types .ASN1Subject {
289292 CommonName : aws .String (commonName ),
290293 },
291- KeyAlgorithm : aws . String (keyAlg ),
292- SigningAlgorithm : aws . String (signAlg ),
294+ KeyAlgorithm : types . KeyAlgorithm (keyAlg ),
295+ SigningAlgorithm : types . SigningAlgorithm (signAlg ),
293296 },
294- RevocationConfiguration : & acmpca .RevocationConfiguration {
297+ RevocationConfiguration : & types .RevocationConfiguration {
295298 // TODO support CRL in future when we manage revocation in Connect more
296299 // generally.
297- CrlConfiguration : & acmpca .CrlConfiguration {
300+ CrlConfiguration : & types .CrlConfiguration {
298301 Enabled : aws .Bool (false ),
299302 },
300303 },
301304 // uid is unique to each PCA we create so use it as an idempotency string. We
302305 // don't actually retry on failure yet but might as well!
303306 IdempotencyToken : aws .String (uid ),
304- Tags : []* acmpca .Tag {
307+ Tags : []types .Tag {
305308 {Key : aws .String ("consul_cluster_id" ), Value : aws .String (a .clusterID )},
306309 {Key : aws .String ("consul_datacenter" ), Value : aws .String (a .datacenter )},
307310 },
308311 }
309312
310313 a .logger .Debug ("creating new PCA" , "common_name" , commonName )
311- createOutput , err := a .client .CreateCertificateAuthority (& createInput )
314+ createOutput , err := a .client .CreateCertificateAuthority (context . Background (), & createInput )
312315 if err != nil {
313316 a .logger .Error ("failed to create new PCA" , "common_name" , commonName , "error" , err )
314317 return err
@@ -320,13 +323,14 @@ func (a *AWSProvider) createPCA() error {
320323 CertificateAuthorityArn : aws .String (newARN ),
321324 }
322325 _ , err = a .pollLoop ("Private CA" , AWSCreateTimeout , func () (bool , string , error ) {
323- describeOutput , err := a .client .DescribeCertificateAuthority (& describeInput )
326+ describeOutput , err := a .client .DescribeCertificateAuthority (context . Background (), & describeInput )
324327 if err != nil {
325- if err .(awserr.Error ).Code () != acmpca .ErrCodeRequestInProgressException {
328+ var apiErr smithy.APIError
329+ if errors .As (err , & apiErr ) && apiErr .ErrorCode () != "RequestInProgressException" {
326330 return true , "" , fmt .Errorf ("error waiting for PCA to be created: %s" , err )
327331 }
328332 }
329- if * describeOutput .CertificateAuthority .Status == acmpca .CertificateAuthorityStatusPendingCertificate {
333+ if describeOutput .CertificateAuthority .Status == types .CertificateAuthorityStatusPendingCertificate {
330334 a .logger .Debug ("new PCA is ready to accept a certificate" , "pca" , newARN )
331335 a .arn = newARN
332336 // We don't need to reload this ARN since we just created it and know what
@@ -345,7 +349,7 @@ func (a *AWSProvider) getCACSR() (string, error) {
345349 CertificateAuthorityArn : aws .String (a .arn ),
346350 }
347351 a .logger .Debug ("retrieving CSR for PCA" , "pca" , a .arn )
348- output , err := a .client .GetCertificateAuthorityCsr (input )
352+ output , err := a .client .GetCertificateAuthorityCsr (context . Background (), input )
349353 if err != nil {
350354 return "" , err
351355 }
@@ -362,7 +366,7 @@ func (a *AWSProvider) loadCACerts() error {
362366 input := & acmpca.GetCertificateAuthorityCertificateInput {
363367 CertificateAuthorityArn : aws .String (a .arn ),
364368 }
365- output , err := a .client .GetCertificateAuthorityCertificate (input )
369+ output , err := a .client .GetCertificateAuthorityCertificate (context . Background (), input )
366370 if err != nil {
367371 return err
368372 }
@@ -458,24 +462,23 @@ func (a *AWSProvider) signCSR(csrPEM string, templateARN string, ttl time.Durati
458462 issueInput := acmpca.IssueCertificateInput {
459463 CertificateAuthorityArn : aws .String (a .arn ),
460464 Csr : []byte (csrPEM ),
461- SigningAlgorithm : aws . String (signAlg ),
465+ SigningAlgorithm : types . SigningAlgorithm (signAlg ),
462466 TemplateArn : aws .String (templateARN ),
463- Validity : & acmpca .Validity {
467+ Validity : & types .Validity {
464468 Value : aws .Int64 (int64 (ttl / day )),
465- Type : aws . String ( acmpca . ValidityPeriodTypeDays ) ,
469+ Type : types . ValidityPeriodTypeDays ,
466470 },
467471 }
468472
469- issueOutput , err := a .client .IssueCertificate (& issueInput )
473+ issueOutput , err := a .client .IssueCertificate (context . Background (), & issueInput )
470474 // ErrCodeLimitExceededException is used for both hard and soft limits in AWS
471475 // SDK :(. In this specific context though (issuing a certificate) there is no
472476 // hard limit on number of certs so a limit exceeded here is a rate limit.
473- if aerr , ok := err .(awserr.Error ); ok && err != nil {
474- if aerr .Code () == acmpca .ErrCodeLimitExceededException {
477+ if err != nil {
478+ var apiErr smithy.APIError
479+ if errors .As (err , & apiErr ) && apiErr .ErrorCode () == "LimitExceededException" {
475480 return "" , ErrRateLimited
476481 }
477- }
478- if err != nil {
479482 return "" , fmt .Errorf ("error issuing certificate from PCA: %s" , err )
480483 }
481484
@@ -487,9 +490,10 @@ func (a *AWSProvider) signCSR(csrPEM string, templateARN string, ttl time.Durati
487490 return a .pollLoop (fmt .Sprintf ("certificate %s" , * issueOutput .CertificateArn ),
488491 AWSSignTimeout ,
489492 func () (bool , string , error ) {
490- certOutput , err := a .client .GetCertificate (& certInput )
493+ certOutput , err := a .client .GetCertificate (context . Background (), & certInput )
491494 if err != nil {
492- if err .(awserr.Error ).Code () != acmpca .ErrCodeRequestInProgressException {
495+ var apiErr smithy.APIError
496+ if errors .As (err , & apiErr ) && apiErr .ErrorCode () != "RequestInProgressException" {
493497 return true , "" , fmt .Errorf ("error retrieving certificate from PCA: %s" , err )
494498 }
495499 }
@@ -533,7 +537,7 @@ func (a *AWSProvider) SetIntermediate(intermediatePEM string, rootPEM string, _
533537 CertificateChain : []byte (rootPEM ),
534538 }
535539 a .logger .Debug ("uploading certificate for PCA" , "pca" , a .arn )
536- _ , err = a .client .ImportCertificateAuthorityCertificate (& input )
540+ _ , err = a .client .ImportCertificateAuthorityCertificate (context . Background (), & input )
537541 if err != nil {
538542 return err
539543 }
@@ -611,10 +615,10 @@ func (a *AWSProvider) disablePCA() error {
611615 }
612616 input := acmpca.UpdateCertificateAuthorityInput {
613617 CertificateAuthorityArn : aws .String (a .arn ),
614- Status : aws . String ( acmpca . CertificateAuthorityStatusDisabled ) ,
618+ Status : types . CertificateAuthorityStatusDisabled ,
615619 }
616620 a .logger .Info ("disabling PCA" , "pca" , a .arn )
617- _ , err := a .client .UpdateCertificateAuthority (& input )
621+ _ , err := a .client .UpdateCertificateAuthority (context . Background (), & input )
618622 return err
619623}
620624
@@ -626,10 +630,10 @@ func (a *AWSProvider) deletePCA() error {
626630 CertificateAuthorityArn : aws .String (a .arn ),
627631 // We only ever use this to clean up after tests so delete as quickly as
628632 // possible (7 days).
629- PermanentDeletionTimeInDays : aws .Int64 (7 ),
633+ PermanentDeletionTimeInDays : aws .Int32 (7 ),
630634 }
631635 a .logger .Info ("deleting PCA" , "pca" , a .arn )
632- _ , err := a .client .DeleteCertificateAuthority (& input )
636+ _ , err := a .client .DeleteCertificateAuthority (context . Background (), & input )
633637 return err
634638}
635639
0 commit comments