1
// Copyright 2015 Canonical Ltd.
2
// Licensed under the AGPLv3, see LICENCE file for details.
13
"github.com/juju/errors"
14
jc "github.com/juju/testing/checkers"
15
gc "gopkg.in/check.v1"
17
"github.com/juju/juju/tools/lxdclient"
21
_ = gc.Suite(&certSuite{})
22
_ = gc.Suite(&certFunctionalSuite{})
25
type certSuite struct {
32
func (s *certSuite) SetUpTest(c *gc.C) {
33
s.BaseSuite.SetUpTest(c)
35
s.certPEM = []byte("<a valid PEM-encoded x.509 cert>")
36
s.keyPEM = []byte("<a valid PEM-encoded x.509 key>")
39
func (s *certSuite) TestNewCert(c *gc.C) {
40
cert := lxdclient.NewCert(s.certPEM, s.keyPEM)
42
checkCert(c, cert, s.certPEM, s.keyPEM)
45
func (s *certSuite) TestValidateOkay(c *gc.C) {
46
cert := lxdclient.NewCert(s.certPEM, s.keyPEM)
47
err := cert.Validate()
49
c.Check(err, jc.ErrorIsNil)
52
func (s *certSuite) TestValidateMissingCertPEM(c *gc.C) {
53
cert := lxdclient.NewCert(nil, s.keyPEM)
54
err := cert.Validate()
56
c.Check(err, jc.Satisfies, errors.IsNotValid)
59
func (s *certSuite) TestValidateMissingKeyPEM(c *gc.C) {
60
cert := lxdclient.NewCert(s.certPEM, nil)
61
err := cert.Validate()
63
c.Check(err, jc.Satisfies, errors.IsNotValid)
66
func (s *certSuite) TestWriteCertPEM(c *gc.C) {
67
cert := lxdclient.NewCert(s.certPEM, s.keyPEM)
68
var pemfile bytes.Buffer
69
err := cert.WriteCertPEM(&pemfile)
70
c.Assert(err, jc.ErrorIsNil)
72
c.Check(pemfile.String(), gc.Equals, string(s.certPEM))
75
func (s *certSuite) TestWriteKeyPEM(c *gc.C) {
76
cert := lxdclient.NewCert(s.certPEM, s.keyPEM)
77
var pemfile bytes.Buffer
78
err := cert.WriteKeyPEM(&pemfile)
79
c.Assert(err, jc.ErrorIsNil)
81
c.Check(pemfile.String(), gc.Equals, string(s.keyPEM))
84
func (s *certSuite) TestWritePEMs(c *gc.C) {
85
cert := lxdclient.NewCert(s.certPEM, s.keyPEM)
86
var pemfile bytes.Buffer
87
err := cert.WriteCertPEM(&pemfile)
88
c.Assert(err, jc.ErrorIsNil)
89
err = cert.WriteKeyPEM(&pemfile)
90
c.Assert(err, jc.ErrorIsNil)
92
expected := string(s.certPEM) + string(s.keyPEM)
93
c.Check(pemfile.String(), gc.Equals, expected)
96
func (s *certSuite) TestFingerprint(c *gc.C) {
97
certPEM := []byte(testCertPEM)
98
cert := lxdclient.NewCert(certPEM, nil)
99
fingerprint, err := cert.Fingerprint()
100
c.Assert(err, jc.ErrorIsNil)
102
c.Check(fingerprint, gc.Equals, testCertFingerprint)
105
func (s *certSuite) TestX509Okay(c *gc.C) {
106
certPEM := []byte(testCertPEM)
107
cert := lxdclient.NewCert(certPEM, nil)
108
x509Cert, err := cert.X509()
109
c.Assert(err, jc.ErrorIsNil)
111
block, _ := pem.Decode(certPEM)
112
c.Assert(block, gc.NotNil)
113
c.Check(string(x509Cert.Raw), gc.Equals, string(block.Bytes))
116
func (s *certSuite) TestX509ZeroValue(c *gc.C) {
117
var cert lxdclient.Cert
118
_, err := cert.X509()
120
c.Check(err, gc.ErrorMatches, `invalid cert PEM \(0 bytes\)`)
123
func (s *certSuite) TestX509BadPEM(c *gc.C) {
124
cert := lxdclient.NewCert(s.certPEM, s.keyPEM)
125
_, err := cert.X509()
127
c.Check(err, gc.ErrorMatches, `invalid cert PEM \(\d+ bytes\)`)
130
type certFunctionalSuite struct {
134
func checkCert(c *gc.C, cert lxdclient.Cert, certPEM, keyPEM []byte) {
135
c.Check(cert, jc.DeepEquals, lxdclient.Cert{
139
c.Check(string(cert.CertPEM), gc.Equals, string(certPEM))
140
c.Check(string(cert.KeyPEM), gc.Equals, string(keyPEM))
143
func checkValidCert(c *gc.C, cert *lxdclient.Cert) {
144
c.Assert(cert, gc.NotNil)
146
_, err := tls.X509KeyPair(cert.CertPEM, cert.KeyPEM)
147
c.Check(err, jc.ErrorIsNil)
149
block, remainder := pem.Decode(cert.CertPEM)
150
c.Check(block.Type, gc.Equals, "CERTIFICATE")
151
c.Check(remainder, gc.HasLen, 0)
153
block, remainder = pem.Decode(cert.KeyPEM)
154
c.Check(block.Type, gc.Equals, "RSA PRIVATE KEY")
155
c.Check(remainder, gc.HasLen, 0)
159
testCertFingerprint = "1c5156027fe71cfd0f7db807123e6873879f0f9754e08eab151f224783b2bff0"
161
-----BEGIN CERTIFICATE-----
162
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
194
-----END CERTIFICATE-----