github.com/hoffie/larasync@v0.0.0-20151025221940-0384d2bddcef/api/tls/fingerprintVerifier_test.go (about) 1 package tls 2 3 import ( 4 "bytes" 5 "crypto/ecdsa" 6 "crypto/elliptic" 7 "crypto/tls" 8 "crypto/x509" 9 "io/ioutil" 10 "math/big" 11 "net" 12 "strings" 13 "time" 14 15 . "gopkg.in/check.v1" 16 ) 17 18 type FVTests struct{} 19 20 var _ = Suite(&FVTests{}) 21 22 func (t *FVTests) TestAcceptPeerCertNoFpNoFunc(c *C) { 23 crt, _, _ := t.makeTestCert(c) 24 fpv := FingerprintVerifier{} 25 c.Assert(fpv.acceptPeerCert(crt), Equals, false) 26 } 27 28 func (t *FVTests) TestAcceptPeerCertAcceptFuncFail(c *C) { 29 crt, _, _ := t.makeTestCert(c) 30 fpv := FingerprintVerifier{ 31 VerificationFunc: func(fp string) bool { 32 return false 33 }, 34 } 35 c.Assert(fpv.acceptPeerCert(crt), Equals, false) 36 c.Assert(fpv.AcceptFingerprint, Equals, "") 37 } 38 39 func (t *FVTests) TestAcceptPeerCertAcceptFuncAccept(c *C) { 40 crt, _, _ := t.makeTestCert(c) 41 fpv := FingerprintVerifier{ 42 VerificationFunc: func(fp string) bool { 43 return true 44 }, 45 } 46 c.Assert(fpv.acceptPeerCert(crt), Equals, true) 47 c.Assert(fpv.AcceptFingerprint, Equals, testCertFp) 48 fpv.VerificationFunc = func(fp string) bool { 49 c.Fatal("unexpected call to verification func") 50 return false 51 } 52 c.Assert(fpv.acceptPeerCert(crt), Equals, true) 53 } 54 55 func (t *FVTests) TestAcceptPeerCertPreset(c *C) { 56 crt, _, _ := t.makeTestCert(c) 57 fpv := FingerprintVerifier{ 58 AcceptFingerprint: testCertFp, 59 } 60 c.Assert(fpv.acceptPeerCert(crt), Equals, true) 61 } 62 63 func (t *FVTests) TestAcceptPeerCertPresetFail(c *C) { 64 crt, _, _ := t.makeTestCert(c) 65 fpv := FingerprintVerifier{ 66 AcceptFingerprint: strings.Replace(testCertFp, "c", "d", 1), 67 } 68 c.Assert(fpv.acceptPeerCert(crt), Equals, false) 69 } 70 71 func (t *FVTests) TestAcceptPeerCertPresetFailNoCall(c *C) { 72 crt, _, _ := t.makeTestCert(c) 73 fpv := FingerprintVerifier{ 74 AcceptFingerprint: strings.Replace(testCertFp, "c", "d", 1), 75 VerificationFunc: func(fp string) bool { 76 c.Fatal("verification called although unexpected") 77 return false 78 }, 79 } 80 c.Assert(fpv.acceptPeerCert(crt), Equals, false) 81 } 82 83 func (t *FVTests) setupTLSServer(c *C) (string, net.Listener) { 84 l, err := net.Listen("tcp", "127.0.0.1:0") 85 c.Assert(err, IsNil) 86 _, derBytes, priv := t.makeTestCert(c) 87 myCert := tls.Certificate{ 88 Certificate: [][]byte{derBytes}, 89 PrivateKey: priv, 90 } 91 tlsL := tls.NewListener(l, &tls.Config{ 92 NextProtos: []string{"http/1.1"}, 93 Certificates: []tls.Certificate{myCert}, 94 }) 95 go func() { 96 conn, err := tlsL.Accept() 97 c.Assert(err, IsNil) 98 defer conn.Close() 99 _, err = conn.Write([]byte("test")) 100 c.Assert(err, IsNil) 101 }() 102 addr := tlsL.Addr().String() 103 return addr, l 104 } 105 106 func (t *FVTests) TestDialTLSReject(c *C) { 107 addr, l := t.setupTLSServer(c) 108 defer l.Close() 109 fpv := &FingerprintVerifier{} 110 _, err := fpv.DialTLS("tcp", addr) 111 c.Assert(err, Equals, ErrFingerprintRejected) 112 } 113 114 func (t *FVTests) TestDialTLSAccept(c *C) { 115 addr, l := t.setupTLSServer(c) 116 defer l.Close() 117 fpv := &FingerprintVerifier{AcceptFingerprint: testCertFp} 118 conn, err := fpv.DialTLS("tcp", addr) 119 c.Assert(err, IsNil) 120 r, err := ioutil.ReadAll(conn) 121 c.Assert(err, IsNil) 122 c.Assert(r, DeepEquals, []byte("test")) 123 } 124 125 const testCertFp = "9f79df7d821ea16d89c09e026074e81f89540aa7fbfda1b0b3f5ba7dcab88d71b944a49bb0c8a5c8abf42308d8ae060bf7437831e7a5f21b3c7718f04578680b" 126 127 func (t *FVTests) makeTestCert(c *C) (*x509.Certificate, []byte, *ecdsa.PrivateKey) { 128 entropy := bytes.NewBufferString("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") 129 priv, err := ecdsa.GenerateKey(elliptic.P521(), entropy) 130 c.Assert(err, IsNil) 131 132 template := x509.Certificate{ 133 SerialNumber: big.NewInt(1), 134 } 135 136 derBytes, err := x509.CreateCertificate(entropy, &template, &template, 137 &priv.PublicKey, priv) 138 c.Assert(err, IsNil) 139 cert, err := x509.ParseCertificate(derBytes) 140 c.Assert(err, IsNil) 141 return cert, derBytes, priv 142 } 143 144 func (t *FVTests) TestNoConnection(c *C) { 145 fpv := &FingerprintVerifier{AcceptFingerprint: testCertFp} 146 _, err := fpv.DialTLS("tcp", "127.0.0.1:55543") 147 c.Assert(err, NotNil) 148 } 149 150 func (t *FVTests) TestTimeout(c *C) { 151 addr, l := t.setupTLSServer(c) 152 defer l.Close() 153 fpv := &FingerprintVerifier{AcceptFingerprint: testCertFp} 154 _, err := fpv.dialTLS("tcp", addr, 0*time.Minute) 155 c.Assert(err, NotNil) 156 157 c.Assert(err, FitsTypeOf, handshakeTimeoutError{}) 158 timeoutError := err.(handshakeTimeoutError) 159 c.Check(len(timeoutError.Error()) > 1, Equals, true) 160 c.Check(timeoutError.Temporary(), Equals, true) 161 c.Check(timeoutError.Timeout(), Equals, true) 162 }