Skip to content

Instantly share code, notes, and snippets.

@salrashid123
Last active October 2, 2025 01:30
Show Gist options
  • Select an option

  • Save salrashid123/d8aee4cf4f05c8921617daca0c9864b9 to your computer and use it in GitHub Desktop.

Select an option

Save salrashid123/d8aee4cf4f05c8921617daca0c9864b9 to your computer and use it in GitHub Desktop.
TLS with Restricted TPM Signing key and crypto.MessageSigner

ref: golang/go#75656

  1. install golang go 1.25.1 and override handshake_server_tls13.go

  2. 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  

  1. 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
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment