@@ -4,9 +4,11 @@ import (
44 "crypto/ecdsa"
55 "crypto/tls"
66 "crypto/x509"
7+ "encoding/base32"
78 "encoding/pem"
89 "fmt"
910 "os"
11+ "sort"
1012 "strings"
1113
1214 log "github.com/sirupsen/logrus"
@@ -27,37 +29,86 @@ func init() {
2729 rootCmd .AddCommand (certificateAuditCmd )
2830}
2931
30- func attestationFromCertificate (cert * x509.Certificate ) (* attestation.Document , string , error ) {
32+ func decodeHashDomains (domains []string ) (string , error ) {
33+ sort .Slice (domains , func (i , j int ) bool {
34+ return domains [i ][:2 ] < domains [j ][:2 ]
35+ })
36+
37+ var encodedData string
38+ for _ , domain := range domains {
39+ domain = strings .Split (domain , "." )[0 ]
40+ encodedData += domain [2 :]
41+ }
42+
43+ encoder := base32 .StdEncoding .WithPadding (base32 .NoPadding )
44+ hashBytes , err := encoder .DecodeString (strings .ToUpper (encodedData ))
45+ if err != nil {
46+ return "" , fmt .Errorf ("failed to decode base32: %v" , err )
47+ }
48+ return string (hashBytes ), nil
49+ }
50+
51+ func attestationFromCertificate (cert * x509.Certificate , enclaveHost string ) (* attestation.Document , string , error ) {
3152 pubKey , ok := cert .PublicKey .(* ecdsa.PublicKey )
3253 if ! ok {
3354 return nil , "" , fmt .Errorf ("public key is not an ECDSA key" )
3455 }
3556 keyFP := tlsutil .KeyFP (pubKey )
3657
3758 var attDomains []string
59+ var hashAttDomains []string
3860 for _ , name := range cert .DNSNames {
3961 if strings .HasSuffix (name , ".att.tinfoil.sh" ) {
4062 attDomains = append (attDomains , name )
4163 log .Debugf ("Attestation domain: %s" , name )
64+ } else if strings .HasSuffix (name , ".hatt.tinfoil.sh" ) {
65+ hashAttDomains = append (hashAttDomains , name )
66+ log .Debugf ("Hash attestation domain: %s" , name )
4267 }
4368 }
4469
45- if len (attDomains ) == 0 {
46- return nil , "" , fmt .Errorf ("no attestation domains found in certificate" )
70+ if len (attDomains ) > 0 {
71+ att , err := dcode .Decode (attDomains )
72+ if err != nil {
73+ return nil , "" , fmt .Errorf ("failed to decode attestation: %v" , err )
74+ }
75+ return att , keyFP , nil
4776 }
4877
49- att , err := dcode .Decode (attDomains )
50- if err != nil {
51- return nil , "" , fmt .Errorf ("failed to decode attestation: %v" , err )
78+ if len (hashAttDomains ) > 0 {
79+ if enclaveHost == "" {
80+ return nil , "" , fmt .Errorf ("certificate contains only hash attestation domains; use -s flag to specify server for attestation fetch" )
81+ }
82+
83+ certAttHash , err := decodeHashDomains (hashAttDomains )
84+ if err != nil {
85+ return nil , "" , fmt .Errorf ("failed to decode hash attestation: %v" , err )
86+ }
87+ log .Debugf ("Certificate attestation hash: %s" , certAttHash )
88+
89+ att , err := attestation .Fetch (enclaveHost )
90+ if err != nil {
91+ return nil , "" , fmt .Errorf ("failed to fetch attestation from server: %v" , err )
92+ }
93+ serverAttHash := att .Hash ()
94+ log .Debugf ("Server attestation hash: %s" , serverAttHash )
95+
96+ if certAttHash != serverAttHash {
97+ return nil , "" , fmt .Errorf ("attestation hash mismatch: cert=%s server=%s" , certAttHash , serverAttHash )
98+ }
99+ log .Infof ("Attestation hash verified: %s" , certAttHash )
100+ return att , keyFP , nil
52101 }
53- return att , keyFP , nil
102+
103+ return nil , "" , fmt .Errorf ("no attestation domains found in certificate" )
54104}
55105
56106var certificateAuditCmd = & cobra.Command {
57107 Use : "certificate audit" ,
58108 Short : "Audit enclave certificate" ,
59109 Run : func (cmd * cobra.Command , args []string ) {
60110 var cert * x509.Certificate
111+ var enclaveHost string
61112 if certFile != "" {
62113 certBytes , err := os .ReadFile (certFile )
63114 if err != nil {
@@ -75,11 +126,13 @@ var certificateAuditCmd = &cobra.Command{
75126 if server == "" {
76127 log .Fatal ("Server address is required" )
77128 }
78- if ! strings .Contains (server , ":" ) {
79- server += ":443"
129+ enclaveHost = strings .TrimSuffix (server , ":443" )
130+ serverAddr := server
131+ if ! strings .Contains (serverAddr , ":" ) {
132+ serverAddr += ":443"
80133 }
81134
82- conn , err := tls .Dial ("tcp" , server , nil )
135+ conn , err := tls .Dial ("tcp" , serverAddr , nil )
83136 if err != nil {
84137 log .Fatalf ("Failed to connect to server: %v" , err )
85138 }
@@ -91,7 +144,7 @@ var certificateAuditCmd = &cobra.Command{
91144 cert = certs [0 ]
92145 }
93146
94- att , certKeyFP , err := attestationFromCertificate (cert )
147+ att , certKeyFP , err := attestationFromCertificate (cert , enclaveHost )
95148 if err != nil {
96149 log .Fatalf ("Failed to get attestation from certificate: %v" , err )
97150 }
0 commit comments