-
Notifications
You must be signed in to change notification settings - Fork 6
/
iid.go
101 lines (85 loc) · 2.84 KB
/
iid.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
package aws_iid
import (
"context"
"crypto/sha256"
"encoding/hex"
"encoding/json"
"fmt"
"github.com/allegro/bigcache/v3"
"github.com/coinbase/baseca/internal/client/ec2"
"github.com/coinbase/baseca/internal/types"
)
const (
// https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/verify-signature.html (Other AWS Regions)
aws_certificate_path = "config/aws/ec2.amazonaws.com.crt"
)
func AWSIidNodeAttestation(node types.NodeIIDAttestation, cache *bigcache.BigCache) error {
err := validateMetadataSignature(node.EC2InstanceMetadata)
if err != nil {
return err
}
instance_identity_document := types.InstanceIdentityDocument{}
err = json.Unmarshal(node.EC2InstanceMetadata.InstanceIdentityDocument, &instance_identity_document)
if err != nil {
return fmt.Errorf("error unmarshal aws_iid metadata")
}
err = searchIidCache(node, cache)
if err != nil {
return err
}
return nil
}
// Query Instance Metadata in Cache
func searchIidCache(node types.NodeIIDAttestation, cache *bigcache.BigCache) error {
hash := sha256.Sum256(node.EC2InstanceMetadata.InstanceIdentityDocument)
hash_key := hex.EncodeToString(hash[:])
if value, err := cache.Get(hash_key); err != nil {
// Cache Missed
err := setIidCache(node, cache)
if err != nil {
return fmt.Errorf("error setting iid cache, %s", err)
}
} else {
// SHA-256 Instance Identity Document [Key]
// []byte Instance Identity Document [Value]
document := types.InstanceIdentityDocument{}
err := json.Unmarshal(value, &document)
if err != nil {
return fmt.Errorf("error unmarshal hashed iid in cached, %s", err)
}
}
return nil
}
func setIidCache(node types.NodeIIDAttestation, cache *bigcache.BigCache) error {
hash := sha256.Sum256(node.EC2InstanceMetadata.InstanceIdentityDocument)
hash_key := hex.EncodeToString(hash[:])
client, err := ec2.NewEC2Client(node.Attestation.Region, node.Attestation.AssumeRole)
if err != nil {
return fmt.Errorf("error building ec2 client, %s", err)
}
// Instance ID from EC2 IID
iid := types.InstanceIdentityDocument{}
err = json.Unmarshal(node.EC2InstanceMetadata.InstanceIdentityDocument, &iid)
if err != nil {
return fmt.Errorf("error unmarshal aws_iid metadata")
}
instance, err := ec2.QueryInstanceMetadata(context.Background(), client, []string{iid.InstanceId})
if err != nil {
return err
}
// IAM Role Arn Attestation
if len(node.Attestation.RoleArn) > 0 {
if *instance.IamInstanceProfile.Arn != node.Attestation.RoleArn {
return fmt.Errorf("aws_iid role arn attestation error [client_id %s] %s", node.Uuid, string(node.EC2InstanceMetadata.InstanceIdentityDocument))
}
}
data, err := json.Marshal(iid)
if err != nil {
return fmt.Errorf("error marshalling cached_service_account, %s", err)
}
err = cache.Set(hash_key, data)
if err != nil {
return fmt.Errorf("error setting hashed aws_iid in cache, %s", err)
}
return nil
}