@@ -2,6 +2,13 @@ package api
22
33import (
44 "context"
5+ "crypto/ecdsa"
6+ "crypto/elliptic"
7+ "crypto/rand"
8+ "crypto/x509"
9+ "crypto/x509/pkix"
10+ "encoding/pem"
11+ "math/big"
512 "os"
613 "path/filepath"
714 "strings"
@@ -18,6 +25,29 @@ import (
1825 utilsShared "github.com/e2b-dev/infra/packages/shared/pkg/utils"
1926)
2027
28+ // generateTestCACert creates a minimal self-signed CA certificate and returns
29+ // it as a PEM-encoded string. The cert is not written to disk.
30+ func generateTestCACert (t * testing.T ) string {
31+ t .Helper ()
32+
33+ key , err := ecdsa .GenerateKey (elliptic .P256 (), rand .Reader )
34+ require .NoError (t , err )
35+
36+ template := & x509.Certificate {
37+ SerialNumber : big .NewInt (1 ),
38+ Subject : pkix.Name {CommonName : "Test CA" },
39+ NotBefore : time .Now ().Add (- time .Minute ),
40+ NotAfter : time .Now ().Add (time .Hour ),
41+ IsCA : true ,
42+ BasicConstraintsValid : true ,
43+ }
44+
45+ der , err := x509 .CreateCertificate (rand .Reader , template , template , & key .PublicKey , key )
46+ require .NoError (t , err )
47+
48+ return string (pem .EncodeToMemory (& pem.Block {Type : "CERTIFICATE" , Bytes : der }))
49+ }
50+
2151func TestSimpleCases (t * testing.T ) {
2252 t .Parallel ()
2353 testCases := map [string ]func (string ) string {
@@ -585,3 +615,82 @@ func TestSetData(t *testing.T) {
585615 assert .Equal (t , "value" , val )
586616 })
587617}
618+
619+ func TestInstallCACerts (t * testing.T ) {
620+ t .Parallel ()
621+ ctx := context .Background ()
622+
623+ newAPIWithTempCertDir := func (t * testing.T ) (* API , string ) {
624+ t .Helper ()
625+ api := newTestAPI (nil , & mockMMDSClient {})
626+ api .certDir = t .TempDir ()
627+ return api , api .certDir
628+ }
629+
630+ t .Run ("writes single cert file with .crt extension" , func (t * testing.T ) {
631+ t .Parallel ()
632+ api , certDir := newAPIWithTempCertDir (t )
633+ certPEM := generateTestCACert (t )
634+
635+ api .installCACerts (ctx , []CACertificate {{Name : "my-proxy-ca" , Cert : certPEM }})
636+
637+ content , err := os .ReadFile (filepath .Join (certDir , "my-proxy-ca.crt" ))
638+ require .NoError (t , err )
639+ assert .Equal (t , certPEM , string (content ))
640+ })
641+
642+ t .Run ("writes multiple cert files" , func (t * testing.T ) {
643+ t .Parallel ()
644+ api , certDir := newAPIWithTempCertDir (t )
645+ cert1 := generateTestCACert (t )
646+ cert2 := generateTestCACert (t )
647+
648+ api .installCACerts (ctx , []CACertificate {
649+ {Name : "ca-one" , Cert : cert1 },
650+ {Name : "ca-two" , Cert : cert2 },
651+ })
652+
653+ content , err := os .ReadFile (filepath .Join (certDir , "ca-one.crt" ))
654+ require .NoError (t , err )
655+ assert .Equal (t , cert1 , string (content ))
656+
657+ content , err = os .ReadFile (filepath .Join (certDir , "ca-two.crt" ))
658+ require .NoError (t , err )
659+ assert .Equal (t , cert2 , string (content ))
660+ })
661+
662+ t .Run ("strips directory traversal from name" , func (t * testing.T ) {
663+ t .Parallel ()
664+ api , certDir := newAPIWithTempCertDir (t )
665+ certPEM := generateTestCACert (t )
666+
667+ api .installCACerts (ctx , []CACertificate {{Name : "../../../etc/evil" , Cert : certPEM }})
668+
669+ // filepath.Base("../../../etc/evil") == "evil", so the file lands inside certDir
670+ content , err := os .ReadFile (filepath .Join (certDir , "evil.crt" ))
671+ require .NoError (t , err )
672+ assert .Equal (t , certPEM , string (content ))
673+
674+ // Nothing should have escaped the temp dir
675+ _ , err = os .ReadFile ("/etc/evil.crt" )
676+ assert .True (t , os .IsNotExist (err ))
677+ })
678+
679+ t .Run ("cert content is valid PEM" , func (t * testing.T ) {
680+ t .Parallel ()
681+ api , certDir := newAPIWithTempCertDir (t )
682+ certPEM := generateTestCACert (t )
683+
684+ api .installCACerts (ctx , []CACertificate {{Name : "valid-ca" , Cert : certPEM }})
685+
686+ raw , err := os .ReadFile (filepath .Join (certDir , "valid-ca.crt" ))
687+ require .NoError (t , err )
688+
689+ block , _ := pem .Decode (raw )
690+ require .NotNil (t , block , "expected valid PEM block in written file" )
691+ assert .Equal (t , "CERTIFICATE" , block .Type )
692+
693+ _ , err = x509 .ParseCertificate (block .Bytes )
694+ require .NoError (t , err , "expected parseable X.509 certificate" )
695+ })
696+ }
0 commit comments