MCPcopy Index your code
hub / github.com/tailscale/tailscale / hostKeyFileOrCreate

Function hostKeyFileOrCreate

ssh/tailssh/hostkeys.go:97–138  ·  view source on GitHub ↗
(keyDir, typ string)

Source from the content-addressed store, hash-verified

95var keyGenMu sync.Mutex
96
97func hostKeyFileOrCreate(keyDir, typ string) ([]byte, error) {
98 keyGenMu.Lock()
99 defer keyGenMu.Unlock()
100
101 path := filepath.Join(keyDir, "ssh_host_"+typ+"_key")
102 v, err := os.ReadFile(path)
103 if err == nil {
104 return v, nil
105 }
106 if !os.IsNotExist(err) {
107 return nil, err
108 }
109 var priv any
110 switch typ {
111 default:
112 return nil, fmt.Errorf("unsupported key type %q", typ)
113 case "ed25519":
114 _, priv, err = ed25519.GenerateKey(rand.Reader)
115 case "ecdsa":
116 // curve is arbitrary. We pick whatever will at
117 // least pacify clients as the actual encryption
118 // doesn't matter: it's all over WireGuard anyway.
119 curve := elliptic.P256()
120 priv, err = ecdsa.GenerateKey(curve, rand.Reader)
121 case "rsa":
122 // keySize is arbitrary. We pick whatever will at
123 // least pacify clients as the actual encryption
124 // doesn't matter: it's all over WireGuard anyway.
125 const keySize = 2048
126 priv, err = rsa.GenerateKey(rand.Reader, keySize)
127 }
128 if err != nil {
129 return nil, err
130 }
131 mk, err := x509.MarshalPKCS8PrivateKey(priv)
132 if err != nil {
133 return nil, err
134 }
135 pemGen := pem.EncodeToMemory(&pem.Block{Type: "PRIVATE KEY", Bytes: mk})
136 err = os.WriteFile(path, pemGen, 0700)
137 return pemGen, err
138}
139
140func getSystemHostKeys(logf logger.Logf) (ret map[string]ssh.Signer) {
141 for _, typ := range keyTypes {

Callers 1

getTailscaleHostKeysFunction · 0.70

Calls 5

LockMethod · 0.65
UnlockMethod · 0.65
ReadFileMethod · 0.65
ErrorfMethod · 0.65
WriteFileMethod · 0.65

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…