in aws_signing_helper/credentials.go [58:170]
func GenerateCredentials(opts *CredentialsOpts, signer Signer, signatureAlgorithm string) (CredentialProcessOutput, error) {
// Assign values to region and endpoint if they haven't already been assigned
trustAnchorArn, err := arn.Parse(opts.TrustAnchorArnStr)
if err != nil {
return CredentialProcessOutput{}, err
}
profileArn, err := arn.Parse(opts.ProfileArnStr)
if err != nil {
return CredentialProcessOutput{}, err
}
if trustAnchorArn.Region != profileArn.Region {
return CredentialProcessOutput{}, errors.New("trust anchor and profile regions don't match")
}
if opts.Region == "" {
opts.Region = trustAnchorArn.Region
}
var logMode aws.ClientLogMode = 0
if Debug {
logMode = aws.LogSigning | aws.LogRetries | aws.LogRequestWithBody | aws.LogResponseWithBody | aws.LogRequestEventMessage | aws.LogResponseEventMessage
}
// Custom HTTP client with proxy and TLS settings
var tr *http.Transport
if opts.WithProxy {
tr = &http.Transport{
TLSClientConfig: &tls.Config{MinVersion: tls.VersionTLS12, InsecureSkipVerify: opts.NoVerifySSL},
Proxy: http.ProxyFromEnvironment,
}
} else {
tr = &http.Transport{
TLSClientConfig: &tls.Config{MinVersion: tls.VersionTLS12, InsecureSkipVerify: opts.NoVerifySSL},
}
}
httpClient := &http.Client{Transport: tr}
ctx := context.TODO()
cfg, err := config.LoadDefaultConfig(ctx, config.WithRegion(opts.Region), config.WithHTTPClient(httpClient), config.WithClientLogMode(logMode))
if err != nil {
return CredentialProcessOutput{}, err
}
// Override endpoint if specified
if opts.Endpoint != "" {
cfg.BaseEndpoint = aws.String(opts.Endpoint)
}
// Set a custom user agent
userAgentStr := fmt.Sprintf("CredHelper/%s (%s; %s; %s)", opts.Version, runtime.Version(), runtime.GOOS, runtime.GOARCH)
cfg.APIOptions = append(cfg.APIOptions, func(stack *middleware.Stack) error {
stack.Build.Remove("UserAgent")
return stack.Build.Add(createCredHelperUserAgentMiddleware(userAgentStr), middleware.After)
})
// Add custom request signer, implementing SigV4-X509
certificate, err := signer.Certificate()
if err != nil {
return CredentialProcessOutput{}, errors.New("unable to find certificate")
}
certificateChain, err := signer.CertificateChain()
if err != nil {
// If the chain couldn't be found, don't include it in the request
if Debug {
log.Println(err)
}
}
cfg.APIOptions = append(cfg.APIOptions, func(stack *middleware.Stack) error {
// Remove middleware related to SigV4 signing
stack.Finalize.Remove("Signing")
stack.Finalize.Remove("setLegacyContextSigningOptions")
stack.Finalize.Remove("GetIdentity")
// Add middleware for SigV4-X509 signing
stack.Finalize.Add(middleware.FinalizeMiddlewareFunc("Signing", CreateRequestSignFinalizeFunction(signer, opts.Region, signatureAlgorithm, certificate, certificateChain)), middleware.After)
return nil
})
// Create the Roles Anywhere client using the above-constructed Config
rolesAnywhereClient := rolesanywhere.NewFromConfig(cfg)
certificateStr := base64.StdEncoding.EncodeToString(certificate.Raw)
durationSeconds := int32(opts.SessionDuration)
createSessionRequest := rolesanywhere.CreateSessionInput{
Cert: &certificateStr,
ProfileArn: &opts.ProfileArnStr,
TrustAnchorArn: &opts.TrustAnchorArnStr,
DurationSeconds: &(durationSeconds),
InstanceProperties: nil,
RoleArn: &opts.RoleArn,
SessionName: nil,
}
if opts.RoleSessionName != "" {
createSessionRequest.RoleSessionName = &opts.RoleSessionName
}
output, err := rolesAnywhereClient.CreateSession(ctx, &createSessionRequest)
if err != nil {
return CredentialProcessOutput{}, err
}
if len(output.CredentialSet) == 0 {
msg := "unable to obtain temporary security credentials from CreateSession"
return CredentialProcessOutput{}, errors.New(msg)
}
credentials := output.CredentialSet[0].Credentials
credentialProcessOutput := CredentialProcessOutput{
Version: 1,
AccessKeyId: *credentials.AccessKeyId,
SecretAccessKey: *credentials.SecretAccessKey,
SessionToken: *credentials.SessionToken,
Expiration: *credentials.Expiration,
}
return credentialProcessOutput, nil
}