@@ -31,6 +31,7 @@ import (
3131 "github.com/stretchr/testify/assert"
3232 "github.com/stretchr/testify/require"
3333 "go.step.sm/crypto/jose"
34+ "go.step.sm/crypto/minica"
3435 "go.step.sm/crypto/x509util"
3536 "golang.org/x/crypto/ssh"
3637
@@ -147,6 +148,13 @@ nIHOI54lAqDeF7A0y73fPRVCiJEWmuxz0g==
147148 privKey = "eyJhbGciOiJQQkVTMi1IUzI1NitBMTI4S1ciLCJjdHkiOiJqd2sranNvbiIsImVuYyI6IkEyNTZHQ00iLCJwMmMiOjEwMDAwMCwicDJzIjoiNEhBYjE0WDQ5OFM4LWxSb29JTnpqZyJ9.RbkJXGzI3kOsaP20KmZs0ELFLgpRddAE49AJHlEblw-uH_gg6SV3QA.M3MArEpHgI171lhm.gBlFySpzK9F7riBJbtLSNkb4nAw_gWokqs1jS-ZK1qxuqTK-9mtX5yILjRnftx9P9uFp5xt7rvv4Mgom1Ed4V9WtIyfNP_Cz3Pme1Eanp5nY68WCe_yG6iSB1RJdMDBUb2qBDZiBdhJim1DRXsOfgedOrNi7GGbppMlD77DEpId118owR5izA-c6Q_hg08hIE3tnMAnebDNQoF9jfEY99_AReVRH8G4hgwZEPCfXMTb3J-lowKGG4vXIbK5knFLh47SgOqG4M2M51SMS-XJ7oBz1Vjoamc90QIqKV51rvZ5m0N_sPFtxzcfV4E9yYH3XVd4O-CG4ydVKfKVyMtQ.mcKFZqBHp_n7Ytj2jz9rvw"
148149)
149150
151+ func mustJSON (t * testing.T , v any ) []byte {
152+ t .Helper ()
153+ var buf bytes.Buffer
154+ require .NoError (t , json .NewEncoder (& buf ).Encode (v ))
155+ return buf .Bytes ()
156+ }
157+
150158func parseCertificate (data string ) * x509.Certificate {
151159 block , _ := pem .Decode ([]byte (data ))
152160 if block == nil {
@@ -199,6 +207,7 @@ type mockAuthority struct {
199207 revoke func (context.Context , * authority.RevokeOptions ) error
200208 getEncryptedKey func (kid string ) (string , error )
201209 getRoots func () ([]* x509.Certificate , error )
210+ getIntermediateCertificates func () []* x509.Certificate
202211 getFederation func () ([]* x509.Certificate , error )
203212 getCRL func () (* authority.CertificateRevocationListInfo , error )
204213 signSSH func (ctx context.Context , key ssh.PublicKey , opts provisioner.SignSSHOptions , signOpts ... provisioner.SignOption ) (* ssh.Certificate , error )
@@ -321,6 +330,13 @@ func (m *mockAuthority) GetRoots() ([]*x509.Certificate, error) {
321330 return m .ret1 .([]* x509.Certificate ), m .err
322331}
323332
333+ func (m * mockAuthority ) GetIntermediateCertificates () []* x509.Certificate {
334+ if m .getIntermediateCertificates != nil {
335+ return m .getIntermediateCertificates ()
336+ }
337+ return m .ret1 .([]* x509.Certificate )
338+ }
339+
324340func (m * mockAuthority ) GetFederation () ([]* x509.Certificate , error ) {
325341 if m .getFederation != nil {
326342 return m .getFederation ()
@@ -1658,3 +1674,83 @@ func TestLogSSHCertificate(t *testing.T) {
16581674 assert .Equal (t , "AAAAKGVjZHNhLXNoYTItbmlzdHAyNTYtY2VydC12MDFAb3BlbnNzaC5jb20AAAAgLnkvSk4odlo3b1R+RDw+LmorL3RkN354IilCIVFVen4AAAAIbmlzdHAyNTYAAABBBHjKHss8WM2ffMYlavisoLXR0I6UEIU+cidV1ogEH1U6+/SYaFPrlzQo0tGLM5CNkMbhInbyasQsrHzn8F1Rt7nHg5/tcSf9qwAAAAEAAAAGaGVybWFuAAAACgAAAAZoZXJtYW4AAAAAY8kvJwAAAABjyhBjAAAAAAAAAIIAAAAVcGVybWl0LVgxMS1mb3J3YXJkaW5nAAAAAAAAABdwZXJtaXQtYWdlbnQtZm9yd2FyZGluZwAAAAAAAAAWcGVybWl0LXBvcnQtZm9yd2FyZGluZwAAAAAAAAAKcGVybWl0LXB0eQAAAAAAAAAOcGVybWl0LXVzZXItcmMAAAAAAAAAAAAAAGgAAAATZWNkc2Etc2hhMi1uaXN0cDI1NgAAAAhuaXN0cDI1NgAAAEEE/ayqpPrZZF5uA1UlDt4FreTf15agztQIzpxnWq/XoxAHzagRSkFGkdgFpjgsfiRpP8URHH3BZScqc0ZDCTxhoQAAAGQAAAATZWNkc2Etc2hhMi1uaXN0cDI1NgAAAEkAAAAhAJuP1wCVwoyrKrEtHGfFXrVbRHySDjvXtS1tVTdHyqymAAAAIBa/CSSzfZb4D2NLP+eEmOOMJwSjYOiNM8fiOoAaqglI" , fields ["certificate" ])
16591675 assert .Equal (t , "SHA256:RvkDPGwl/G9d7LUFm1kmWhvOD9I/moPq4yxcb0STwr0 (ECDSA-CERT)" , fields ["public-key" ])
16601676}
1677+
1678+ func TestIntermediates (t * testing.T ) {
1679+ ca , err := minica .New ()
1680+ require .NoError (t , err )
1681+
1682+ getRequest := func (t * testing.T , crt []* x509.Certificate ) * http.Request {
1683+ mockMustAuthority (t , & mockAuthority {
1684+ ret1 : crt ,
1685+ })
1686+ return httptest .NewRequest ("GET" , "/intermediates" , http .NoBody )
1687+ }
1688+
1689+ type args struct {
1690+ crts []* x509.Certificate
1691+ }
1692+ tests := []struct {
1693+ name string
1694+ args args
1695+ wantStatusCode int
1696+ wantBody []byte
1697+ }{
1698+ {"ok" , args {[]* x509.Certificate {ca .Intermediate }}, http .StatusCreated , mustJSON (t , IntermediatesResponse {
1699+ Certificates : []Certificate {{ca .Intermediate }},
1700+ })},
1701+ {"ok multiple" , args {[]* x509.Certificate {ca .Root , ca .Intermediate }}, http .StatusCreated , mustJSON (t , IntermediatesResponse {
1702+ Certificates : []Certificate {{ca .Root }, {ca .Intermediate }},
1703+ })},
1704+ {"fail" , args {}, http .StatusNotImplemented , mustJSON (t , errs .NotImplemented ("not implemented" ))},
1705+ }
1706+ for _ , tt := range tests {
1707+ t .Run (tt .name , func (t * testing.T ) {
1708+ w := httptest .NewRecorder ()
1709+ r := getRequest (t , tt .args .crts )
1710+ Intermediates (w , r )
1711+ assert .Equal (t , tt .wantStatusCode , w .Result ().StatusCode )
1712+ assert .Equal (t , tt .wantBody , w .Body .Bytes ())
1713+ })
1714+ }
1715+ }
1716+
1717+ func TestIntermediatesPEM (t * testing.T ) {
1718+ ca , err := minica .New ()
1719+ require .NoError (t , err )
1720+
1721+ getRequest := func (t * testing.T , crt []* x509.Certificate ) * http.Request {
1722+ mockMustAuthority (t , & mockAuthority {
1723+ ret1 : crt ,
1724+ })
1725+ return httptest .NewRequest ("GET" , "/intermediates.pem" , http .NoBody )
1726+ }
1727+
1728+ type args struct {
1729+ crts []* x509.Certificate
1730+ }
1731+ tests := []struct {
1732+ name string
1733+ args args
1734+ wantStatusCode int
1735+ wantBody []byte
1736+ }{
1737+ {"ok" , args {[]* x509.Certificate {ca .Intermediate }}, http .StatusOK , pem .EncodeToMemory (& pem.Block {
1738+ Type : "CERTIFICATE" , Bytes : ca .Intermediate .Raw ,
1739+ })},
1740+ {"ok multiple" , args {[]* x509.Certificate {ca .Root , ca .Intermediate }}, http .StatusOK , append (pem .EncodeToMemory (& pem.Block {
1741+ Type : "CERTIFICATE" , Bytes : ca .Root .Raw ,
1742+ }), pem .EncodeToMemory (& pem.Block {
1743+ Type : "CERTIFICATE" , Bytes : ca .Intermediate .Raw ,
1744+ })... )},
1745+ {"fail" , args {}, http .StatusNotImplemented , mustJSON (t , errs .NotImplemented ("not implemented" ))},
1746+ }
1747+ for _ , tt := range tests {
1748+ t .Run (tt .name , func (t * testing.T ) {
1749+ w := httptest .NewRecorder ()
1750+ r := getRequest (t , tt .args .crts )
1751+ IntermediatesPEM (w , r )
1752+ assert .Equal (t , tt .wantStatusCode , w .Result ().StatusCode )
1753+ assert .Equal (t , tt .wantBody , w .Body .Bytes ())
1754+ })
1755+ }
1756+ }
0 commit comments