@@ -31,6 +31,7 @@ import (
31
31
"github.com/stretchr/testify/assert"
32
32
"github.com/stretchr/testify/require"
33
33
"go.step.sm/crypto/jose"
34
+ "go.step.sm/crypto/minica"
34
35
"go.step.sm/crypto/x509util"
35
36
"golang.org/x/crypto/ssh"
36
37
@@ -147,6 +148,13 @@ nIHOI54lAqDeF7A0y73fPRVCiJEWmuxz0g==
147
148
privKey = "eyJhbGciOiJQQkVTMi1IUzI1NitBMTI4S1ciLCJjdHkiOiJqd2sranNvbiIsImVuYyI6IkEyNTZHQ00iLCJwMmMiOjEwMDAwMCwicDJzIjoiNEhBYjE0WDQ5OFM4LWxSb29JTnpqZyJ9.RbkJXGzI3kOsaP20KmZs0ELFLgpRddAE49AJHlEblw-uH_gg6SV3QA.M3MArEpHgI171lhm.gBlFySpzK9F7riBJbtLSNkb4nAw_gWokqs1jS-ZK1qxuqTK-9mtX5yILjRnftx9P9uFp5xt7rvv4Mgom1Ed4V9WtIyfNP_Cz3Pme1Eanp5nY68WCe_yG6iSB1RJdMDBUb2qBDZiBdhJim1DRXsOfgedOrNi7GGbppMlD77DEpId118owR5izA-c6Q_hg08hIE3tnMAnebDNQoF9jfEY99_AReVRH8G4hgwZEPCfXMTb3J-lowKGG4vXIbK5knFLh47SgOqG4M2M51SMS-XJ7oBz1Vjoamc90QIqKV51rvZ5m0N_sPFtxzcfV4E9yYH3XVd4O-CG4ydVKfKVyMtQ.mcKFZqBHp_n7Ytj2jz9rvw"
148
149
)
149
150
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
+
150
158
func parseCertificate (data string ) * x509.Certificate {
151
159
block , _ := pem .Decode ([]byte (data ))
152
160
if block == nil {
@@ -199,6 +207,7 @@ type mockAuthority struct {
199
207
revoke func (context.Context , * authority.RevokeOptions ) error
200
208
getEncryptedKey func (kid string ) (string , error )
201
209
getRoots func () ([]* x509.Certificate , error )
210
+ getIntermediateCertificates func () []* x509.Certificate
202
211
getFederation func () ([]* x509.Certificate , error )
203
212
getCRL func () (* authority.CertificateRevocationListInfo , error )
204
213
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) {
321
330
return m .ret1 .([]* x509.Certificate ), m .err
322
331
}
323
332
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
+
324
340
func (m * mockAuthority ) GetFederation () ([]* x509.Certificate , error ) {
325
341
if m .getFederation != nil {
326
342
return m .getFederation ()
@@ -1658,3 +1674,83 @@ func TestLogSSHCertificate(t *testing.T) {
1658
1674
assert .Equal (t , "AAAAKGVjZHNhLXNoYTItbmlzdHAyNTYtY2VydC12MDFAb3BlbnNzaC5jb20AAAAgLnkvSk4odlo3b1R+RDw+LmorL3RkN354IilCIVFVen4AAAAIbmlzdHAyNTYAAABBBHjKHss8WM2ffMYlavisoLXR0I6UEIU+cidV1ogEH1U6+/SYaFPrlzQo0tGLM5CNkMbhInbyasQsrHzn8F1Rt7nHg5/tcSf9qwAAAAEAAAAGaGVybWFuAAAACgAAAAZoZXJtYW4AAAAAY8kvJwAAAABjyhBjAAAAAAAAAIIAAAAVcGVybWl0LVgxMS1mb3J3YXJkaW5nAAAAAAAAABdwZXJtaXQtYWdlbnQtZm9yd2FyZGluZwAAAAAAAAAWcGVybWl0LXBvcnQtZm9yd2FyZGluZwAAAAAAAAAKcGVybWl0LXB0eQAAAAAAAAAOcGVybWl0LXVzZXItcmMAAAAAAAAAAAAAAGgAAAATZWNkc2Etc2hhMi1uaXN0cDI1NgAAAAhuaXN0cDI1NgAAAEEE/ayqpPrZZF5uA1UlDt4FreTf15agztQIzpxnWq/XoxAHzagRSkFGkdgFpjgsfiRpP8URHH3BZScqc0ZDCTxhoQAAAGQAAAATZWNkc2Etc2hhMi1uaXN0cDI1NgAAAEkAAAAhAJuP1wCVwoyrKrEtHGfFXrVbRHySDjvXtS1tVTdHyqymAAAAIBa/CSSzfZb4D2NLP+eEmOOMJwSjYOiNM8fiOoAaqglI" , fields ["certificate" ])
1659
1675
assert .Equal (t , "SHA256:RvkDPGwl/G9d7LUFm1kmWhvOD9I/moPq4yxcb0STwr0 (ECDSA-CERT)" , fields ["public-key" ])
1660
1676
}
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