@@ -36,7 +36,8 @@ type Ports struct {
3636
3737type Certs struct {
3838 daemonCerts map [string ]certs.CertAndKey
39- daemonLock sync.Mutex
39+ clientCert certs.CertAndKey
40+ lock sync.Mutex
4041}
4142
4243func IsDaemonRunning (url string ) bool {
@@ -157,8 +158,8 @@ func (e *Engine) startDaemon(tool types.Tool) (string, error) {
157158 url = fmt .Sprintf ("https://127.0.0.1:%d%s" , port , path )
158159
159160 // Generate a certificate for the daemon, unless one already exists.
160- certificates .daemonLock .Lock ()
161- defer certificates .daemonLock .Unlock ()
161+ certificates .lock .Lock ()
162+ defer certificates .lock .Unlock ()
162163 cert , exists := certificates .daemonCerts [tool .ID ]
163164 if ! exists {
164165 var err error
@@ -173,12 +174,21 @@ func (e *Engine) startDaemon(tool types.Tool) (string, error) {
173174 certificates .daemonCerts [tool .ID ] = cert
174175 }
175176
177+ // Set the client certificate if there isn't one already.
178+ if len (certificates .clientCert .Cert ) == 0 {
179+ gptscriptCert , err := certs .GenerateGPTScriptCert ()
180+ if err != nil {
181+ return "" , fmt .Errorf ("failed to generate GPTScript certificate: %v" , err )
182+ }
183+ certificates .clientCert = gptscriptCert
184+ }
185+
176186 cmd , stop , err := e .newCommand (ctx , []string {
177187 fmt .Sprintf ("PORT=%d" , port ),
178188 fmt .Sprintf ("CERT=%s" , base64 .StdEncoding .EncodeToString (cert .Cert )),
179189 fmt .Sprintf ("PRIVATE_KEY=%s" , base64 .StdEncoding .EncodeToString (cert .Key )),
180190 fmt .Sprintf ("GPTSCRIPT_PORT=%d" , port ),
181- fmt .Sprintf ("GPTSCRIPT_CERT=%s" , base64 .StdEncoding .EncodeToString (e . GPTScriptCert .Cert )),
191+ fmt .Sprintf ("GPTSCRIPT_CERT=%s" , base64 .StdEncoding .EncodeToString (certificates . clientCert .Cert )),
182192 },
183193 tool ,
184194 "{}" ,
@@ -241,7 +251,7 @@ func (e *Engine) startDaemon(tool types.Tool) (string, error) {
241251 }()
242252
243253 // Build HTTP client for checking the health of the daemon
244- clientCert , err := tls .X509KeyPair (e . GPTScriptCert .Cert , e . GPTScriptCert .Key )
254+ tlsClientCert , err := tls .X509KeyPair (certificates . clientCert .Cert , certificates . clientCert .Key )
245255 if err != nil {
246256 return "" , fmt .Errorf ("failed to create client certificate: %v" , err )
247257 }
@@ -254,7 +264,7 @@ func (e *Engine) startDaemon(tool types.Tool) (string, error) {
254264 httpClient := & http.Client {
255265 Transport : & http.Transport {
256266 TLSClientConfig : & tls.Config {
257- Certificates : []tls.Certificate {clientCert },
267+ Certificates : []tls.Certificate {tlsClientCert },
258268 RootCAs : pool ,
259269 InsecureSkipVerify : false ,
260270 },
@@ -271,7 +281,6 @@ func (e *Engine) startDaemon(tool types.Tool) (string, error) {
271281 }()
272282 return url , nil
273283 }
274- _ = resp .Body .Close ()
275284 select {
276285 case <- killedCtx .Done ():
277286 return url , fmt .Errorf ("daemon failed to start: %w" , context .Cause (killedCtx ))
0 commit comments