github.com/makyo/juju@v0.0.0-20160425123129-2608902037e9/tools/lxdclient/cert_test.go (about) 1 // Copyright 2015 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 // +build go1.3 5 6 package lxdclient_test 7 8 import ( 9 "bytes" 10 "crypto/tls" 11 "encoding/pem" 12 13 "github.com/juju/errors" 14 jc "github.com/juju/testing/checkers" 15 gc "gopkg.in/check.v1" 16 17 "github.com/juju/juju/tools/lxdclient" 18 ) 19 20 var ( 21 _ = gc.Suite(&certSuite{}) 22 _ = gc.Suite(&certFunctionalSuite{}) 23 ) 24 25 type certSuite struct { 26 lxdclient.BaseSuite 27 28 certPEM []byte 29 keyPEM []byte 30 } 31 32 func (s *certSuite) SetUpTest(c *gc.C) { 33 s.BaseSuite.SetUpTest(c) 34 35 s.certPEM = []byte("<a valid PEM-encoded x.509 cert>") 36 s.keyPEM = []byte("<a valid PEM-encoded x.509 key>") 37 } 38 39 func (s *certSuite) TestNewCert(c *gc.C) { 40 cert := lxdclient.NewCert(s.certPEM, s.keyPEM) 41 42 checkCert(c, cert, s.certPEM, s.keyPEM) 43 } 44 45 func (s *certSuite) TestValidateOkay(c *gc.C) { 46 cert := lxdclient.NewCert(s.certPEM, s.keyPEM) 47 err := cert.Validate() 48 49 c.Check(err, jc.ErrorIsNil) 50 } 51 52 func (s *certSuite) TestValidateMissingCertPEM(c *gc.C) { 53 cert := lxdclient.NewCert(nil, s.keyPEM) 54 err := cert.Validate() 55 56 c.Check(err, jc.Satisfies, errors.IsNotValid) 57 } 58 59 func (s *certSuite) TestValidateMissingKeyPEM(c *gc.C) { 60 cert := lxdclient.NewCert(s.certPEM, nil) 61 err := cert.Validate() 62 63 c.Check(err, jc.Satisfies, errors.IsNotValid) 64 } 65 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) 71 72 c.Check(pemfile.String(), gc.Equals, string(s.certPEM)) 73 } 74 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) 80 81 c.Check(pemfile.String(), gc.Equals, string(s.keyPEM)) 82 } 83 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) 91 92 expected := string(s.certPEM) + string(s.keyPEM) 93 c.Check(pemfile.String(), gc.Equals, expected) 94 } 95 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) 101 102 c.Check(fingerprint, gc.Equals, testCertFingerprint) 103 } 104 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) 110 111 block, _ := pem.Decode(certPEM) 112 c.Assert(block, gc.NotNil) 113 c.Check(string(x509Cert.Raw), gc.Equals, string(block.Bytes)) 114 } 115 116 func (s *certSuite) TestX509ZeroValue(c *gc.C) { 117 var cert lxdclient.Cert 118 _, err := cert.X509() 119 120 c.Check(err, gc.ErrorMatches, `invalid cert PEM \(0 bytes\)`) 121 } 122 123 func (s *certSuite) TestX509BadPEM(c *gc.C) { 124 cert := lxdclient.NewCert(s.certPEM, s.keyPEM) 125 _, err := cert.X509() 126 127 c.Check(err, gc.ErrorMatches, `invalid cert PEM \(\d+ bytes\)`) 128 } 129 130 type certFunctionalSuite struct { 131 lxdclient.BaseSuite 132 } 133 134 func checkCert(c *gc.C, cert lxdclient.Cert, certPEM, keyPEM []byte) { 135 c.Check(cert, jc.DeepEquals, lxdclient.Cert{ 136 CertPEM: certPEM, 137 KeyPEM: keyPEM, 138 }) 139 c.Check(string(cert.CertPEM), gc.Equals, string(certPEM)) 140 c.Check(string(cert.KeyPEM), gc.Equals, string(keyPEM)) 141 } 142 143 func checkValidCert(c *gc.C, cert *lxdclient.Cert) { 144 c.Assert(cert, gc.NotNil) 145 146 _, err := tls.X509KeyPair(cert.CertPEM, cert.KeyPEM) 147 c.Check(err, jc.ErrorIsNil) 148 149 block, remainder := pem.Decode(cert.CertPEM) 150 c.Check(block.Type, gc.Equals, "CERTIFICATE") 151 c.Check(remainder, gc.HasLen, 0) 152 153 block, remainder = pem.Decode(cert.KeyPEM) 154 c.Check(block.Type, gc.Equals, "RSA PRIVATE KEY") 155 c.Check(remainder, gc.HasLen, 0) 156 } 157 158 const ( 159 testCertFingerprint = "1c5156027fe71cfd0f7db807123e6873879f0f9754e08eab151f224783b2bff0" 160 testCertPEM = ` 161 -----BEGIN CERTIFICATE----- 162 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 193 zxBNMbP3 194 -----END CERTIFICATE----- 195 ` 196 )