github.com/maier/nomad@v0.4.1-0.20161110003312-a9e3d0b8549d/helper/tlsutil/config_test.go (about) 1 package tlsutil 2 3 import ( 4 "crypto/tls" 5 "crypto/x509" 6 "io" 7 "io/ioutil" 8 "net" 9 "testing" 10 11 "github.com/hashicorp/yamux" 12 ) 13 14 func TestConfig_AppendCA_None(t *testing.T) { 15 conf := &Config{} 16 pool := x509.NewCertPool() 17 err := conf.AppendCA(pool) 18 if err != nil { 19 t.Fatalf("err: %v", err) 20 } 21 if len(pool.Subjects()) != 0 { 22 t.Fatalf("bad: %v", pool.Subjects()) 23 } 24 } 25 26 func TestConfig_CACertificate_Valid(t *testing.T) { 27 conf := &Config{ 28 CAFile: "./test/ca/root.cer", 29 } 30 pool := x509.NewCertPool() 31 err := conf.AppendCA(pool) 32 if err != nil { 33 t.Fatalf("err: %v", err) 34 } 35 if len(pool.Subjects()) == 0 { 36 t.Fatalf("expected cert") 37 } 38 } 39 40 func TestConfig_KeyPair_None(t *testing.T) { 41 conf := &Config{} 42 cert, err := conf.KeyPair() 43 if err != nil { 44 t.Fatalf("err: %v", err) 45 } 46 if cert != nil { 47 t.Fatalf("bad: %v", cert) 48 } 49 } 50 51 func TestConfig_KeyPair_Valid(t *testing.T) { 52 conf := &Config{ 53 CertFile: "./test/key/ourdomain.cer", 54 KeyFile: "./test/key/ourdomain.key", 55 } 56 cert, err := conf.KeyPair() 57 if err != nil { 58 t.Fatalf("err: %v", err) 59 } 60 if cert == nil { 61 t.Fatalf("expected cert") 62 } 63 } 64 65 func TestConfig_OutgoingTLS_MissingCA(t *testing.T) { 66 conf := &Config{ 67 VerifyOutgoing: true, 68 } 69 tls, err := conf.OutgoingTLSConfig() 70 if err == nil { 71 t.Fatalf("expected err") 72 } 73 if tls != nil { 74 t.Fatalf("bad: %v", tls) 75 } 76 } 77 78 func TestConfig_OutgoingTLS_OnlyCA(t *testing.T) { 79 conf := &Config{ 80 CAFile: "./test/ca/root.cer", 81 } 82 tls, err := conf.OutgoingTLSConfig() 83 if err != nil { 84 t.Fatalf("err: %v", err) 85 } 86 if tls != nil { 87 t.Fatalf("expected no config") 88 } 89 } 90 91 func TestConfig_OutgoingTLS_VerifyOutgoing(t *testing.T) { 92 conf := &Config{ 93 VerifyOutgoing: true, 94 CAFile: "./test/ca/root.cer", 95 } 96 tls, err := conf.OutgoingTLSConfig() 97 if err != nil { 98 t.Fatalf("err: %v", err) 99 } 100 if tls == nil { 101 t.Fatalf("expected config") 102 } 103 if len(tls.RootCAs.Subjects()) != 1 { 104 t.Fatalf("expect root cert") 105 } 106 if tls.ServerName != "" { 107 t.Fatalf("expect no server name verification") 108 } 109 if !tls.InsecureSkipVerify { 110 t.Fatalf("should skip built-in verification") 111 } 112 } 113 114 func TestConfig_OutgoingTLS_ServerName(t *testing.T) { 115 conf := &Config{ 116 VerifyOutgoing: true, 117 CAFile: "./test/ca/root.cer", 118 ServerName: "consul.example.com", 119 } 120 tls, err := conf.OutgoingTLSConfig() 121 if err != nil { 122 t.Fatalf("err: %v", err) 123 } 124 if tls == nil { 125 t.Fatalf("expected config") 126 } 127 if len(tls.RootCAs.Subjects()) != 1 { 128 t.Fatalf("expect root cert") 129 } 130 if tls.ServerName != "consul.example.com" { 131 t.Fatalf("expect server name") 132 } 133 if tls.InsecureSkipVerify { 134 t.Fatalf("should not skip built-in verification") 135 } 136 } 137 138 func TestConfig_OutgoingTLS_VerifyHostname(t *testing.T) { 139 conf := &Config{ 140 VerifyServerHostname: true, 141 CAFile: "./test/ca/root.cer", 142 ServerName: "foo", 143 } 144 tls, err := conf.OutgoingTLSConfig() 145 if err != nil { 146 t.Fatalf("err: %v", err) 147 } 148 if tls == nil { 149 t.Fatalf("expected config") 150 } 151 if len(tls.RootCAs.Subjects()) != 1 { 152 t.Fatalf("expect root cert") 153 } 154 if tls.ServerName != "foo" { 155 t.Fatalf("expect server name") 156 } 157 if tls.InsecureSkipVerify { 158 t.Fatalf("should not skip built-in verification") 159 } 160 } 161 162 func TestConfig_OutgoingTLS_WithKeyPair(t *testing.T) { 163 conf := &Config{ 164 VerifyOutgoing: true, 165 CAFile: "./test/ca/root.cer", 166 CertFile: "./test/key/ourdomain.cer", 167 KeyFile: "./test/key/ourdomain.key", 168 } 169 tls, err := conf.OutgoingTLSConfig() 170 if err != nil { 171 t.Fatalf("err: %v", err) 172 } 173 if tls == nil { 174 t.Fatalf("expected config") 175 } 176 if len(tls.RootCAs.Subjects()) != 1 { 177 t.Fatalf("expect root cert") 178 } 179 if !tls.InsecureSkipVerify { 180 t.Fatalf("should skip verification") 181 } 182 if len(tls.Certificates) != 1 { 183 t.Fatalf("expected client cert") 184 } 185 } 186 187 func startTLSServer(config *Config) (net.Conn, chan error) { 188 errc := make(chan error, 1) 189 190 tlsConfigServer, err := config.IncomingTLSConfig() 191 if err != nil { 192 errc <- err 193 return nil, errc 194 } 195 196 client, server := net.Pipe() 197 198 // Use yamux to buffer the reads, otherwise it's easy to deadlock 199 muxConf := yamux.DefaultConfig() 200 serverSession, _ := yamux.Server(server, muxConf) 201 clientSession, _ := yamux.Client(client, muxConf) 202 clientConn, _ := clientSession.Open() 203 serverConn, _ := serverSession.Accept() 204 205 go func() { 206 tlsServer := tls.Server(serverConn, tlsConfigServer) 207 if err := tlsServer.Handshake(); err != nil { 208 errc <- err 209 } 210 close(errc) 211 // Because net.Pipe() is unbuffered, if both sides 212 // Close() simultaneously, we will deadlock as they 213 // both send an alert and then block. So we make the 214 // server read any data from the client until error or 215 // EOF, which will allow the client to Close(), and 216 // *then* we Close() the server. 217 io.Copy(ioutil.Discard, tlsServer) 218 tlsServer.Close() 219 }() 220 return clientConn, errc 221 } 222 223 func TestConfig_outgoingWrapper_OK(t *testing.T) { 224 config := &Config{ 225 CAFile: "./test/hostname/CertAuth.crt", 226 CertFile: "./test/hostname/Alice.crt", 227 KeyFile: "./test/hostname/Alice.key", 228 VerifyServerHostname: true, 229 VerifyOutgoing: true, 230 ServerName: "server.dc1.consul", 231 } 232 233 client, errc := startTLSServer(config) 234 if client == nil { 235 t.Fatalf("startTLSServer err: %v", <-errc) 236 } 237 238 wrap, err := config.OutgoingTLSWrapper() 239 if err != nil { 240 t.Fatalf("OutgoingTLSWrapper err: %v", err) 241 } 242 243 tlsClient, err := wrap(client) 244 if err != nil { 245 t.Fatalf("wrapTLS err: %v", err) 246 } 247 defer tlsClient.Close() 248 if err := tlsClient.(*tls.Conn).Handshake(); err != nil { 249 t.Fatalf("write err: %v", err) 250 } 251 252 err = <-errc 253 if err != nil { 254 t.Fatalf("server: %v", err) 255 } 256 } 257 258 func TestConfig_outgoingWrapper_BadCert(t *testing.T) { 259 // TODO this test is currently hanging, need to investigate more. 260 t.SkipNow() 261 config := &Config{ 262 CAFile: "./test/ca/root.cer", 263 CertFile: "./test/key/ourdomain.cer", 264 KeyFile: "./test/key/ourdomain.key", 265 ServerName: "foo", 266 VerifyServerHostname: true, 267 VerifyOutgoing: true, 268 } 269 270 client, errc := startTLSServer(config) 271 if client == nil { 272 t.Fatalf("startTLSServer err: %v", <-errc) 273 } 274 275 wrap, err := config.OutgoingTLSWrapper() 276 if err != nil { 277 t.Fatalf("OutgoingTLSWrapper err: %v", err) 278 } 279 280 tlsClient, err := wrap(client) 281 if err != nil { 282 t.Fatalf("wrapTLS err: %v", err) 283 } 284 defer tlsClient.Close() 285 err = tlsClient.(*tls.Conn).Handshake() 286 287 if _, ok := err.(x509.HostnameError); !ok { 288 t.Fatalf("should get hostname err: %v", err) 289 } 290 291 <-errc 292 } 293 294 func TestConfig_wrapTLS_OK(t *testing.T) { 295 config := &Config{ 296 CAFile: "./test/ca/root.cer", 297 CertFile: "./test/key/ourdomain.cer", 298 KeyFile: "./test/key/ourdomain.key", 299 VerifyOutgoing: true, 300 } 301 302 client, errc := startTLSServer(config) 303 if client == nil { 304 t.Fatalf("startTLSServer err: %v", <-errc) 305 } 306 307 clientConfig, err := config.OutgoingTLSConfig() 308 if err != nil { 309 t.Fatalf("OutgoingTLSConfig err: %v", err) 310 } 311 312 tlsClient, err := WrapTLSClient(client, clientConfig) 313 if err != nil { 314 t.Fatalf("wrapTLS err: %v", err) 315 } else { 316 tlsClient.Close() 317 } 318 err = <-errc 319 if err != nil { 320 t.Fatalf("server: %v", err) 321 } 322 } 323 324 func TestConfig_wrapTLS_BadCert(t *testing.T) { 325 serverConfig := &Config{ 326 CertFile: "./test/key/ssl-cert-snakeoil.pem", 327 KeyFile: "./test/key/ssl-cert-snakeoil.key", 328 } 329 330 client, errc := startTLSServer(serverConfig) 331 if client == nil { 332 t.Fatalf("startTLSServer err: %v", <-errc) 333 } 334 335 clientConfig := &Config{ 336 CAFile: "./test/ca/root.cer", 337 VerifyOutgoing: true, 338 } 339 340 clientTLSConfig, err := clientConfig.OutgoingTLSConfig() 341 if err != nil { 342 t.Fatalf("OutgoingTLSConfig err: %v", err) 343 } 344 345 tlsClient, err := WrapTLSClient(client, clientTLSConfig) 346 if err == nil { 347 t.Fatalf("wrapTLS no err") 348 } 349 if tlsClient != nil { 350 t.Fatalf("returned a client") 351 } 352 353 err = <-errc 354 if err != nil { 355 t.Fatalf("server: %v", err) 356 } 357 } 358 359 func TestConfig_IncomingTLS(t *testing.T) { 360 conf := &Config{ 361 VerifyIncoming: true, 362 CAFile: "./test/ca/root.cer", 363 CertFile: "./test/key/ourdomain.cer", 364 KeyFile: "./test/key/ourdomain.key", 365 } 366 tlsC, err := conf.IncomingTLSConfig() 367 if err != nil { 368 t.Fatalf("err: %v", err) 369 } 370 if tlsC == nil { 371 t.Fatalf("expected config") 372 } 373 if len(tlsC.ClientCAs.Subjects()) != 1 { 374 t.Fatalf("expect client cert") 375 } 376 if tlsC.ClientAuth != tls.RequireAndVerifyClientCert { 377 t.Fatalf("should not skip verification") 378 } 379 if len(tlsC.Certificates) != 1 { 380 t.Fatalf("expected client cert") 381 } 382 } 383 384 func TestConfig_IncomingTLS_MissingCA(t *testing.T) { 385 conf := &Config{ 386 VerifyIncoming: true, 387 CertFile: "./test/key/ourdomain.cer", 388 KeyFile: "./test/key/ourdomain.key", 389 } 390 _, err := conf.IncomingTLSConfig() 391 if err == nil { 392 t.Fatalf("expected err") 393 } 394 } 395 396 func TestConfig_IncomingTLS_MissingKey(t *testing.T) { 397 conf := &Config{ 398 VerifyIncoming: true, 399 CAFile: "./test/ca/root.cer", 400 } 401 _, err := conf.IncomingTLSConfig() 402 if err == nil { 403 t.Fatalf("expected err") 404 } 405 } 406 407 func TestConfig_IncomingTLS_NoVerify(t *testing.T) { 408 conf := &Config{} 409 tlsC, err := conf.IncomingTLSConfig() 410 if err != nil { 411 t.Fatalf("err: %v", err) 412 } 413 if tlsC == nil { 414 t.Fatalf("expected config") 415 } 416 if len(tlsC.ClientCAs.Subjects()) != 0 { 417 t.Fatalf("do not expect client cert") 418 } 419 if tlsC.ClientAuth != tls.NoClientCert { 420 t.Fatalf("should skip verification") 421 } 422 if len(tlsC.Certificates) != 0 { 423 t.Fatalf("unexpected client cert") 424 } 425 }