ref: golang/go#75656
-
install golang
go 1.25.1and override handshake_server_tls13.go -
create a restricted rsapss key and make it persistent
rm -rf myvtpmA && mkdir myvtpmA && mkdir certsA
swtpm_setup --tpmstate myvtpmA --tpm2 --create-ek-cert --create-platform-cert --allow-signing --write-ek-cert-files .
swtpm socket --tpmstate dir=myvtpmA --tpm2 --server type=tcp,port=2321 --ctrl type=tcp,port=2322 --flags not-need-init,startup-clear --log level=2
export TPM2TOOLS_TCTI="swtpm:port=2321"
tpm2_flushcontext -t && tpm2_flushcontext -s && tpm2_flushcontext -l
printf '\x00\x00' > /tmp/unique.dat
tpm2_createprimary -C o -G ecc -g sha256 \
-c primary.ctx \
-a "fixedtpm|fixedparent|sensitivedataorigin|userwithauth|noda|restricted|decrypt" -u /tmp/unique.dat
tpm2_flushcontext -t && tpm2_flushcontext -s && tpm2_flushcontext -l
tpm2_create -G rsa2048:rsapss:null -g sha256 -u rsa.pub -r rsa.priv -C primary.ctx \
-a "fixedtpm|fixedparent|sensitivedataorigin|userwithauth|noda|restricted|sign"
tpm2_flushcontext -t && tpm2_flushcontext -s && tpm2_flushcontext -l
tpm2_load -C primary.ctx -u rsa.pub -r rsa.priv -c rsa.ctx
tpm2_evictcontrol -C o -c rsa.ctx 0x81008001
tpm2_flushcontext -t && tpm2_flushcontext -s && tpm2_flushcontext -l - run server
package main
import (
"crypto"
"crypto/rand"
"crypto/tls"
"crypto/x509"
"crypto/x509/pkix"
"flag"
"fmt"
"io"
"log"
"math/big"
"net"
"net/http"
"os"
"slices"
"time"
//"github.com/salrashid123/messagesigner"
"github.com/google/go-tpm/tpm2"
"github.com/google/go-tpm/tpmutil"
"github.com/gorilla/mux"
"github.com/salrashid123/tpmsigner"
"golang.org/x/net/http2"
)
var (
persistentHandle = flag.Uint("persistentHandle", 0x81008001, "Handle value")
tpmPath = flag.String("tpm-path", "127.0.0.1:2321", "Path to the TPM device (character device or a Unix socket).")
)
var TPMDEVICES = []string{"/dev/tpm0", "/dev/tpmrm0"}
func OpenTPM(path string) (io.ReadWriteCloser, error) {
if slices.Contains(TPMDEVICES, path) {
return tpmutil.OpenTPM(path)
} else {
return net.Dial("tcp", path)
}
}
func gethandler(w http.ResponseWriter, r *http.Request) {
fmt.Fprint(w, "ok")
}
func main() {
flag.Parse()
rwc, err := OpenTPM(*tpmPath)
if err != nil {
log.Fatalf("can't open TPM %q: %v", *tpmPath, err)
}
defer func() {
if err := rwc.Close(); err != nil {
log.Fatalf("can't close TPM %q: %v", *tpmPath, err)
}
}()
// rwr := transport.FromReadWriter(rwc)
msigner, err := tpmsigner.NewTPMCrypto(&tpmsigner.TPM{
TpmDevice: rwc,
Handle: tpm2.TPMHandle(*persistentHandle),
})
if err != nil {
fmt.Println(err)
os.Exit(1)
}
crt2, err := createServerCertFromMessageSigner(msigner)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
fmt.Printf("%d\n", crt2.Leaf.SerialNumber)
tlsConfig := &tls.Config{
Certificates: []tls.Certificate{*crt2},
MinVersion: tls.VersionTLS13,
Renegotiation: tls.RenegotiateNever,
}
router := mux.NewRouter()
router.Methods(http.MethodGet).Path("/").HandlerFunc(gethandler)
server := &http.Server{
Addr: ":8081",
Handler: router,
TLSConfig: tlsConfig,
}
http2.ConfigureServer(server, &http2.Server{})
fmt.Println("Starting Server..")
err = server.ListenAndServeTLS("", "")
fmt.Printf("Unable to start Server %v", err)
}
func createServerCertFromMessageSigner(pk crypto.MessageSigner) (*tls.Certificate, error) {
serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128)
serialNumber, err := rand.Int(rand.Reader, serialNumberLimit)
if err != nil {
return nil, fmt.Errorf("failed to generate serial number: %s", err)
}
template := &x509.Certificate{
SerialNumber: serialNumber,
Subject: pkix.Name{
Organization: []string{"Acme Co"},
},
NotBefore: time.Now(),
NotAfter: time.Now().Add(time.Hour),
SignatureAlgorithm: x509.SHA256WithRSAPSS,
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
BasicConstraintsValid: true,
}
derBytes, err := x509.CreateCertificate(rand.Reader, template, template, pk.Public(), pk)
if err != nil {
return nil, fmt.Errorf("failed to create certificate: %s", err)
}
return &tls.Certificate{PrivateKey: pk, Leaf: template, Certificate: [][]byte{derBytes}}, nil
}