Skip to content

Commit 7e9eb2f

Browse files
committed
feat: proxy and cmdline config
1 parent 7d8897c commit 7e9eb2f

File tree

2 files changed

+60
-11
lines changed

2 files changed

+60
-11
lines changed

.goreleaser.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ builds:
1313

1414
nfpms:
1515
- package_name: tinfoil-sev-shim
16-
file_name_template: "{{ .ProjectName }}_{{ .Version }}"
16+
file_name_template: tinfoil-sev-shim
1717
vendor: Tinfoil
1818
maintainer: Tinfoil <[email protected]>
1919
section: utils

main.go

Lines changed: 59 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ import (
1010
"fmt"
1111
"log"
1212
"net/http"
13+
"net/http/httputil"
14+
"net/url"
15+
"os"
16+
"strings"
1317

1418
"github.com/caddyserver/certmagic"
1519
"github.com/google/go-sev-guest/abi"
@@ -18,13 +22,33 @@ import (
1822
"github.com/tinfoilanalytics/verifier/pkg/attestation"
1923
)
2024

25+
var version = "dev"
26+
2127
var (
2228
listenAddr = flag.String("l", ":443", "listen address")
23-
domain = flag.String("d", "", "TLS domain name")
24-
email = flag.String("e", "", "TLS email address")
2529
staging = flag.Bool("s", false, "use staging CA")
30+
upstream = flag.Int("u", 8080, "upstream port")
31+
32+
2633
)
2734

35+
// cmdlineParam returns the value of a parameter from the kernel command line
36+
func cmdlineParam(key string) (string, error) {
37+
cmdline, err := os.ReadFile("/proc/cmdline")
38+
if err != nil {
39+
return "", err
40+
}
41+
42+
for _, p := range strings.Split(string(cmdline), " ") {
43+
if strings.HasPrefix(p, key+"=") {
44+
return strings.TrimPrefix(p, key+"="), nil
45+
}
46+
}
47+
48+
return "", fmt.Errorf("missing %s", key)
49+
}
50+
51+
// attestationReport gets a SEV-SNP signed attestation report over a TLS certificate fingerprint
2852
func attestationReport(certFP string) (*attestation.Document, error) {
2953
var userData [64]byte
3054
copy(userData[:], certFP)
@@ -48,44 +72,69 @@ func attestationReport(certFP string) (*attestation.Document, error) {
4872
}, nil
4973
}
5074

75+
func cors(w http.ResponseWriter, r *http.Request) {
76+
w.Header().Set("Access-Control-Allow-Origin", "*")
77+
w.Header().Set("Access-Control-Allow-Methods", "*")
78+
w.Header().Set("Access-Control-Allow-Headers", "*")
79+
80+
if r.Method == "OPTIONS" {
81+
w.WriteHeader(http.StatusOK)
82+
return
83+
}
84+
}
85+
5186
func main() {
5287
flag.Parse()
53-
if *domain == "" {
54-
log.Fatal("domain is required")
55-
}
56-
if *email == "" {
57-
log.Fatal("email is required")
88+
89+
domain, err := cmdlineParam("tinfoil-domain")
90+
if err != nil {
91+
log.Fatal(err)
5892
}
5993

94+
log.Printf("Starting SEV-SNP attestation shim %s domain %s", version, domain)
95+
6096
mux := http.NewServeMux()
6197

62-
certmagic.DefaultACME.Email = *email
98+
// Request TLS certificate
99+
certmagic.DefaultACME.Email = email
63100
if *staging {
64101
certmagic.DefaultACME.CA = certmagic.LetsEncryptStagingCA
65102
} else {
66103
certmagic.DefaultACME.CA = certmagic.LetsEncryptProductionCA
67104
}
68-
tlsConfig, err := certmagic.TLS([]string{*domain})
105+
tlsConfig, err := certmagic.TLS([]string{domain})
69106
if err != nil {
70107
log.Fatalf("Failed to get TLS config: %v", err)
71108
}
72109

110+
// Get certificate from TLS config
73111
cert, err := tlsConfig.GetCertificate(&tls.ClientHelloInfo{
74-
ServerName: *domain,
112+
ServerName: domain,
75113
})
76114
if err != nil {
77115
log.Fatalf("Failed to get certificate: %v", err)
78116
}
79117
certFP := sha256.Sum256(cert.Leaf.Raw)
80118
certFPHex := hex.EncodeToString(certFP[:])
81119

120+
// Request SEV-SNP attestation
82121
log.Printf("Fetching attestation over %s", certFPHex)
83122
att, err := attestationReport(certFPHex)
84123
if err != nil {
85124
log.Fatal(err)
86125
}
87126

88127
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
128+
cors(w, r)
129+
proxy := httputil.NewSingleHostReverseProxy(&url.URL{
130+
Scheme: "http",
131+
Host: fmt.Sprintf("localhost:%d", *upstream),
132+
})
133+
proxy.ServeHTTP(w, r)
134+
})
135+
136+
mux.HandleFunc("/.well-known/tinfoil-attestation", func(w http.ResponseWriter, r *http.Request) {
137+
cors(w, r)
89138
w.WriteHeader(http.StatusOK)
90139
w.Header().Set("Content-Type", "application/json")
91140
json.NewEncoder(w).Encode(att)

0 commit comments

Comments
 (0)