Beispiel
github.com/tailscale/tscert v0.0.0-20240608151842-d3f834017e53: fetch TLS certificate using tailscale tscert GetCertificate with mocked daemon transport
Verifiziertes Beispiel für golang github.com/tailscale/tscert v0.0.0-20240608151842-d3f834017e53: fetch TLS certificate using tailscale tscert GetCertificate…
sha256:fa827b92eaa8464bf3278089b147f12ba05fcd79912fd7bcff96b5d5d7c842b2
Dieses Netzwerk bietet eine Sache: ein Sample, das baut. Es hat es in einer Sandbox ausgeführt und die signierte Quittung behalten. Es bewertet nichts und garantiert nichts — ob derselbe Code bei Ihnen baut, hat es nicht gemessen.
Wie viele verschiedene Signaturschlüssel eine bestandene Vertragsquittung eingereicht haben. Einer ist der Autor allein; mehr als einer heißt, jemand anderes hat es auch gebaut. Ein Schlüssel wird selbst erzeugt und hat keine registrierte Identität dahinter — gezählt werden Schlüssel, nicht Personen.
MIT-0
Ausführungsbelege
Die deklarierte Umgebung und die signierten Läufe stehen getrennt, damit Sie genau sehen, was dieses Sample ausgeführt hat und wo.
- Beleggrundlage
- Signierter Vertrag bestanden
- Verifizierungsbelege
- 1
- Signaturschlüssel, die es gebaut haben
- 1
Deklarierte Umgebung
linux 24 · ubuntu · glibc 2.39 x64 go
Umgebungen der Verifizierungsläufe
| Umgebung | Contract | Stufen | Lauf |
|---|---|---|---|
| go 1.26 · linux alpine/x64 · docker ed25519:c1973797be207ac4 | PASS | compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS CONTAINER_RUN · golang@1golang:1.26-alpine@sha256:28d89ee9cc0f… |
2026-08-23 |
Fall
HOW- Ziel
- fetch TLS certificate using tailscale tscert GetCertificate with mocked daemon transport
- Symbole
-
- tscert.GetCertificate
- Erstellt
- 2026-08-23T16:47:42Z
Contract
- tscert.GetCertificate returns an error matching 'no SNI ServerName' when passed nil ClientHelloInfo or an empty ServerName
- tscert.GetCertificate fetches and returns a tls.Certificate from LocalAPI cert endpoint (/localapi/v0/cert/<domain>?type=pair) for a full domain name
- tscert.GetCertificate expands a bare hostname to FQDN using the LocalAPI status endpoint (/localapi/v0/status) CertDomains when ServerName contains no period
- tscert.TailscaledTransport allows mock HTTP transport override for daemon LocalAPI interactions
Dateien
- PROMPT.md
- contract_test.go
- csx.json
- go.mod
- go.sum
- spec.json
Quelltext
Clean-room public code sample — generation instructions
Write a brand-new, minimal, self-contained code sample in this clean-room directory.
Do not copy, paraphrase, or reference any existing project source. Work only from this spec.
A csx.json manifest scaffold already exists. Do not recreate it from memory. Preserve its case.goal, packages and symbols; fill its empty case.contract with exact assertions and correct its environment, commands and verifierAdapter for the files you generate.
Goal: fetch TLS certificate using tailscale tscert GetCertificate with mocked daemon transport
Kind: HOW
Use EXACTLY these public packages and versions:
- pkg:golang/github.com/tailscale/tscert@v0.0.0-20240608151842-d3f834017e53
Demonstrate these symbols/APIs:
- tscert.GetCertificate
Rules:
- One focused purpose; the smallest project that proves the goal.
- Include a contract test (test/contract.*) that runs OFFLINE and exits 0 exactly when the goal behavior works.
- Pin every dependency with a lockfile so resolution is reproducible.
- No secrets, credentials, or tokens. No real URLs (only example.com or localhost). No absolute paths.
- No personal names, emails, company names, or project identifiers of any kind.
- No binaries and no generated output (node_modules, dist, target, venv, .git, .env).
- Keep it under 200 files and 256KB packed.
package sample
import (
"bytes"
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
"crypto/tls"
"crypto/x509"
"crypto/x509/pkix"
"encoding/json"
"encoding/pem"
"io"
"math/big"
"net/http"
"strings"
"testing"
"time"
"github.com/tailscale/tscert"
)
type mockTransport func(*http.Request) (*http.Response, error)
func (f mockTransport) RoundTrip(req *http.Request) (*http.Response, error) {
return f(req)
}
func generateCertPairPEM(domain string) ([]byte, []byte, error) {
key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
if err != nil {
return nil, nil, err
}
template := x509.Certificate{
SerialNumber: big.NewInt(1),
Subject: pkix.Name{CommonName: domain},
DNSNames: []string{domain},
NotBefore: time.Now().Add(-time.Hour),
NotAfter: time.Now().Add(24 * time.Hour),
KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageKeyEncipherment,
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
}
certDER, err := x509.CreateCertificate(rand.Reader, &template, &template, &key.PublicKey, key)
if err != nil {
return nil, nil, err
}
keyDER, err := x509.MarshalECPrivateKey(key)
if err != nil {
return nil, nil, err
}
keyPEM := pem.EncodeToMemory(&pem.Block{Type: "EC PRIVATE KEY", Bytes: keyDER})
certPEM := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: certDER})
return keyPEM, certPEM, nil
}
func TestGetCertificateContract(t *testing.T) {
// Assert 1: nil ClientHelloInfo returns "no SNI ServerName" error
if _, err := tscert.GetCertificate(nil); err == nil || !strings.Contains(err.Error(), "no SNI ServerName") {
t.Fatalf("expected 'no SNI ServerName' error for nil info, got %v", err)
}
// Assert 2: empty ServerName returns "no SNI ServerName" error
if _, err := tscert.GetCertificate(&tls.ClientHelloInfo{ServerName: ""}); err == nil || !strings.Contains(err.Error(), "no SNI ServerName") {
t.Fatalf("expected 'no SNI ServerName' error for empty ServerName, got %v", err)
}
domain := "myserver.example.com"
keyPEM, certPEM, err := generateCertPairPEM(domain)
if err != nil {
t.Fatalf("failed to generate cert pair: %v", err)
}
pairPayload := append(keyPEM, certPEM...)
// Configure mock transport for daemon LocalAPI
tscert.TailscaledTransport = mockTransport(func(req *http.Request) (*http.Response, error) {
switch req.URL.Path {
case "/localapi/v0/status":
body, _ := json.Marshal(map[string]interface{}{
"Version": "1.0.0",
"BackendState": "Running",
"CertDomains": []string{domain},
})
return &http.Response{
StatusCode: http.StatusOK,
Body: io.NopCloser(bytes.NewReader(body)),
Header: make(http.Header),
}, nil
case "/localapi/v0/cert/" + domain:
if req.URL.Query().Get("type") != "pair" {
return &http.Response{
StatusCode: http.StatusBadRequest,
Body: io.NopCloser(bytes.NewReader([]byte("bad query"))),
Header: make(http.Header),
}, nil
}
return &http.Response{
StatusCode: http.StatusOK,
Body: io.NopCloser(bytes.NewReader(pairPayload)),
Header: make(http.Header),
}, nil
default:
return &http.Response{
StatusCode: http.StatusNotFound,
Body: io.NopCloser(bytes.NewReader([]byte("not found"))),
Header: make(http.Header),
}, nil
}
})
// Assert 3: GetCertificate with FQDN fetches cert pair from LocalAPI and returns tls.Certificate
cert, err := tscert.GetCertificate(&tls.ClientHelloInfo{ServerName: domain})
if err != nil {
t.Fatalf("GetCertificate failed for FQDN: %v", err)
}
if cert == nil || len(cert.Certificate) == 0 {
t.Fatalf("expected non-empty certificate for FQDN")
}
// Assert 4: GetCertificate with bare label expands domain using daemon status and returns tls.Certificate
certBare, err := tscert.GetCertificate(&tls.ClientHelloInfo{ServerName: "myserver"})
if err != nil {
t.Fatalf("GetCertificate failed for bare label: %v", err)
}
if certBare == nil || len(certBare.Certificate) == 0 {
t.Fatalf("expected non-empty certificate for bare label")
}
}
{"case":{"caseId":"case:sha256:bd538166c6f57e8215aedefdbc3482a67e328f38adf3c371cfe04d3f2e9069fb","contract":["tscert.GetCertificate returns an error matching 'no SNI ServerName' when passed nil ClientHelloInfo or an empty ServerName","tscert.GetCertificate fetches and returns a tls.Certificate from LocalAPI cert endpoint (/localapi/v0/cert/\u003cdomain\u003e?type=pair) for a full domain name","tscert.GetCertificate expands a bare hostname to FQDN using the LocalAPI status endpoint (/localapi/v0/status) CertDomains when ServerName contains no period","tscert.TailscaledTransport allows mock HTTP transport override for daemon LocalAPI interactions"],"goal":"fetch TLS certificate using tailscale tscert GetCertificate with mocked daemon transport","kind":"HOW","packages":["pkg:golang/github.com/tailscale/tscert@v0.0.0-20240608151842-d3f834017e53"],"schemaVersion":1,"symbols":["tscert.GetCertificate"]},"contractCommand":["go","test","./..."],"environment":{"arch":"x64","distro":"ubuntu","ecosystem":"golang","libc":"glibc","libcVersion":"2.39","os":"linux","osVersionBucket":"24","packageManager":"go","schemaVersion":1},"license":"MIT-0","packages":["pkg:golang/github.com/tailscale/tscert@v0.0.0-20240608151842-d3f834017e53"],"schemaVersion":1,"subject":"pkg:golang/github.com/tailscale/tscert@v0.0.0-20240608151842-d3f834017e53","symbols":["tscert.GetCertificate"],"verifierAdapter":"golang@1"}
module sample
go 1.22
require github.com/tailscale/tscert v0.0.0-20240608151842-d3f834017e53
require (
github.com/Microsoft/go-winio v0.6.0 // indirect
github.com/mitchellh/go-ps v1.0.0 // indirect
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f // indirect
golang.org/x/tools v0.1.12 // indirect
)
github.com/Microsoft/go-winio v0.6.0 h1:slsWYD/zyx7lCXoZVlvQrj0hPTM1HI4+v1sIda2yDvg=
github.com/Microsoft/go-winio v0.6.0/go.mod h1:cTAf44im0RAYeL23bpB+fzCyDH2MJiz2BO69KH/soAE=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/mitchellh/go-ps v1.0.0 h1:i6ampVEEF4wQFF+bkYfwYgY+F/uYJDktmvLPf7qIgjc=
github.com/mitchellh/go-ps v1.0.0/go.mod h1:J4lOc8z8yJs6vUwklHw2XEIiT4z4C40KtWVN3nvg8Pg=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/tailscale/tscert v0.0.0-20240608151842-d3f834017e53 h1:uxMgm0C+EjytfAqyfBG55ZONKQ7mvd7x4YYCWsf8QHQ=
github.com/tailscale/tscert v0.0.0-20240608151842-d3f834017e53/go.mod h1:kNGUQ3VESx3VZwRwA9MSCUegIl6+saPL8Noq82ozCaU=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f h1:v4INt8xihDGvnrfjMDVXGxw9wrfxYyCjk0KbXjhR55s=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
{
"schemaVersion": 1,
"goal": "fetch TLS certificate using tailscale tscert GetCertificate with mocked daemon transport",
"kind": "HOW",
"packages": [
"pkg:golang/github.com/tailscale/tscert@v0.0.0-20240608151842-d3f834017e53"
],
"symbols": [
"tscert.GetCertificate"
]
}
Ursprungs-Seeder
anonym