get.pme.sh/pnats@v0.0.0-20240304004023-26bb5a137ed0/test/ocsp_test.go (about) 1 // Copyright 2021-2023 The NATS Authors 2 // Licensed under the Apache License, Version 2.0 (the "License"); 3 // you may not use this file except in compliance with the License. 4 // You may obtain a copy of the License at 5 // 6 // http://www.apache.org/licenses/LICENSE-2.0 7 // 8 // Unless required by applicable law or agreed to in writing, software 9 // distributed under the License is distributed on an "AS IS" BASIS, 10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 package test 15 16 import ( 17 "bytes" 18 "context" 19 "crypto" 20 "crypto/tls" 21 "crypto/x509" 22 "encoding/base64" 23 "encoding/pem" 24 "fmt" 25 "io" 26 "net/http" 27 "os" 28 "path/filepath" 29 "strconv" 30 "strings" 31 "sync" 32 "testing" 33 "time" 34 35 "golang.org/x/crypto/ocsp" 36 37 "get.pme.sh/pnats/server" 38 "github.com/nats-io/nats.go" 39 ) 40 41 const ( 42 defaultResponseTTL = 4 * time.Second 43 defaultAddress = "127.0.0.1:8888" 44 ) 45 46 func TestOCSPAlwaysMustStapleAndShutdown(t *testing.T) { 47 // Certs that have must staple will auto shutdown the server. 48 const ( 49 caCert = "configs/certs/ocsp/ca-cert.pem" 50 caKey = "configs/certs/ocsp/ca-key.pem" 51 serverCert = "configs/certs/ocsp/server-cert.pem" 52 serverKey = "configs/certs/ocsp/server-key.pem" 53 ) 54 55 ctx, cancel := context.WithCancel(context.Background()) 56 defer cancel() 57 ocspr := newOCSPResponder(t, caCert, caKey) 58 defer ocspr.Shutdown(ctx) 59 addr := fmt.Sprintf("http://%s", ocspr.Addr) 60 setOCSPStatus(t, addr, serverCert, ocsp.Good) 61 62 opts := server.Options{} 63 opts.Host = "127.0.0.1" 64 opts.NoLog = true 65 opts.NoSigs = true 66 opts.MaxControlLine = 4096 67 opts.Port = -1 68 opts.TLSCert = serverCert 69 opts.TLSKey = serverKey 70 opts.TLSCaCert = caCert 71 opts.TLSTimeout = 5 72 tcOpts := &server.TLSConfigOpts{ 73 CertFile: opts.TLSCert, 74 KeyFile: opts.TLSKey, 75 CaFile: opts.TLSCaCert, 76 Timeout: opts.TLSTimeout, 77 } 78 79 tlsConf, err := server.GenTLSConfig(tcOpts) 80 if err != nil { 81 t.Fatal(err) 82 } 83 opts.TLSConfig = tlsConf 84 85 opts.OCSPConfig = &server.OCSPConfig{ 86 Mode: server.OCSPModeAlways, 87 OverrideURLs: []string{addr}, 88 } 89 srv := RunServer(&opts) 90 defer srv.Shutdown() 91 92 nc, err := nats.Connect(fmt.Sprintf("tls://localhost:%d", opts.Port), 93 nats.Secure(&tls.Config{ 94 VerifyConnection: func(s tls.ConnectionState) error { 95 resp, err := getOCSPStatus(s) 96 if err != nil { 97 return err 98 } 99 if resp.Status != ocsp.Good { 100 return fmt.Errorf("invalid staple") 101 } 102 return nil 103 }, 104 }), 105 nats.RootCAs(caCert), 106 nats.ErrorHandler(noOpErrHandler), 107 ) 108 if err != nil { 109 t.Fatal(err) 110 } 111 defer nc.Close() 112 sub, err := nc.SubscribeSync("foo") 113 if err != nil { 114 t.Fatal(err) 115 } 116 nc.Publish("foo", []byte("hello world")) 117 nc.Flush() 118 119 _, err = sub.NextMsg(1 * time.Second) 120 if err != nil { 121 t.Fatal(err) 122 } 123 nc.Close() 124 125 // The server will shutdown because the server becomes revoked 126 // and the policy is to always must-staple. The OCSP Responder 127 // instructs the NATS Server to fetch OCSP Staples every 2 seconds. 128 time.Sleep(2 * time.Second) 129 setOCSPStatus(t, addr, serverCert, ocsp.Revoked) 130 time.Sleep(2 * time.Second) 131 132 // Should be connection refused since server will abort now. 133 _, err = nats.Connect(fmt.Sprintf("tls://localhost:%d", opts.Port), 134 nats.RootCAs(caCert), 135 nats.ErrorHandler(noOpErrHandler), 136 ) 137 if err != nats.ErrNoServers { 138 t.Errorf("Expected connection refused") 139 } 140 // Verify that the server finishes shutdown 141 srv.WaitForShutdown() 142 } 143 144 func TestOCSPMustStapleShutdown(t *testing.T) { 145 const ( 146 caCert = "configs/certs/ocsp/ca-cert.pem" 147 caKey = "configs/certs/ocsp/ca-key.pem" 148 serverCert = "configs/certs/ocsp/server-status-request-cert.pem" 149 serverKey = "configs/certs/ocsp/server-status-request-key.pem" 150 ) 151 152 ctx, cancel := context.WithCancel(context.Background()) 153 defer cancel() 154 ocspr := newOCSPResponder(t, caCert, caKey) 155 defer ocspr.Shutdown(ctx) 156 addr := fmt.Sprintf("http://%s", ocspr.Addr) 157 setOCSPStatus(t, addr, serverCert, ocsp.Good) 158 159 opts := server.Options{} 160 opts.Host = "127.0.0.1" 161 opts.NoLog = true 162 opts.NoSigs = true 163 opts.MaxControlLine = 4096 164 opts.Port = -1 165 opts.TLSCert = serverCert 166 opts.TLSKey = serverKey 167 opts.TLSCaCert = caCert 168 opts.TLSTimeout = 5 169 tlsConfigOpts := &server.TLSConfigOpts{ 170 CertFile: opts.TLSCert, 171 KeyFile: opts.TLSKey, 172 CaFile: opts.TLSCaCert, 173 Timeout: opts.TLSTimeout, 174 } 175 176 tlsConf, err := server.GenTLSConfig(tlsConfigOpts) 177 if err != nil { 178 t.Fatal(err) 179 } 180 opts.TLSConfig = tlsConf 181 182 opts.OCSPConfig = &server.OCSPConfig{ 183 Mode: server.OCSPModeMust, 184 OverrideURLs: []string{addr}, 185 } 186 187 srv := RunServer(&opts) 188 defer srv.Shutdown() 189 190 nc, err := nats.Connect(fmt.Sprintf("tls://localhost:%d", opts.Port), 191 nats.Secure(&tls.Config{ 192 VerifyConnection: func(s tls.ConnectionState) error { 193 resp, err := getOCSPStatus(s) 194 if err != nil { 195 return err 196 } 197 if resp.Status != ocsp.Good { 198 return fmt.Errorf("invalid staple") 199 } 200 return nil 201 }, 202 }), 203 nats.RootCAs(caCert), 204 nats.ErrorHandler(noOpErrHandler), 205 ) 206 if err != nil { 207 t.Fatal(err) 208 } 209 defer nc.Close() 210 sub, err := nc.SubscribeSync("foo") 211 if err != nil { 212 t.Fatal(err) 213 } 214 nc.Publish("foo", []byte("hello world")) 215 nc.Flush() 216 217 _, err = sub.NextMsg(1 * time.Second) 218 if err != nil { 219 t.Fatal(err) 220 } 221 nc.Close() 222 223 // The server will shutdown because the server becomes revoked 224 // and the policy is to always must-staple. The OCSP Responder 225 // instructs the NATS Server to fetch OCSP Staples every 2 seconds. 226 time.Sleep(2 * time.Second) 227 setOCSPStatus(t, addr, serverCert, ocsp.Revoked) 228 time.Sleep(2 * time.Second) 229 230 // Should be connection refused since server will abort now. 231 _, err = nats.Connect(fmt.Sprintf("tls://localhost:%d", opts.Port), 232 nats.RootCAs(caCert), 233 nats.ErrorHandler(noOpErrHandler), 234 ) 235 if err != nats.ErrNoServers { 236 t.Errorf("Expected connection refused") 237 } 238 } 239 240 func TestOCSPMustStapleAutoDoesNotShutdown(t *testing.T) { 241 const ( 242 caCert = "configs/certs/ocsp/ca-cert.pem" 243 caKey = "configs/certs/ocsp/ca-key.pem" 244 serverCert = "configs/certs/ocsp/server-status-request-url-01-cert.pem" 245 ) 246 ctx, cancel := context.WithCancel(context.Background()) 247 defer cancel() 248 ocspr := newOCSPResponder(t, caCert, caKey) 249 defer ocspr.Shutdown(ctx) 250 addr := fmt.Sprintf("http://%s", ocspr.Addr) 251 setOCSPStatus(t, addr, serverCert, ocsp.Good) 252 253 content := ` 254 port: -1 255 256 tls { 257 cert_file: "configs/certs/ocsp/server-status-request-url-01-cert.pem" 258 key_file: "configs/certs/ocsp/server-status-request-url-01-key.pem" 259 ca_file: "configs/certs/ocsp/ca-cert.pem" 260 timeout: 5 261 } 262 ` 263 conf := createConfFile(t, []byte(content)) 264 s, opts := RunServerWithConfig(conf) 265 defer s.Shutdown() 266 267 nc, err := nats.Connect(fmt.Sprintf("tls://localhost:%d", opts.Port), 268 nats.Secure(&tls.Config{ 269 VerifyConnection: func(s tls.ConnectionState) error { 270 resp, err := getOCSPStatus(s) 271 if err != nil { 272 return err 273 } 274 if resp.Status != ocsp.Good { 275 t.Errorf("Expected valid OCSP staple status") 276 } 277 return nil 278 }, 279 }), 280 nats.RootCAs(caCert), 281 nats.ErrorHandler(noOpErrHandler), 282 ) 283 if err != nil { 284 t.Fatal(err) 285 } 286 defer nc.Close() 287 sub, err := nc.SubscribeSync("foo") 288 if err != nil { 289 t.Fatal(err) 290 } 291 nc.Publish("foo", []byte("hello world")) 292 nc.Flush() 293 294 _, err = sub.NextMsg(1 * time.Second) 295 if err != nil { 296 t.Fatal(err) 297 } 298 nc.Close() 299 300 // The server will shutdown because the server becomes revoked 301 // and the policy is to always must-staple. The OCSP Responder 302 // instructs the NATS Server to fetch OCSP Staples every 2 seconds. 303 time.Sleep(2 * time.Second) 304 setOCSPStatus(t, addr, serverCert, ocsp.Revoked) 305 time.Sleep(2 * time.Second) 306 307 // Should not be connection refused, the client will continue running and 308 // be served the stale OCSP staple instead. 309 nc, err = nats.Connect(fmt.Sprintf("tls://localhost:%d", opts.Port), 310 nats.Secure(&tls.Config{ 311 VerifyConnection: func(s tls.ConnectionState) error { 312 resp, err := getOCSPStatus(s) 313 if err != nil { 314 return err 315 } 316 if resp.Status != ocsp.Revoked { 317 t.Errorf("Expected revoked status") 318 } 319 return nil 320 }, 321 }), 322 nats.RootCAs(caCert), 323 nats.ErrorHandler(noOpErrHandler), 324 ) 325 if err != nil { 326 t.Fatal(err) 327 } 328 nc.Close() 329 } 330 331 func TestOCSPAutoWithoutMustStapleDoesNotShutdownOnRevoke(t *testing.T) { 332 const ( 333 caCert = "configs/certs/ocsp/ca-cert.pem" 334 caKey = "configs/certs/ocsp/ca-key.pem" 335 serverCert = "configs/certs/ocsp/server-cert.pem" 336 serverKey = "configs/certs/ocsp/server-key.pem" 337 ) 338 339 ctx, cancel := context.WithCancel(context.Background()) 340 defer cancel() 341 ocspr := newOCSPResponder(t, caCert, caKey) 342 defer ocspr.Shutdown(ctx) 343 addr := fmt.Sprintf("http://%s", ocspr.Addr) 344 setOCSPStatus(t, addr, serverCert, ocsp.Good) 345 346 opts := server.Options{} 347 opts.Host = "127.0.0.1" 348 opts.NoLog = true 349 opts.NoSigs = true 350 opts.MaxControlLine = 4096 351 opts.Port = -1 352 opts.TLSCert = serverCert 353 opts.TLSKey = serverKey 354 opts.TLSCaCert = caCert 355 opts.TLSTimeout = 5 356 tlsConfigOpts := &server.TLSConfigOpts{ 357 CertFile: opts.TLSCert, 358 KeyFile: opts.TLSKey, 359 CaFile: opts.TLSCaCert, 360 Timeout: opts.TLSTimeout, 361 } 362 tlsConf, err := server.GenTLSConfig(tlsConfigOpts) 363 if err != nil { 364 t.Fatal(err) 365 } 366 opts.TLSConfig = tlsConf 367 368 opts.OCSPConfig = &server.OCSPConfig{ 369 Mode: server.OCSPModeAuto, 370 OverrideURLs: []string{addr}, 371 } 372 373 srv := RunServer(&opts) 374 defer srv.Shutdown() 375 376 nc, err := nats.Connect(fmt.Sprintf("tls://localhost:%d", opts.Port), 377 nats.Secure(&tls.Config{ 378 VerifyConnection: func(s tls.ConnectionState) error { 379 if s.OCSPResponse != nil { 380 return fmt.Errorf("Unexpected OCSP staple for certificate") 381 } 382 return nil 383 }, 384 }), 385 386 nats.RootCAs(caCert), 387 nats.ErrorHandler(noOpErrHandler), 388 ) 389 if err != nil { 390 t.Fatal(err) 391 } 392 defer nc.Close() 393 sub, err := nc.SubscribeSync("foo") 394 if err != nil { 395 t.Fatal(err) 396 } 397 nc.Publish("foo", []byte("hello world")) 398 nc.Flush() 399 400 _, err = sub.NextMsg(1 * time.Second) 401 if err != nil { 402 t.Fatal(err) 403 } 404 nc.Close() 405 406 // Revoke the client certificate, nothing will happens since does 407 // not have MustStaple. 408 time.Sleep(2 * time.Second) 409 setOCSPStatus(t, addr, serverCert, ocsp.Revoked) 410 time.Sleep(2 * time.Second) 411 412 // Should not be connection refused since server will continue running. 413 nc, err = nats.Connect(fmt.Sprintf("tls://localhost:%d", opts.Port), 414 nats.RootCAs(caCert), 415 nats.ErrorHandler(noOpErrHandler), 416 ) 417 if err != nil { 418 t.Errorf("Unexpected error: %s", err) 419 } 420 nc.Close() 421 } 422 423 func TestOCSPClient(t *testing.T) { 424 const ( 425 caCert = "configs/certs/ocsp/ca-cert.pem" 426 caKey = "configs/certs/ocsp/ca-key.pem" 427 serverCert = "configs/certs/ocsp/server-cert.pem" 428 serverKey = "configs/certs/ocsp/server-key.pem" 429 ) 430 431 ctx, cancel := context.WithCancel(context.Background()) 432 defer cancel() 433 ocspr := newOCSPResponder(t, caCert, caKey) 434 ocspURL := fmt.Sprintf("http://%s", ocspr.Addr) 435 defer ocspr.Shutdown(ctx) 436 437 for _, test := range []struct { 438 name string 439 config string 440 opts []nats.Option 441 err error 442 rerr error 443 configure func() 444 }{ 445 { 446 "OCSP Stapling makes server fail to boot if status is unknown", 447 ` 448 port: -1 449 450 # Enable OCSP stapling with policy to honor must staple if present. 451 ocsp: true 452 453 tls { 454 cert_file: "configs/certs/ocsp/server-cert.pem" 455 key_file: "configs/certs/ocsp/server-key.pem" 456 ca_file: "configs/certs/ocsp/ca-cert.pem" 457 timeout: 5 458 } 459 `, 460 []nats.Option{ 461 nats.ClientCert("./configs/certs/ocsp/client-cert.pem", "./configs/certs/ocsp/client-key.pem"), 462 nats.RootCAs(caCert), 463 nats.ErrorHandler(noOpErrHandler), 464 }, 465 nil, 466 nil, 467 func() {}, 468 }, 469 { 470 "OCSP Stapling ignored by default if server without must staple status", 471 ` 472 port: -1 473 474 ocsp: true 475 476 tls { 477 cert_file: "configs/certs/ocsp/server-cert.pem" 478 key_file: "configs/certs/ocsp/server-key.pem" 479 ca_file: "configs/certs/ocsp/ca-cert.pem" 480 timeout: 5 481 } 482 `, 483 []nats.Option{ 484 nats.ClientCert("./configs/certs/ocsp/client-cert.pem", "./configs/certs/ocsp/client-key.pem"), 485 nats.RootCAs(caCert), 486 nats.ErrorHandler(noOpErrHandler), 487 }, 488 nil, 489 nil, 490 func() { setOCSPStatus(t, ocspURL, serverCert, ocsp.Good) }, 491 }, 492 { 493 "OCSP Stapling honored by default if server has must staple status", 494 ` 495 port: -1 496 497 tls { 498 cert_file: "configs/certs/ocsp/server-status-request-url-01-cert.pem" 499 key_file: "configs/certs/ocsp/server-status-request-url-01-key.pem" 500 ca_file: "configs/certs/ocsp/ca-cert.pem" 501 timeout: 5 502 } 503 `, 504 []nats.Option{ 505 nats.ClientCert("./configs/certs/ocsp/client-cert.pem", "./configs/certs/ocsp/client-key.pem"), 506 nats.RootCAs(caCert), 507 nats.ErrorHandler(noOpErrHandler), 508 }, 509 nil, 510 nil, 511 func() { 512 setOCSPStatus(t, ocspURL, "configs/certs/ocsp/server-status-request-url-01-cert.pem", ocsp.Good) 513 }, 514 }, 515 { 516 "OCSP Stapling can be disabled even if server has must staple status", 517 ` 518 port: -1 519 520 ocsp: false 521 522 tls { 523 cert_file: "configs/certs/ocsp/server-status-request-url-01-cert.pem" 524 key_file: "configs/certs/ocsp/server-status-request-url-01-key.pem" 525 ca_file: "configs/certs/ocsp/ca-cert.pem" 526 timeout: 5 527 } 528 `, 529 []nats.Option{ 530 nats.ClientCert("./configs/certs/ocsp/client-cert.pem", "./configs/certs/ocsp/client-key.pem"), 531 nats.RootCAs(caCert), 532 nats.ErrorHandler(noOpErrHandler), 533 }, 534 nil, 535 nil, 536 func() { 537 setOCSPStatus(t, ocspURL, "configs/certs/ocsp/server-status-request-url-01-cert.pem", ocsp.Revoked) 538 }, 539 }, 540 } { 541 t.Run(test.name, func(t *testing.T) { 542 test.configure() 543 content := test.config 544 conf := createConfFile(t, []byte(content)) 545 s, opts := RunServerWithConfig(conf) 546 defer s.Shutdown() 547 548 nc, err := nats.Connect(fmt.Sprintf("tls://localhost:%d", opts.Port), test.opts...) 549 if test.err == nil && err != nil { 550 t.Errorf("Expected to connect, got %v", err) 551 } else if test.err != nil && err == nil { 552 t.Errorf("Expected error on connect") 553 } else if test.err != nil && err != nil { 554 // Error on connect was expected 555 if test.err.Error() != err.Error() { 556 t.Errorf("Expected error %s, got: %s", test.err, err) 557 } 558 return 559 } 560 defer nc.Close() 561 562 nc.Subscribe("ping", func(m *nats.Msg) { 563 m.Respond([]byte("pong")) 564 }) 565 nc.Flush() 566 567 _, err = nc.Request("ping", []byte("ping"), 250*time.Millisecond) 568 if test.rerr != nil && err == nil { 569 t.Errorf("Expected error getting response") 570 } else if test.rerr == nil && err != nil { 571 t.Errorf("Expected response") 572 } 573 }) 574 } 575 } 576 577 func TestOCSPReloadRotateTLSCertWithNoURL(t *testing.T) { 578 const ( 579 caCert = "configs/certs/ocsp/ca-cert.pem" 580 caKey = "configs/certs/ocsp/ca-key.pem" 581 serverCert = "configs/certs/ocsp/server-status-request-url-01-cert.pem" 582 updatedServerCert = "configs/certs/ocsp/server-status-request-cert.pem" 583 ) 584 ctx, cancel := context.WithCancel(context.Background()) 585 defer cancel() 586 ocspr := newOCSPResponder(t, caCert, caKey) 587 defer ocspr.Shutdown(ctx) 588 addr := fmt.Sprintf("http://%s", ocspr.Addr) 589 setOCSPStatus(t, addr, serverCert, ocsp.Good) 590 591 content := ` 592 port: -1 593 594 tls { 595 cert_file: "configs/certs/ocsp/server-status-request-url-01-cert.pem" 596 key_file: "configs/certs/ocsp/server-status-request-url-01-key.pem" 597 ca_file: "configs/certs/ocsp/ca-cert.pem" 598 timeout: 5 599 } 600 ` 601 conf := createConfFile(t, []byte(content)) 602 s, opts := RunServerWithConfig(conf) 603 defer s.Shutdown() 604 605 nc, err := nats.Connect(fmt.Sprintf("tls://localhost:%d", opts.Port), 606 nats.Secure(&tls.Config{ 607 VerifyConnection: func(s tls.ConnectionState) error { 608 resp, err := getOCSPStatus(s) 609 if err != nil { 610 return err 611 } 612 if resp.Status != ocsp.Good { 613 t.Errorf("Expected valid OCSP staple status") 614 } 615 return nil 616 }, 617 }), 618 nats.RootCAs(caCert), 619 nats.ErrorHandler(noOpErrHandler), 620 ) 621 if err != nil { 622 t.Fatal(err) 623 } 624 defer nc.Close() 625 sub, err := nc.SubscribeSync("foo") 626 if err != nil { 627 t.Fatal(err) 628 } 629 nc.Publish("foo", []byte("hello world")) 630 nc.Flush() 631 632 _, err = sub.NextMsg(1 * time.Second) 633 if err != nil { 634 t.Fatal(err) 635 } 636 nc.Close() 637 638 // Change the contents with another that will fail to get a staple 639 // since it does not have an URL. 640 content = ` 641 port: -1 642 643 tls { 644 cert_file: "configs/certs/ocsp/server-status-request-cert.pem" 645 key_file: "configs/certs/ocsp/server-status-request-key.pem" 646 ca_file: "configs/certs/ocsp/ca-cert.pem" 647 timeout: 5 648 } 649 ` 650 if err := os.WriteFile(conf, []byte(content), 0666); err != nil { 651 t.Fatalf("Error writing config: %v", err) 652 } 653 // Reload show warning because of cert missing OCSP Url so cannot be used 654 // with OCSP stapling. 655 if err := s.Reload(); err != nil { 656 t.Fatal(err) 657 } 658 expectedErr := fmt.Errorf("missing OCSP response") 659 // The server will not shutdown because the reload will fail. 660 _, err = nats.Connect(fmt.Sprintf("tls://localhost:%d", opts.Port), 661 nats.Secure(&tls.Config{ 662 VerifyConnection: func(s tls.ConnectionState) error { 663 // The new certificate does not have OCSP Staples since 664 // it could not fetch one from a OCSP server. 665 if s.OCSPResponse == nil { 666 return expectedErr 667 } 668 return nil 669 }, 670 }), 671 nats.RootCAs(caCert), 672 nats.ErrorHandler(noOpErrHandler), 673 ) 674 if err != expectedErr { 675 t.Fatalf("Unexpected error: %s", expectedErr) 676 } 677 } 678 679 func TestOCSPReloadRotateTLSCertDisableMustStaple(t *testing.T) { 680 const ( 681 caCert = "configs/certs/ocsp/ca-cert.pem" 682 caKey = "configs/certs/ocsp/ca-key.pem" 683 serverCert = "configs/certs/ocsp/server-status-request-url-01-cert.pem" 684 updatedServerCert = "configs/certs/ocsp/server-status-request-cert.pem" 685 ) 686 ctx, cancel := context.WithCancel(context.Background()) 687 defer cancel() 688 ocspr := newOCSPResponder(t, caCert, caKey) 689 defer ocspr.Shutdown(ctx) 690 addr := fmt.Sprintf("http://%s", ocspr.Addr) 691 setOCSPStatus(t, addr, serverCert, ocsp.Good) 692 693 storeDir := t.TempDir() 694 695 originalContent := ` 696 port: -1 697 698 store_dir: '%s' 699 700 tls { 701 cert_file: "configs/certs/ocsp/server-status-request-url-01-cert.pem" 702 key_file: "configs/certs/ocsp/server-status-request-url-01-key.pem" 703 ca_file: "configs/certs/ocsp/ca-cert.pem" 704 timeout: 5 705 } 706 ` 707 708 content := fmt.Sprintf(originalContent, storeDir) 709 conf := createConfFile(t, []byte(content)) 710 s, opts := RunServerWithConfig(conf) 711 defer s.Shutdown() 712 713 var staple []byte 714 nc, err := nats.Connect(fmt.Sprintf("tls://localhost:%d", opts.Port), 715 nats.Secure(&tls.Config{ 716 VerifyConnection: func(s tls.ConnectionState) error { 717 staple = s.OCSPResponse 718 resp, err := getOCSPStatus(s) 719 if err != nil { 720 return err 721 } 722 if resp.Status != ocsp.Good { 723 t.Errorf("Expected valid OCSP staple status") 724 } 725 return nil 726 }, 727 }), 728 nats.RootCAs(caCert), 729 nats.ErrorHandler(noOpErrHandler), 730 ) 731 if err != nil { 732 t.Fatal(err) 733 } 734 defer nc.Close() 735 sub, err := nc.SubscribeSync("foo") 736 if err != nil { 737 t.Fatal(err) 738 } 739 nc.Publish("foo", []byte("hello world")) 740 nc.Flush() 741 742 _, err = sub.NextMsg(1 * time.Second) 743 if err != nil { 744 t.Fatal(err) 745 } 746 nc.Close() 747 748 files := []string{} 749 err = filepath.Walk(storeDir+"/ocsp/", func(path string, info os.FileInfo, err error) error { 750 if info.IsDir() { 751 return nil 752 } 753 files = append(files, path) 754 return nil 755 }) 756 if err != nil { 757 t.Fatal(err) 758 } 759 found := false 760 for _, file := range files { 761 data, err := os.ReadFile(file) 762 if err != nil { 763 t.Error(err) 764 } 765 if bytes.Equal(staple, data) { 766 found = true 767 } 768 } 769 if !found { 770 t.Error("Could not find OCSP Staple") 771 } 772 773 // Change the contents with another that has OCSP Stapling disabled. 774 updatedContent := ` 775 port: -1 776 777 store_dir: '%s' 778 779 tls { 780 cert_file: "configs/certs/ocsp/server-cert.pem" 781 key_file: "configs/certs/ocsp/server-key.pem" 782 ca_file: "configs/certs/ocsp/ca-cert.pem" 783 timeout: 5 784 } 785 ` 786 content = fmt.Sprintf(updatedContent, storeDir) 787 if err := os.WriteFile(conf, []byte(content), 0666); err != nil { 788 t.Fatalf("Error writing config: %v", err) 789 } 790 if err := s.Reload(); err != nil { 791 t.Fatal(err) 792 } 793 794 // The new certificate does not have must staple so they will be missing. 795 time.Sleep(4 * time.Second) 796 797 nc, err = nats.Connect(fmt.Sprintf("tls://localhost:%d", opts.Port), 798 nats.Secure(&tls.Config{ 799 VerifyConnection: func(s tls.ConnectionState) error { 800 if s.OCSPResponse != nil { 801 return fmt.Errorf("unexpected OCSP Staple!") 802 } 803 return nil 804 }, 805 }), 806 nats.RootCAs(caCert), 807 nats.ErrorHandler(noOpErrHandler), 808 ) 809 if err != nil { 810 t.Fatal(err) 811 } 812 nc.Close() 813 814 // Re-enable OCSP Stapling 815 content = fmt.Sprintf(originalContent, storeDir) 816 if err := os.WriteFile(conf, []byte(content), 0666); err != nil { 817 t.Fatalf("Error writing config: %v", err) 818 } 819 if err := s.Reload(); err != nil { 820 t.Fatal(err) 821 } 822 823 var newStaple []byte 824 nc, err = nats.Connect(fmt.Sprintf("tls://localhost:%d", opts.Port), 825 nats.Secure(&tls.Config{ 826 VerifyConnection: func(s tls.ConnectionState) error { 827 newStaple = s.OCSPResponse 828 resp, err := getOCSPStatus(s) 829 if err != nil { 830 return err 831 } 832 if resp.Status != ocsp.Good { 833 t.Errorf("Expected valid OCSP staple status") 834 } 835 return nil 836 }, 837 }), 838 nats.RootCAs(caCert), 839 nats.ErrorHandler(noOpErrHandler), 840 ) 841 if err != nil { 842 t.Fatal(err) 843 } 844 nc.Close() 845 846 // Confirm that it got a new staple. 847 files = []string{} 848 err = filepath.Walk(storeDir+"/ocsp/", func(path string, info os.FileInfo, err error) error { 849 if info.IsDir() { 850 return nil 851 } 852 files = append(files, path) 853 return nil 854 }) 855 if err != nil { 856 t.Fatal(err) 857 } 858 found = false 859 for _, file := range files { 860 data, err := os.ReadFile(file) 861 if err != nil { 862 t.Error(err) 863 } 864 if bytes.Equal(newStaple, data) { 865 found = true 866 } 867 } 868 if !found { 869 t.Error("Could not find OCSP Staple") 870 } 871 if bytes.Equal(staple, newStaple) { 872 t.Error("Expected new OCSP Staple") 873 } 874 } 875 876 func TestOCSPReloadRotateTLSCertEnableMustStaple(t *testing.T) { 877 const ( 878 caCert = "configs/certs/ocsp/ca-cert.pem" 879 caKey = "configs/certs/ocsp/ca-key.pem" 880 serverCert = "configs/certs/ocsp/server-cert.pem" 881 updatedServerCert = "configs/certs/ocsp/server-status-request-url-01-cert.pem" 882 ) 883 ctx, cancel := context.WithCancel(context.Background()) 884 defer cancel() 885 ocspr := newOCSPResponder(t, caCert, caKey) 886 defer ocspr.Shutdown(ctx) 887 addr := fmt.Sprintf("http://%s", ocspr.Addr) 888 setOCSPStatus(t, addr, serverCert, ocsp.Good) 889 setOCSPStatus(t, addr, updatedServerCert, ocsp.Good) 890 891 // Start without OCSP Stapling MustStaple 892 content := ` 893 port: -1 894 895 tls { 896 cert_file: "configs/certs/ocsp/server-cert.pem" 897 key_file: "configs/certs/ocsp/server-key.pem" 898 ca_file: "configs/certs/ocsp/ca-cert.pem" 899 timeout: 5 900 } 901 ` 902 conf := createConfFile(t, []byte(content)) 903 s, opts := RunServerWithConfig(conf) 904 defer s.Shutdown() 905 906 nc, err := nats.Connect(fmt.Sprintf("tls://localhost:%d", opts.Port), 907 nats.Secure(&tls.Config{ 908 VerifyConnection: func(s tls.ConnectionState) error { 909 if s.OCSPResponse != nil { 910 return fmt.Errorf("unexpected OCSP Staple!") 911 } 912 return nil 913 }, 914 }), 915 nats.RootCAs(caCert), 916 nats.ErrorHandler(noOpErrHandler), 917 ) 918 if err != nil { 919 t.Fatal(err) 920 } 921 defer nc.Close() 922 sub, err := nc.SubscribeSync("foo") 923 if err != nil { 924 t.Fatal(err) 925 } 926 nc.Publish("foo", []byte("hello world")) 927 nc.Flush() 928 929 _, err = sub.NextMsg(1 * time.Second) 930 if err != nil { 931 t.Fatal(err) 932 } 933 nc.Close() 934 935 // Change the contents with another that has OCSP Stapling enabled. 936 content = ` 937 port: -1 938 939 tls { 940 cert_file: "configs/certs/ocsp/server-status-request-url-01-cert.pem" 941 key_file: "configs/certs/ocsp/server-status-request-url-01-key.pem" 942 ca_file: "configs/certs/ocsp/ca-cert.pem" 943 timeout: 5 944 } 945 ` 946 if err := os.WriteFile(conf, []byte(content), 0666); err != nil { 947 t.Fatalf("Error writing config: %v", err) 948 } 949 if err := s.Reload(); err != nil { 950 t.Fatal(err) 951 } 952 953 // The new certificate does not have must staple so they will be missing. 954 time.Sleep(2 * time.Second) 955 956 nc, err = nats.Connect(fmt.Sprintf("tls://localhost:%d", opts.Port), 957 nats.Secure(&tls.Config{ 958 VerifyConnection: func(s tls.ConnectionState) error { 959 resp, err := getOCSPStatus(s) 960 if err != nil { 961 return err 962 } 963 if resp.Status != ocsp.Good { 964 t.Errorf("Expected valid OCSP staple status") 965 } 966 return nil 967 }, 968 }), 969 nats.RootCAs(caCert), 970 nats.ErrorHandler(noOpErrHandler), 971 ) 972 if err != nil { 973 t.Fatal(err) 974 } 975 nc.Close() 976 } 977 978 func TestOCSPCluster(t *testing.T) { 979 const ( 980 caCert = "configs/certs/ocsp/ca-cert.pem" 981 caKey = "configs/certs/ocsp/ca-key.pem" 982 ) 983 ctx, cancel := context.WithCancel(context.Background()) 984 defer cancel() 985 ocspr := newOCSPResponder(t, caCert, caKey) 986 defer ocspr.Shutdown(ctx) 987 addr := fmt.Sprintf("http://%s", ocspr.Addr) 988 setOCSPStatus(t, addr, "configs/certs/ocsp/server-status-request-url-01-cert.pem", ocsp.Good) 989 setOCSPStatus(t, addr, "configs/certs/ocsp/server-status-request-url-02-cert.pem", ocsp.Good) 990 setOCSPStatus(t, addr, "configs/certs/ocsp/server-status-request-url-03-cert.pem", ocsp.Good) 991 setOCSPStatus(t, addr, "configs/certs/ocsp/server-status-request-url-04-cert.pem", ocsp.Good) 992 setOCSPStatus(t, addr, "configs/certs/ocsp/server-status-request-url-05-cert.pem", ocsp.Good) 993 setOCSPStatus(t, addr, "configs/certs/ocsp/server-status-request-url-06-cert.pem", ocsp.Good) 994 setOCSPStatus(t, addr, "configs/certs/ocsp/server-status-request-url-07-cert.pem", ocsp.Good) 995 setOCSPStatus(t, addr, "configs/certs/ocsp/server-status-request-url-08-cert.pem", ocsp.Good) 996 997 // Store Dirs 998 storeDirA := t.TempDir() 999 storeDirB := t.TempDir() 1000 storeDirC := t.TempDir() 1001 1002 // Seed server configuration 1003 srvConfA := ` 1004 host: "127.0.0.1" 1005 port: -1 1006 1007 server_name: "AAA" 1008 1009 tls { 1010 cert_file: "configs/certs/ocsp/server-status-request-url-01-cert.pem" 1011 key_file: "configs/certs/ocsp/server-status-request-url-01-key.pem" 1012 ca_file: "configs/certs/ocsp/ca-cert.pem" 1013 timeout: 5 1014 } 1015 store_dir: '%s' 1016 cluster { 1017 name: AB 1018 host: "127.0.0.1" 1019 advertise: 127.0.0.1 1020 port: -1 1021 pool_size: -1 1022 1023 tls { 1024 cert_file: "configs/certs/ocsp/server-status-request-url-02-cert.pem" 1025 key_file: "configs/certs/ocsp/server-status-request-url-02-key.pem" 1026 ca_file: "configs/certs/ocsp/ca-cert.pem" 1027 timeout: 5 1028 } 1029 } 1030 ` 1031 srvConfA = fmt.Sprintf(srvConfA, storeDirA) 1032 sconfA := createConfFile(t, []byte(srvConfA)) 1033 srvA, optsA := RunServerWithConfig(sconfA) 1034 defer srvA.Shutdown() 1035 1036 // The rest 1037 srvConfB := ` 1038 host: "127.0.0.1" 1039 port: -1 1040 1041 server_name: "BBB" 1042 1043 tls { 1044 cert_file: "configs/certs/ocsp/server-status-request-url-03-cert.pem" 1045 key_file: "configs/certs/ocsp/server-status-request-url-03-key.pem" 1046 ca_file: "configs/certs/ocsp/ca-cert.pem" 1047 timeout: 5 1048 } 1049 store_dir: '%s' 1050 cluster { 1051 name: AB 1052 host: "127.0.0.1" 1053 advertise: 127.0.0.1 1054 port: -1 1055 pool_size: -1 1056 1057 routes: [ nats://127.0.0.1:%d ] 1058 connect_retries: 30 1059 1060 tls { 1061 cert_file: "configs/certs/ocsp/server-status-request-url-04-cert.pem" 1062 key_file: "configs/certs/ocsp/server-status-request-url-04-key.pem" 1063 ca_file: "configs/certs/ocsp/ca-cert.pem" 1064 timeout: 5 1065 } 1066 } 1067 ` 1068 srvConfB = fmt.Sprintf(srvConfB, storeDirB, optsA.Cluster.Port) 1069 conf := createConfFile(t, []byte(srvConfB)) 1070 srvB, optsB := RunServerWithConfig(conf) 1071 defer srvB.Shutdown() 1072 1073 // Client connects to server A. 1074 cA, err := nats.Connect(fmt.Sprintf("tls://localhost:%d", optsA.Port), 1075 nats.Secure(&tls.Config{ 1076 VerifyConnection: func(s tls.ConnectionState) error { 1077 if s.OCSPResponse == nil { 1078 return fmt.Errorf("missing OCSP Staple from server") 1079 } 1080 return nil 1081 }, 1082 }), 1083 nats.RootCAs(caCert), 1084 nats.ErrorHandler(noOpErrHandler), 1085 ) 1086 if err != nil { 1087 t.Fatal(err) 1088 } 1089 defer cA.Close() 1090 checkClusterFormed(t, srvA, srvB) 1091 1092 // Revoke the seed server cluster certificate, following servers will not be able to verify connection. 1093 setOCSPStatus(t, addr, "configs/certs/ocsp/server-status-request-url-02-cert.pem", ocsp.Revoked) 1094 1095 // Original set of servers still can communicate to each other, even though the cert has been revoked. 1096 // NOTE: Should we unplug from the cluster in case our server is revoke and OCSP policy is always or must? 1097 checkClusterFormed(t, srvA, srvB) 1098 1099 // Wait for seed server to notice that its certificate has been revoked, 1100 // so that new routes can't connect to it. 1101 time.Sleep(6 * time.Second) 1102 1103 // Start another server against the seed server that has an invalid OCSP Staple 1104 srvConfC := ` 1105 host: "127.0.0.1" 1106 port: -1 1107 1108 server_name: "CCC" 1109 1110 tls { 1111 cert_file: "configs/certs/ocsp/server-status-request-url-05-cert.pem" 1112 key_file: "configs/certs/ocsp/server-status-request-url-05-key.pem" 1113 ca_file: "configs/certs/ocsp/ca-cert.pem" 1114 timeout: 5 1115 } 1116 store_dir: '%s' 1117 cluster { 1118 name: AB 1119 host: "127.0.0.1" 1120 advertise: 127.0.0.1 1121 port: -1 1122 pool_size: -1 1123 1124 routes: [ nats://127.0.0.1:%d ] 1125 connect_retries: 30 1126 1127 tls { 1128 cert_file: "configs/certs/ocsp/server-status-request-url-06-cert.pem" 1129 key_file: "configs/certs/ocsp/server-status-request-url-06-key.pem" 1130 ca_file: "configs/certs/ocsp/ca-cert.pem" 1131 timeout: 5 1132 } 1133 } 1134 ` 1135 srvConfC = fmt.Sprintf(srvConfC, storeDirC, optsA.Cluster.Port) 1136 conf = createConfFile(t, []byte(srvConfC)) 1137 srvC, optsC := RunServerWithConfig(conf) 1138 defer srvC.Shutdown() 1139 1140 cB, err := nats.Connect(fmt.Sprintf("tls://localhost:%d", optsB.Port), 1141 nats.Secure(&tls.Config{ 1142 VerifyConnection: func(s tls.ConnectionState) error { 1143 if s.OCSPResponse == nil { 1144 return fmt.Errorf("missing OCSP Staple from server") 1145 } 1146 return nil 1147 }, 1148 }), 1149 nats.RootCAs(caCert), 1150 nats.ErrorHandler(noOpErrHandler), 1151 ) 1152 if err != nil { 1153 t.Fatal(err) 1154 } 1155 defer cB.Close() 1156 cC, err := nats.Connect(fmt.Sprintf("tls://localhost:%d", optsC.Port), 1157 nats.Secure(&tls.Config{ 1158 VerifyConnection: func(s tls.ConnectionState) error { 1159 if s.OCSPResponse == nil { 1160 return fmt.Errorf("missing OCSP Staple from server") 1161 } 1162 return nil 1163 }, 1164 }), 1165 nats.RootCAs(caCert), 1166 nats.ErrorHandler(noOpErrHandler), 1167 ) 1168 if err != nil { 1169 t.Fatal(err) 1170 } 1171 defer cC.Close() 1172 1173 // There should be no connectivity between the clients due to the revoked staple. 1174 _, err = cA.Subscribe("foo", func(m *nats.Msg) { 1175 m.Respond(nil) 1176 }) 1177 if err != nil { 1178 t.Errorf("%v", err) 1179 } 1180 cA.Flush() 1181 _, err = cB.Subscribe("bar", func(m *nats.Msg) { 1182 m.Respond(nil) 1183 }) 1184 if err != nil { 1185 t.Fatal(err) 1186 } 1187 cB.Flush() 1188 resp, err := cC.Request("foo", nil, 2*time.Second) 1189 if err == nil { 1190 t.Errorf("Unexpected success, response: %+v", resp) 1191 } 1192 resp, err = cC.Request("bar", nil, 2*time.Second) 1193 if err == nil { 1194 t.Errorf("Unexpected success, response: %+v", resp) 1195 } 1196 1197 // Switch the certs from the seed server to new ones that are not revoked, 1198 // this should restart OCSP Stapling for the cluster routes. 1199 srvConfA = ` 1200 host: "127.0.0.1" 1201 port: -1 1202 1203 server_name: "AAA" 1204 1205 tls { 1206 cert_file: "configs/certs/ocsp/server-status-request-url-07-cert.pem" 1207 key_file: "configs/certs/ocsp/server-status-request-url-07-key.pem" 1208 ca_file: "configs/certs/ocsp/ca-cert.pem" 1209 timeout: 5 1210 } 1211 store_dir: '%s' 1212 cluster { 1213 port: -1 1214 pool_size: -1 1215 compression: "disabled" 1216 name: AB 1217 host: "127.0.0.1" 1218 advertise: 127.0.0.1 1219 connect_retries: 30 1220 1221 tls { 1222 cert_file: "configs/certs/ocsp/server-status-request-url-08-cert.pem" 1223 key_file: "configs/certs/ocsp/server-status-request-url-08-key.pem" 1224 ca_file: "configs/certs/ocsp/ca-cert.pem" 1225 timeout: 5 1226 } 1227 } 1228 ` 1229 srvConfA = fmt.Sprintf(srvConfA, storeDirA) 1230 if err := os.WriteFile(sconfA, []byte(srvConfA), 0666); err != nil { 1231 t.Fatalf("Error writing config: %v", err) 1232 } 1233 if err := srvA.Reload(); err != nil { 1234 t.Fatal(err) 1235 } 1236 // Wait to get a new OCSP Staple. 1237 time.Sleep(10 * time.Second) 1238 checkClusterFormed(t, srvA, srvB, srvC) 1239 1240 // Now clients connect to C can communicate with B and A. 1241 _, err = cC.Request("foo", nil, 2*time.Second) 1242 if err != nil { 1243 t.Errorf("%v", err) 1244 } 1245 _, err = cC.Request("bar", nil, 2*time.Second) 1246 if err != nil { 1247 t.Errorf("%v", err) 1248 } 1249 } 1250 1251 func TestOCSPLeaf(t *testing.T) { 1252 const ( 1253 caCert = "configs/certs/ocsp/ca-cert.pem" 1254 caKey = "configs/certs/ocsp/ca-key.pem" 1255 ) 1256 ctx, cancel := context.WithCancel(context.Background()) 1257 defer cancel() 1258 ocspr := newOCSPResponder(t, caCert, caKey) 1259 defer ocspr.Shutdown(ctx) 1260 addr := fmt.Sprintf("http://%s", ocspr.Addr) 1261 setOCSPStatus(t, addr, "configs/certs/ocsp/server-status-request-url-01-cert.pem", ocsp.Good) 1262 setOCSPStatus(t, addr, "configs/certs/ocsp/server-status-request-url-02-cert.pem", ocsp.Good) 1263 setOCSPStatus(t, addr, "configs/certs/ocsp/server-status-request-url-03-cert.pem", ocsp.Good) 1264 setOCSPStatus(t, addr, "configs/certs/ocsp/server-status-request-url-04-cert.pem", ocsp.Good) 1265 setOCSPStatus(t, addr, "configs/certs/ocsp/server-status-request-url-05-cert.pem", ocsp.Good) 1266 setOCSPStatus(t, addr, "configs/certs/ocsp/server-status-request-url-06-cert.pem", ocsp.Good) 1267 setOCSPStatus(t, addr, "configs/certs/ocsp/server-status-request-url-07-cert.pem", ocsp.Good) 1268 setOCSPStatus(t, addr, "configs/certs/ocsp/server-status-request-url-08-cert.pem", ocsp.Good) 1269 setOCSPStatus(t, addr, "configs/certs/ocsp/client-cert.pem", ocsp.Good) 1270 1271 // Store Dirs 1272 storeDirA := t.TempDir() 1273 storeDirB := t.TempDir() 1274 storeDirC := t.TempDir() 1275 1276 // LeafNode server configuration 1277 srvConfA := ` 1278 host: "127.0.0.1" 1279 port: -1 1280 1281 server_name: "AAA" 1282 1283 tls { 1284 cert_file: "configs/certs/ocsp/server-status-request-url-01-cert.pem" 1285 key_file: "configs/certs/ocsp/server-status-request-url-01-key.pem" 1286 ca_file: "configs/certs/ocsp/ca-cert.pem" 1287 timeout: 5 1288 } 1289 store_dir: '%s' 1290 1291 leafnodes { 1292 host: "127.0.0.1" 1293 port: -1 1294 advertise: "127.0.0.1" 1295 1296 tls { 1297 cert_file: "configs/certs/ocsp/server-status-request-url-02-cert.pem" 1298 key_file: "configs/certs/ocsp/server-status-request-url-02-key.pem" 1299 ca_file: "configs/certs/ocsp/ca-cert.pem" 1300 timeout: 5 1301 # Leaf connection must present certs. 1302 verify: true 1303 } 1304 } 1305 ` 1306 srvConfA = fmt.Sprintf(srvConfA, storeDirA) 1307 sconfA := createConfFile(t, []byte(srvConfA)) 1308 srvA, optsA := RunServerWithConfig(sconfA) 1309 defer srvA.Shutdown() 1310 1311 // LeafNode that has the original as a remote and running 1312 // without OCSP Stapling for the leaf remote. 1313 srvConfB := ` 1314 host: "127.0.0.1" 1315 port: -1 1316 1317 server_name: "BBB" 1318 1319 tls { 1320 cert_file: "configs/certs/ocsp/server-status-request-url-03-cert.pem" 1321 key_file: "configs/certs/ocsp/server-status-request-url-03-key.pem" 1322 ca_file: "configs/certs/ocsp/ca-cert.pem" 1323 timeout: 5 1324 } 1325 store_dir: '%s' 1326 1327 leafnodes { 1328 remotes: [ { 1329 url: "tls://127.0.0.1:%d" 1330 tls { 1331 # Cert without OCSP Stapling enabled is able to connect. 1332 cert_file: "configs/certs/ocsp/client-cert.pem" 1333 key_file: "configs/certs/ocsp/client-key.pem" 1334 ca_file: "configs/certs/ocsp/ca-cert.pem" 1335 timeout: 5 1336 } 1337 } ] 1338 } 1339 ` 1340 srvConfB = fmt.Sprintf(srvConfB, storeDirB, optsA.LeafNode.Port) 1341 conf := createConfFile(t, []byte(srvConfB)) 1342 srvB, optsB := RunServerWithConfig(conf) 1343 defer srvB.Shutdown() 1344 1345 // Client connects to server A. 1346 cA, err := nats.Connect(fmt.Sprintf("tls://127.0.0.1:%d", optsA.Port), 1347 nats.Secure(&tls.Config{ 1348 VerifyConnection: func(s tls.ConnectionState) error { 1349 if s.OCSPResponse == nil { 1350 return fmt.Errorf("missing OCSP Staple from server") 1351 } 1352 return nil 1353 }, 1354 }), 1355 nats.RootCAs(caCert), 1356 nats.ErrorHandler(noOpErrHandler), 1357 ) 1358 if err != nil { 1359 t.Fatal(err) 1360 } 1361 defer cA.Close() 1362 checkLeafNodeConnected(t, srvA) 1363 1364 // Revoke the seed server cluster certificate, following servers will not be able to verify connection. 1365 setOCSPStatus(t, addr, "configs/certs/ocsp/server-status-request-url-02-cert.pem", ocsp.Revoked) 1366 1367 // Original set of servers still can communicate to each other via leafnode, even though the staple 1368 // for the leaf server has been revoked. 1369 checkLeafNodeConnected(t, srvA) 1370 1371 // Wait for seed server to notice that its certificate has been revoked. 1372 time.Sleep(6 * time.Second) 1373 1374 // Start another server against the seed server that has an revoked OCSP Staple. 1375 srvConfC := ` 1376 host: "127.0.0.1" 1377 port: -1 1378 1379 server_name: "CCC" 1380 1381 tls { 1382 cert_file: "configs/certs/ocsp/server-status-request-url-05-cert.pem" 1383 key_file: "configs/certs/ocsp/server-status-request-url-05-key.pem" 1384 ca_file: "configs/certs/ocsp/ca-cert.pem" 1385 timeout: 5 1386 } 1387 store_dir: '%s' 1388 leafnodes { 1389 remotes: [ { 1390 url: "tls://127.0.0.1:%d" 1391 tls { 1392 cert_file: "configs/certs/ocsp/server-status-request-url-06-cert.pem" 1393 key_file: "configs/certs/ocsp/server-status-request-url-06-key.pem" 1394 ca_file: "configs/certs/ocsp/ca-cert.pem" 1395 timeout: 5 1396 } 1397 } ] 1398 } 1399 ` 1400 srvConfC = fmt.Sprintf(srvConfC, storeDirC, optsA.LeafNode.Port) 1401 conf = createConfFile(t, []byte(srvConfC)) 1402 srvC, optsC := RunServerWithConfig(conf) 1403 defer srvC.Shutdown() 1404 1405 cB, err := nats.Connect(fmt.Sprintf("tls://127.0.0.1:%d", optsB.Port), 1406 nats.Secure(&tls.Config{ 1407 VerifyConnection: func(s tls.ConnectionState) error { 1408 if s.OCSPResponse == nil { 1409 return fmt.Errorf("missing OCSP Staple from server") 1410 } 1411 return nil 1412 }, 1413 }), 1414 nats.RootCAs(caCert), 1415 nats.ErrorHandler(noOpErrHandler), 1416 ) 1417 if err != nil { 1418 t.Fatal(err) 1419 } 1420 defer cB.Close() 1421 cC, err := nats.Connect(fmt.Sprintf("tls://127.0.0.1:%d", optsC.Port), 1422 nats.Secure(&tls.Config{ 1423 VerifyConnection: func(s tls.ConnectionState) error { 1424 if s.OCSPResponse == nil { 1425 return fmt.Errorf("missing OCSP Staple from server") 1426 } 1427 return nil 1428 }, 1429 }), 1430 nats.RootCAs(caCert), 1431 nats.ErrorHandler(noOpErrHandler), 1432 ) 1433 if err != nil { 1434 t.Fatal(err) 1435 } 1436 defer cC.Close() 1437 1438 // There should be connectivity between the clients even if there is a revoked staple 1439 // from a leafnode connection. 1440 _, err = cA.Subscribe("foo", func(m *nats.Msg) { 1441 m.Respond(nil) 1442 }) 1443 if err != nil { 1444 t.Errorf("%v", err) 1445 } 1446 cA.Flush() 1447 _, err = cB.Subscribe("bar", func(m *nats.Msg) { 1448 m.Respond(nil) 1449 }) 1450 if err != nil { 1451 t.Fatal(err) 1452 } 1453 cB.Flush() 1454 _, err = cC.Request("foo", nil, 2*time.Second) 1455 if err != nil { 1456 t.Errorf("Expected success, got: %+v", err) 1457 } 1458 _, err = cC.Request("bar", nil, 2*time.Second) 1459 if err != nil { 1460 t.Errorf("Expected success, got: %+v", err) 1461 } 1462 1463 // Switch the certs from the leafnode server to new ones that are not revoked, 1464 // this should restart OCSP Stapling for the leafnode server. 1465 srvConfA = ` 1466 host: "127.0.0.1" 1467 port: -1 1468 1469 server_name: "AAA" 1470 1471 tls { 1472 cert_file: "configs/certs/ocsp/server-status-request-url-07-cert.pem" 1473 key_file: "configs/certs/ocsp/server-status-request-url-07-key.pem" 1474 ca_file: "configs/certs/ocsp/ca-cert.pem" 1475 timeout: 5 1476 } 1477 store_dir: '%s' 1478 leafnodes { 1479 host: "127.0.0.1" 1480 port: -1 1481 advertise: "127.0.0.1" 1482 1483 tls { 1484 cert_file: "configs/certs/ocsp/server-status-request-url-08-cert.pem" 1485 key_file: "configs/certs/ocsp/server-status-request-url-08-key.pem" 1486 ca_file: "configs/certs/ocsp/ca-cert.pem" 1487 timeout: 5 1488 verify: true 1489 } 1490 } 1491 ` 1492 srvConfA = fmt.Sprintf(srvConfA, storeDirA) 1493 if err := os.WriteFile(sconfA, []byte(srvConfA), 0666); err != nil { 1494 t.Fatalf("Error writing config: %v", err) 1495 } 1496 if err := srvA.Reload(); err != nil { 1497 t.Fatal(err) 1498 } 1499 time.Sleep(4 * time.Second) 1500 1501 // A <-> A 1502 _, err = cA.Request("foo", nil, 2*time.Second) 1503 if err != nil { 1504 t.Errorf("%v", err) 1505 } 1506 1507 // B <-> A 1508 _, err = cB.Request("foo", nil, 2*time.Second) 1509 if err != nil { 1510 t.Errorf("%v", err) 1511 } 1512 1513 // C <-> A 1514 _, err = cC.Request("foo", nil, 2*time.Second) 1515 if err != nil { 1516 t.Errorf("%v", err) 1517 } 1518 // C <-> B via leafnode A 1519 _, err = cC.Request("bar", nil, 2*time.Second) 1520 if err != nil { 1521 t.Errorf("%v", err) 1522 } 1523 } 1524 1525 func TestOCSPLeafNoVerify(t *testing.T) { 1526 const ( 1527 caCert = "configs/certs/ocsp/ca-cert.pem" 1528 caKey = "configs/certs/ocsp/ca-key.pem" 1529 ) 1530 ctx, cancel := context.WithCancel(context.Background()) 1531 defer cancel() 1532 ocspr := newOCSPResponder(t, caCert, caKey) 1533 defer ocspr.Shutdown(ctx) 1534 addr := fmt.Sprintf("http://%s", ocspr.Addr) 1535 setOCSPStatus(t, addr, "configs/certs/ocsp/server-status-request-url-01-cert.pem", ocsp.Good) 1536 setOCSPStatus(t, addr, "configs/certs/ocsp/server-status-request-url-02-cert.pem", ocsp.Good) 1537 setOCSPStatus(t, addr, "configs/certs/ocsp/server-status-request-url-03-cert.pem", ocsp.Good) 1538 setOCSPStatus(t, addr, "configs/certs/ocsp/server-status-request-url-04-cert.pem", ocsp.Good) 1539 setOCSPStatus(t, addr, "configs/certs/ocsp/server-status-request-url-05-cert.pem", ocsp.Good) 1540 setOCSPStatus(t, addr, "configs/certs/ocsp/server-status-request-url-06-cert.pem", ocsp.Good) 1541 setOCSPStatus(t, addr, "configs/certs/ocsp/server-status-request-url-07-cert.pem", ocsp.Good) 1542 setOCSPStatus(t, addr, "configs/certs/ocsp/server-status-request-url-08-cert.pem", ocsp.Good) 1543 setOCSPStatus(t, addr, "configs/certs/ocsp/client-cert.pem", ocsp.Good) 1544 1545 // Store Dirs 1546 storeDirA := t.TempDir() 1547 storeDirB := t.TempDir() 1548 storeDirC := t.TempDir() 1549 1550 // LeafNode server configuration 1551 srvConfA := ` 1552 host: "127.0.0.1" 1553 port: -1 1554 1555 server_name: "AAA" 1556 1557 tls { 1558 cert_file: "configs/certs/ocsp/server-status-request-url-01-cert.pem" 1559 key_file: "configs/certs/ocsp/server-status-request-url-01-key.pem" 1560 ca_file: "configs/certs/ocsp/ca-cert.pem" 1561 timeout: 5 1562 } 1563 store_dir: '%s' 1564 1565 leafnodes { 1566 host: "127.0.0.1" 1567 port: -1 1568 advertise: "127.0.0.1" 1569 # for this test, explicitly disable compression because we do it 1570 # in RunServer but here we do a config reload... 1571 compression: off 1572 1573 tls { 1574 cert_file: "configs/certs/ocsp/server-status-request-url-02-cert.pem" 1575 key_file: "configs/certs/ocsp/server-status-request-url-02-key.pem" 1576 ca_file: "configs/certs/ocsp/ca-cert.pem" 1577 timeout: 5 1578 # Leaf server does not require certs for clients. 1579 verify: false 1580 } 1581 } 1582 ` 1583 srvConfA = fmt.Sprintf(srvConfA, storeDirA) 1584 sconfA := createConfFile(t, []byte(srvConfA)) 1585 srvA, optsA := RunServerWithConfig(sconfA) 1586 defer srvA.Shutdown() 1587 1588 // LeafNode remote that will connect to A and will not present certs. 1589 srvConfB := ` 1590 host: "127.0.0.1" 1591 port: -1 1592 1593 server_name: "BBB" 1594 1595 tls { 1596 cert_file: "configs/certs/ocsp/server-status-request-url-03-cert.pem" 1597 key_file: "configs/certs/ocsp/server-status-request-url-03-key.pem" 1598 ca_file: "configs/certs/ocsp/ca-cert.pem" 1599 timeout: 5 1600 } 1601 store_dir: '%s' 1602 1603 leafnodes { 1604 remotes: [ { 1605 url: "tls://127.0.0.1:%d" 1606 tls { 1607 ca_file: "configs/certs/ocsp/ca-cert.pem" 1608 timeout: 5 1609 } 1610 } ] 1611 } 1612 ` 1613 srvConfB = fmt.Sprintf(srvConfB, storeDirB, optsA.LeafNode.Port) 1614 conf := createConfFile(t, []byte(srvConfB)) 1615 srvB, optsB := RunServerWithConfig(conf) 1616 defer srvB.Shutdown() 1617 1618 // Client connects to server A. 1619 cA, err := nats.Connect(fmt.Sprintf("tls://127.0.0.1:%d", optsA.Port), 1620 nats.Secure(&tls.Config{ 1621 VerifyConnection: func(s tls.ConnectionState) error { 1622 if s.OCSPResponse == nil { 1623 return fmt.Errorf("missing OCSP Staple from server") 1624 } 1625 return nil 1626 }, 1627 }), 1628 nats.RootCAs(caCert), 1629 nats.ErrorHandler(noOpErrHandler), 1630 ) 1631 if err != nil { 1632 t.Fatal(err) 1633 } 1634 defer cA.Close() 1635 checkLeafNodeConnected(t, srvA) 1636 1637 // Revoke the seed server cluster certificate, following servers will not be able to verify connection. 1638 setOCSPStatus(t, addr, "configs/certs/ocsp/server-status-request-url-02-cert.pem", ocsp.Revoked) 1639 1640 // Original set of servers still can communicate to each other, even though the cert has been revoked. 1641 checkLeafNodeConnected(t, srvA) 1642 1643 // Wait for seed server to notice that its certificate has been revoked. 1644 time.Sleep(6 * time.Second) 1645 1646 // Start another server against the seed server that has an revoked OCSP Staple. 1647 srvConfC := ` 1648 host: "127.0.0.1" 1649 port: -1 1650 1651 server_name: "CCC" 1652 1653 tls { 1654 cert_file: "configs/certs/ocsp/server-status-request-url-05-cert.pem" 1655 key_file: "configs/certs/ocsp/server-status-request-url-05-key.pem" 1656 ca_file: "configs/certs/ocsp/ca-cert.pem" 1657 timeout: 5 1658 } 1659 store_dir: '%s' 1660 leafnodes { 1661 remotes: [ { 1662 url: "tls://127.0.0.1:%d" 1663 tls { 1664 cert_file: "configs/certs/ocsp/server-status-request-url-06-cert.pem" 1665 key_file: "configs/certs/ocsp/server-status-request-url-06-key.pem" 1666 ca_file: "configs/certs/ocsp/ca-cert.pem" 1667 timeout: 5 1668 timeout: 5 1669 } 1670 } ] 1671 } 1672 ` 1673 srvConfC = fmt.Sprintf(srvConfC, storeDirC, optsA.LeafNode.Port) 1674 conf = createConfFile(t, []byte(srvConfC)) 1675 srvC, optsC := RunServerWithConfig(conf) 1676 defer srvC.Shutdown() 1677 1678 cB, err := nats.Connect(fmt.Sprintf("tls://127.0.0.1:%d", optsB.Port), 1679 nats.Secure(&tls.Config{ 1680 VerifyConnection: func(s tls.ConnectionState) error { 1681 if s.OCSPResponse == nil { 1682 return fmt.Errorf("missing OCSP Staple from server") 1683 } 1684 return nil 1685 }, 1686 }), 1687 nats.RootCAs(caCert), 1688 nats.ErrorHandler(noOpErrHandler), 1689 ) 1690 if err != nil { 1691 t.Fatal(err) 1692 } 1693 defer cB.Close() 1694 cC, err := nats.Connect(fmt.Sprintf("tls://127.0.0.1:%d", optsC.Port), 1695 nats.Secure(&tls.Config{ 1696 VerifyConnection: func(s tls.ConnectionState) error { 1697 if s.OCSPResponse == nil { 1698 return fmt.Errorf("missing OCSP Staple from server") 1699 } 1700 return nil 1701 }, 1702 }), 1703 nats.RootCAs(caCert), 1704 nats.ErrorHandler(noOpErrHandler), 1705 ) 1706 if err != nil { 1707 t.Fatal(err) 1708 } 1709 defer cC.Close() 1710 1711 // There should be connectivity between the clients even if there is a revoked staple 1712 // from a leafnode connection. 1713 _, err = cA.Subscribe("foo", func(m *nats.Msg) { 1714 m.Respond(nil) 1715 }) 1716 if err != nil { 1717 t.Errorf("%v", err) 1718 } 1719 cA.Flush() 1720 _, err = cB.Subscribe("bar", func(m *nats.Msg) { 1721 m.Respond(nil) 1722 }) 1723 if err != nil { 1724 t.Fatal(err) 1725 } 1726 cB.Flush() 1727 _, err = cC.Request("foo", nil, 2*time.Second) 1728 if err != nil { 1729 t.Errorf("Expected success, got: %+v", err) 1730 } 1731 _, err = cC.Request("bar", nil, 2*time.Second) 1732 if err != nil { 1733 t.Errorf("Expected success, got: %+v", err) 1734 } 1735 1736 // Switch the certs from the leafnode server to new ones that are not revoked, 1737 // this should restart OCSP Stapling for the leafnode server. 1738 srvConfA = ` 1739 host: "127.0.0.1" 1740 port: -1 1741 1742 server_name: "AAA" 1743 1744 tls { 1745 cert_file: "configs/certs/ocsp/server-status-request-url-07-cert.pem" 1746 key_file: "configs/certs/ocsp/server-status-request-url-07-key.pem" 1747 ca_file: "configs/certs/ocsp/ca-cert.pem" 1748 timeout: 5 1749 } 1750 store_dir: '%s' 1751 leafnodes { 1752 host: "127.0.0.1" 1753 port: -1 1754 advertise: "127.0.0.1" 1755 compression: off 1756 1757 tls { 1758 cert_file: "configs/certs/ocsp/server-status-request-url-08-cert.pem" 1759 key_file: "configs/certs/ocsp/server-status-request-url-08-key.pem" 1760 ca_file: "configs/certs/ocsp/ca-cert.pem" 1761 timeout: 5 1762 verify: true 1763 } 1764 } 1765 ` 1766 srvConfA = fmt.Sprintf(srvConfA, storeDirA) 1767 if err := os.WriteFile(sconfA, []byte(srvConfA), 0666); err != nil { 1768 t.Fatalf("Error writing config: %v", err) 1769 } 1770 if err := srvA.Reload(); err != nil { 1771 t.Fatal(err) 1772 } 1773 time.Sleep(4 * time.Second) 1774 1775 // A <-> A 1776 _, err = cA.Request("foo", nil, 2*time.Second) 1777 if err != nil { 1778 t.Errorf("%v", err) 1779 } 1780 1781 // B <-> A 1782 _, err = cB.Request("foo", nil, 2*time.Second) 1783 if err != nil { 1784 t.Errorf("%v", err) 1785 } 1786 1787 // C <-> A 1788 _, err = cC.Request("foo", nil, 2*time.Second) 1789 if err != nil { 1790 t.Errorf("%v", err) 1791 } 1792 // C <-> B via leafnode A 1793 _, err = cC.Request("bar", nil, 2*time.Second) 1794 if err != nil { 1795 t.Errorf("%v", err) 1796 } 1797 } 1798 1799 func TestOCSPLeafVerifyLeafRemote(t *testing.T) { 1800 const ( 1801 caCert = "configs/certs/ocsp/ca-cert.pem" 1802 caKey = "configs/certs/ocsp/ca-key.pem" 1803 ) 1804 ctx, cancel := context.WithCancel(context.Background()) 1805 defer cancel() 1806 ocspr := newOCSPResponder(t, caCert, caKey) 1807 defer ocspr.Shutdown(ctx) 1808 addr := fmt.Sprintf("http://%s", ocspr.Addr) 1809 setOCSPStatus(t, addr, "configs/certs/ocsp/server-status-request-url-01-cert.pem", ocsp.Good) 1810 setOCSPStatus(t, addr, "configs/certs/ocsp/server-status-request-url-02-cert.pem", ocsp.Good) 1811 setOCSPStatus(t, addr, "configs/certs/ocsp/server-status-request-url-03-cert.pem", ocsp.Good) 1812 setOCSPStatus(t, addr, "configs/certs/ocsp/server-status-request-url-04-cert.pem", ocsp.Good) 1813 setOCSPStatus(t, addr, "configs/certs/ocsp/server-status-request-url-05-cert.pem", ocsp.Good) 1814 setOCSPStatus(t, addr, "configs/certs/ocsp/server-status-request-url-06-cert.pem", ocsp.Good) 1815 setOCSPStatus(t, addr, "configs/certs/ocsp/server-status-request-url-07-cert.pem", ocsp.Good) 1816 setOCSPStatus(t, addr, "configs/certs/ocsp/server-status-request-url-08-cert.pem", ocsp.Good) 1817 setOCSPStatus(t, addr, "configs/certs/ocsp/client-cert.pem", ocsp.Good) 1818 1819 // Store Dirs 1820 storeDirA := t.TempDir() 1821 storeDirB := t.TempDir() 1822 1823 // LeafNode server configuration 1824 srvConfA := ` 1825 host: "127.0.0.1" 1826 port: -1 1827 1828 server_name: "AAA" 1829 1830 tls { 1831 cert_file: "configs/certs/ocsp/server-status-request-url-01-cert.pem" 1832 key_file: "configs/certs/ocsp/server-status-request-url-01-key.pem" 1833 ca_file: "configs/certs/ocsp/ca-cert.pem" 1834 timeout: 5 1835 } 1836 store_dir: '%s' 1837 1838 leafnodes { 1839 host: "127.0.0.1" 1840 port: -1 1841 advertise: "127.0.0.1" 1842 1843 tls { 1844 cert_file: "configs/certs/ocsp/server-status-request-url-02-cert.pem" 1845 key_file: "configs/certs/ocsp/server-status-request-url-02-key.pem" 1846 ca_file: "configs/certs/ocsp/ca-cert.pem" 1847 timeout: 5 1848 verify: true 1849 } 1850 } 1851 ` 1852 srvConfA = fmt.Sprintf(srvConfA, storeDirA) 1853 sconfA := createConfFile(t, []byte(srvConfA)) 1854 srvA, optsA := RunServerWithConfig(sconfA) 1855 defer srvA.Shutdown() 1856 1857 // LeafNode remote that will connect to A and will not present certs. 1858 srvConfB := ` 1859 host: "127.0.0.1" 1860 port: -1 1861 1862 server_name: "BBB" 1863 1864 tls { 1865 cert_file: "configs/certs/ocsp/server-status-request-url-03-cert.pem" 1866 key_file: "configs/certs/ocsp/server-status-request-url-03-key.pem" 1867 ca_file: "configs/certs/ocsp/ca-cert.pem" 1868 timeout: 5 1869 } 1870 store_dir: '%s' 1871 1872 leafnodes { 1873 remotes: [ { 1874 url: "tls://127.0.0.1:%d" 1875 tls { 1876 ca_file: "configs/certs/ocsp/ca-cert.pem" 1877 timeout: 5 1878 } 1879 } ] 1880 } 1881 ` 1882 srvConfB = fmt.Sprintf(srvConfB, storeDirB, optsA.LeafNode.Port) 1883 conf := createConfFile(t, []byte(srvConfB)) 1884 srvB, _ := RunServerWithConfig(conf) 1885 defer srvB.Shutdown() 1886 1887 // Client connects to server A. 1888 cA, err := nats.Connect(fmt.Sprintf("tls://127.0.0.1:%d", optsA.Port), 1889 nats.Secure(&tls.Config{ 1890 VerifyConnection: func(s tls.ConnectionState) error { 1891 if s.OCSPResponse == nil { 1892 return fmt.Errorf("missing OCSP Staple from server") 1893 } 1894 return nil 1895 }, 1896 }), 1897 nats.RootCAs(caCert), 1898 nats.ErrorHandler(noOpErrHandler), 1899 ) 1900 if err != nil { 1901 t.Fatal(err) 1902 } 1903 defer cA.Close() 1904 1905 // Should not have been able to connect. 1906 checkLeafNodeConnections(t, srvA, 0) 1907 } 1908 1909 func TestOCSPLeafVerifyAndMapLeafRemote(t *testing.T) { 1910 const ( 1911 caCert = "configs/certs/ocsp/ca-cert.pem" 1912 caKey = "configs/certs/ocsp/ca-key.pem" 1913 ) 1914 ctx, cancel := context.WithCancel(context.Background()) 1915 defer cancel() 1916 ocspr := newOCSPResponder(t, caCert, caKey) 1917 defer ocspr.Shutdown(ctx) 1918 addr := fmt.Sprintf("http://%s", ocspr.Addr) 1919 setOCSPStatus(t, addr, "configs/certs/ocsp/server-status-request-url-01-cert.pem", ocsp.Good) 1920 setOCSPStatus(t, addr, "configs/certs/ocsp/server-status-request-url-02-cert.pem", ocsp.Good) 1921 setOCSPStatus(t, addr, "configs/certs/ocsp/server-status-request-url-03-cert.pem", ocsp.Good) 1922 setOCSPStatus(t, addr, "configs/certs/ocsp/server-status-request-url-04-cert.pem", ocsp.Good) 1923 setOCSPStatus(t, addr, "configs/certs/ocsp/server-status-request-url-05-cert.pem", ocsp.Good) 1924 setOCSPStatus(t, addr, "configs/certs/ocsp/server-status-request-url-06-cert.pem", ocsp.Good) 1925 setOCSPStatus(t, addr, "configs/certs/ocsp/server-status-request-url-07-cert.pem", ocsp.Good) 1926 setOCSPStatus(t, addr, "configs/certs/ocsp/server-status-request-url-08-cert.pem", ocsp.Good) 1927 setOCSPStatus(t, addr, "configs/certs/ocsp/client-cert.pem", ocsp.Good) 1928 1929 // Store Dirs 1930 storeDirA := t.TempDir() 1931 storeDirB := t.TempDir() 1932 1933 // LeafNode server configuration 1934 srvConfA := ` 1935 host: "127.0.0.1" 1936 port: -1 1937 1938 server_name: "AAA" 1939 1940 tls { 1941 cert_file: "configs/certs/ocsp/server-status-request-url-01-cert.pem" 1942 key_file: "configs/certs/ocsp/server-status-request-url-01-key.pem" 1943 ca_file: "configs/certs/ocsp/ca-cert.pem" 1944 timeout: 5 1945 verify_and_map: true 1946 } 1947 store_dir: '%s' 1948 1949 leafnodes { 1950 host: "127.0.0.1" 1951 port: -1 1952 advertise: "127.0.0.1" 1953 1954 tls { 1955 cert_file: "configs/certs/ocsp/server-status-request-url-02-cert.pem" 1956 key_file: "configs/certs/ocsp/server-status-request-url-02-key.pem" 1957 ca_file: "configs/certs/ocsp/ca-cert.pem" 1958 timeout: 5 1959 verify_and_map: true 1960 } 1961 } 1962 1963 accounts: { 1964 leaf: { 1965 users: [ {user: "C=US, ST=CA, L=San Francisco, O=Synadia, OU=nats.io, CN=localhost server-status-request-url-04"} ] 1966 } 1967 client: { 1968 users: [ {user: "C=US, ST=CA, L=San Francisco, O=Synadia, OU=nats.io, CN=localhost client"} ] 1969 } 1970 } 1971 1972 ` 1973 srvConfA = fmt.Sprintf(srvConfA, storeDirA) 1974 sconfA := createConfFile(t, []byte(srvConfA)) 1975 srvA, optsA := RunServerWithConfig(sconfA) 1976 defer srvA.Shutdown() 1977 1978 // LeafNode remote that will connect to A and will not present certs. 1979 srvConfB := ` 1980 host: "127.0.0.1" 1981 port: -1 1982 1983 server_name: "BBB" 1984 1985 tls { 1986 cert_file: "configs/certs/ocsp/server-status-request-url-03-cert.pem" 1987 key_file: "configs/certs/ocsp/server-status-request-url-03-key.pem" 1988 ca_file: "configs/certs/ocsp/ca-cert.pem" 1989 timeout: 5 1990 } 1991 store_dir: '%s' 1992 1993 leafnodes { 1994 remotes: [ { 1995 url: "tls://127.0.0.1:%d" 1996 tls { 1997 cert_file: "configs/certs/ocsp/server-status-request-url-04-cert.pem" 1998 key_file: "configs/certs/ocsp/server-status-request-url-04-key.pem" 1999 ca_file: "configs/certs/ocsp/ca-cert.pem" 2000 timeout: 5 2001 } 2002 } ] 2003 } 2004 ` 2005 srvConfB = fmt.Sprintf(srvConfB, storeDirB, optsA.LeafNode.Port) 2006 conf := createConfFile(t, []byte(srvConfB)) 2007 srvB, _ := RunServerWithConfig(conf) 2008 defer srvB.Shutdown() 2009 2010 // Client connects to server A. 2011 cA, err := nats.Connect(fmt.Sprintf("tls://127.0.0.1:%d", optsA.Port), 2012 nats.Secure(&tls.Config{ 2013 VerifyConnection: func(s tls.ConnectionState) error { 2014 if s.OCSPResponse == nil { 2015 return fmt.Errorf("missing OCSP Staple from server") 2016 } 2017 return nil 2018 }, 2019 }), 2020 nats.ClientCert("./configs/certs/ocsp/client-cert.pem", "./configs/certs/ocsp/client-key.pem"), 2021 nats.RootCAs(caCert), 2022 nats.ErrorHandler(noOpErrHandler), 2023 ) 2024 if err != nil { 2025 t.Fatal(err) 2026 } 2027 defer cA.Close() 2028 checkLeafNodeConnections(t, srvA, 1) 2029 } 2030 2031 func TestOCSPGateway(t *testing.T) { 2032 const ( 2033 caCert = "configs/certs/ocsp/ca-cert.pem" 2034 caKey = "configs/certs/ocsp/ca-key.pem" 2035 ) 2036 ctx, cancel := context.WithCancel(context.Background()) 2037 defer cancel() 2038 ocspr := newOCSPResponder(t, caCert, caKey) 2039 defer ocspr.Shutdown(ctx) 2040 addr := fmt.Sprintf("http://%s", ocspr.Addr) 2041 setOCSPStatus(t, addr, "configs/certs/ocsp/server-status-request-url-01-cert.pem", ocsp.Good) 2042 setOCSPStatus(t, addr, "configs/certs/ocsp/server-status-request-url-02-cert.pem", ocsp.Good) 2043 setOCSPStatus(t, addr, "configs/certs/ocsp/server-status-request-url-03-cert.pem", ocsp.Good) 2044 setOCSPStatus(t, addr, "configs/certs/ocsp/server-status-request-url-04-cert.pem", ocsp.Good) 2045 setOCSPStatus(t, addr, "configs/certs/ocsp/server-status-request-url-05-cert.pem", ocsp.Good) 2046 setOCSPStatus(t, addr, "configs/certs/ocsp/server-status-request-url-06-cert.pem", ocsp.Good) 2047 setOCSPStatus(t, addr, "configs/certs/ocsp/server-status-request-url-07-cert.pem", ocsp.Good) 2048 setOCSPStatus(t, addr, "configs/certs/ocsp/server-status-request-url-08-cert.pem", ocsp.Good) 2049 2050 // Store Dirs 2051 storeDirA := t.TempDir() 2052 storeDirB := t.TempDir() 2053 storeDirC := t.TempDir() 2054 2055 // Gateway server configuration 2056 srvConfA := ` 2057 host: "127.0.0.1" 2058 port: -1 2059 2060 server_name: "AAA" 2061 2062 tls { 2063 cert_file: "configs/certs/ocsp/server-status-request-url-01-cert.pem" 2064 key_file: "configs/certs/ocsp/server-status-request-url-01-key.pem" 2065 ca_file: "configs/certs/ocsp/ca-cert.pem" 2066 timeout: 5 2067 } 2068 store_dir: '%s' 2069 gateway { 2070 name: A 2071 host: "127.0.0.1" 2072 port: -1 2073 advertise: "127.0.0.1" 2074 2075 tls { 2076 cert_file: "configs/certs/ocsp/server-status-request-url-02-cert.pem" 2077 key_file: "configs/certs/ocsp/server-status-request-url-02-key.pem" 2078 ca_file: "configs/certs/ocsp/ca-cert.pem" 2079 timeout: 5 2080 } 2081 } 2082 ` 2083 srvConfA = fmt.Sprintf(srvConfA, storeDirA) 2084 sconfA := createConfFile(t, []byte(srvConfA)) 2085 srvA, optsA := RunServerWithConfig(sconfA) 2086 defer srvA.Shutdown() 2087 2088 // LeafNode that has the original as a remote. 2089 srvConfB := ` 2090 host: "127.0.0.1" 2091 port: -1 2092 2093 server_name: "BBB" 2094 2095 tls { 2096 cert_file: "configs/certs/ocsp/server-status-request-url-03-cert.pem" 2097 key_file: "configs/certs/ocsp/server-status-request-url-03-key.pem" 2098 ca_file: "configs/certs/ocsp/ca-cert.pem" 2099 timeout: 5 2100 } 2101 store_dir: '%s' 2102 gateway { 2103 name: B 2104 host: "127.0.0.1" 2105 advertise: "127.0.0.1" 2106 port: -1 2107 gateways: [{ 2108 name: "A" 2109 url: "nats://127.0.0.1:%d" 2110 tls { 2111 cert_file: "configs/certs/ocsp/server-status-request-url-04-cert.pem" 2112 key_file: "configs/certs/ocsp/server-status-request-url-04-key.pem" 2113 ca_file: "configs/certs/ocsp/ca-cert.pem" 2114 timeout: 5 2115 } 2116 }] 2117 tls { 2118 cert_file: "configs/certs/ocsp/server-status-request-url-04-cert.pem" 2119 key_file: "configs/certs/ocsp/server-status-request-url-04-key.pem" 2120 ca_file: "configs/certs/ocsp/ca-cert.pem" 2121 timeout: 5 2122 } 2123 } 2124 ` 2125 srvConfB = fmt.Sprintf(srvConfB, storeDirB, optsA.Gateway.Port) 2126 conf := createConfFile(t, []byte(srvConfB)) 2127 srvB, optsB := RunServerWithConfig(conf) 2128 defer srvB.Shutdown() 2129 2130 // Client connects to server A. 2131 cA, err := nats.Connect(fmt.Sprintf("tls://127.0.0.1:%d", optsA.Port), 2132 nats.Secure(&tls.Config{ 2133 VerifyConnection: func(s tls.ConnectionState) error { 2134 if s.OCSPResponse == nil { 2135 return fmt.Errorf("missing OCSP Staple from server") 2136 } 2137 return nil 2138 }, 2139 }), 2140 nats.RootCAs(caCert), 2141 nats.ErrorHandler(noOpErrHandler), 2142 ) 2143 if err != nil { 2144 t.Fatal(err) 2145 } 2146 defer cA.Close() 2147 waitForOutboundGateways(t, srvB, 1, 5*time.Second) 2148 2149 // Revoke the seed server cluster certificate, following servers will not be able to verify connection. 2150 setOCSPStatus(t, addr, "configs/certs/ocsp/server-status-request-url-02-cert.pem", ocsp.Revoked) 2151 2152 // Original set of servers still can communicate to each other, even though the cert has been revoked. 2153 waitForOutboundGateways(t, srvA, 1, 5*time.Second) 2154 waitForOutboundGateways(t, srvB, 1, 5*time.Second) 2155 2156 // Wait for gateway A to notice that its certificate has been revoked, 2157 // so that new gateways can't connect to it. 2158 time.Sleep(6 * time.Second) 2159 2160 // Start another server against the seed server that has an invalid OCSP Staple 2161 srvConfC := ` 2162 host: "127.0.0.1" 2163 port: -1 2164 2165 server_name: "CCC" 2166 2167 tls { 2168 cert_file: "configs/certs/ocsp/server-status-request-url-05-cert.pem" 2169 key_file: "configs/certs/ocsp/server-status-request-url-05-key.pem" 2170 ca_file: "configs/certs/ocsp/ca-cert.pem" 2171 timeout: 5 2172 } 2173 store_dir: '%s' 2174 gateway { 2175 name: C 2176 host: "127.0.0.1" 2177 advertise: "127.0.0.1" 2178 port: -1 2179 gateways: [{name: "A", url: "nats://127.0.0.1:%d" }] 2180 tls { 2181 cert_file: "configs/certs/ocsp/server-status-request-url-06-cert.pem" 2182 key_file: "configs/certs/ocsp/server-status-request-url-06-key.pem" 2183 ca_file: "configs/certs/ocsp/ca-cert.pem" 2184 timeout: 5 2185 } 2186 } 2187 ` 2188 srvConfC = fmt.Sprintf(srvConfC, storeDirC, optsA.Gateway.Port) 2189 conf = createConfFile(t, []byte(srvConfC)) 2190 srvC, optsC := RunServerWithConfig(conf) 2191 defer srvC.Shutdown() 2192 2193 cB, err := nats.Connect(fmt.Sprintf("tls://127.0.0.1:%d", optsB.Port), 2194 nats.Secure(&tls.Config{ 2195 VerifyConnection: func(s tls.ConnectionState) error { 2196 if s.OCSPResponse == nil { 2197 return fmt.Errorf("missing OCSP Staple from server") 2198 } 2199 return nil 2200 }, 2201 }), 2202 nats.RootCAs(caCert), 2203 nats.ErrorHandler(noOpErrHandler), 2204 ) 2205 if err != nil { 2206 t.Fatal(err) 2207 } 2208 defer cB.Close() 2209 cC, err := nats.Connect(fmt.Sprintf("tls://127.0.0.1:%d", optsC.Port), 2210 nats.Secure(&tls.Config{ 2211 VerifyConnection: func(s tls.ConnectionState) error { 2212 if s.OCSPResponse == nil { 2213 return fmt.Errorf("missing OCSP Staple from server") 2214 } 2215 return nil 2216 }, 2217 }), 2218 nats.RootCAs(caCert), 2219 nats.ErrorHandler(noOpErrHandler), 2220 ) 2221 if err != nil { 2222 t.Fatal(err) 2223 } 2224 defer cC.Close() 2225 2226 // There should be no connectivity between the clients due to the revoked staple. 2227 _, err = cA.Subscribe("foo", func(m *nats.Msg) { 2228 m.Respond(nil) 2229 }) 2230 if err != nil { 2231 t.Errorf("%v", err) 2232 } 2233 cA.Flush() 2234 _, err = cB.Subscribe("bar", func(m *nats.Msg) { 2235 m.Respond(nil) 2236 }) 2237 if err != nil { 2238 t.Fatal(err) 2239 } 2240 cB.Flush() 2241 2242 // Gateway C was not able to mesh with Gateway A because of the revoked OCSP staple 2243 // so these requests to A and B should fail. 2244 resp, err := cC.Request("foo", nil, 2*time.Second) 2245 if err == nil { 2246 t.Errorf("Unexpected success, response: %+v", resp) 2247 } 2248 // Make request to B 2249 resp, err = cC.Request("bar", nil, 2*time.Second) 2250 if err == nil { 2251 t.Errorf("Unexpected success, response: %+v", resp) 2252 } 2253 2254 // Switch the certs from the seed server to new ones that are not revoked, 2255 // this should restart OCSP Stapling for the cluster routes. 2256 srvConfA = ` 2257 host: "127.0.0.1" 2258 port: -1 2259 2260 server_name: "AAA" 2261 2262 tls { 2263 cert_file: "configs/certs/ocsp/server-status-request-url-07-cert.pem" 2264 key_file: "configs/certs/ocsp/server-status-request-url-07-key.pem" 2265 ca_file: "configs/certs/ocsp/ca-cert.pem" 2266 timeout: 5 2267 } 2268 store_dir: '%s' 2269 gateway { 2270 name: A 2271 host: "127.0.0.1" 2272 port: -1 2273 advertise: "127.0.0.1" 2274 2275 tls { 2276 cert_file: "configs/certs/ocsp/server-status-request-url-08-cert.pem" 2277 key_file: "configs/certs/ocsp/server-status-request-url-08-key.pem" 2278 ca_file: "configs/certs/ocsp/ca-cert.pem" 2279 timeout: 5 2280 } 2281 } 2282 ` 2283 2284 srvConfA = fmt.Sprintf(srvConfA, storeDirA) 2285 if err := os.WriteFile(sconfA, []byte(srvConfA), 0666); err != nil { 2286 t.Fatalf("Error writing config: %v", err) 2287 } 2288 if err := srvA.Reload(); err != nil { 2289 t.Fatal(err) 2290 } 2291 time.Sleep(4 * time.Second) 2292 waitForOutboundGateways(t, srvA, 2, 5*time.Second) 2293 waitForOutboundGateways(t, srvB, 2, 5*time.Second) 2294 waitForOutboundGateways(t, srvC, 2, 5*time.Second) 2295 2296 // Now clients connect to C can communicate with B and A. 2297 _, err = cC.Request("foo", nil, 2*time.Second) 2298 if err != nil { 2299 t.Errorf("%v", err) 2300 } 2301 _, err = cC.Request("bar", nil, 2*time.Second) 2302 if err != nil { 2303 t.Errorf("%v", err) 2304 } 2305 } 2306 2307 func TestOCSPGatewayIntermediate(t *testing.T) { 2308 ctx, cancel := context.WithCancel(context.Background()) 2309 defer cancel() 2310 2311 intermediateCA1Responder := newOCSPResponderIntermediateCA1(t) 2312 intermediateCA1ResponderURL := fmt.Sprintf("http://%s", intermediateCA1Responder.Addr) 2313 defer intermediateCA1Responder.Shutdown(ctx) 2314 setOCSPStatus(t, intermediateCA1ResponderURL, "configs/certs/ocsp_peer/mini-ca/server1/TestServer1_cert.pem", ocsp.Good) 2315 setOCSPStatus(t, intermediateCA1ResponderURL, "configs/certs/ocsp_peer/mini-ca/server1/TestServer2_cert.pem", ocsp.Good) 2316 2317 // Gateway server configuration 2318 srvConfA := ` 2319 host: "127.0.0.1" 2320 port: -1 2321 2322 server_name: "AAA" 2323 2324 ocsp: { 2325 mode: always 2326 url: %s 2327 } 2328 2329 gateway { 2330 name: A 2331 host: "127.0.0.1" 2332 port: -1 2333 advertise: "127.0.0.1" 2334 2335 tls { 2336 cert_file: "configs/certs/ocsp_peer/mini-ca/server1/TestServer1_bundle.pem" 2337 key_file: "configs/certs/ocsp_peer/mini-ca/server1/private/TestServer1_keypair.pem" 2338 ca_file: "configs/certs/ocsp_peer/mini-ca/root/root_cert.pem" 2339 timeout: 5 2340 } 2341 } 2342 ` 2343 srvConfA = fmt.Sprintf(srvConfA, intermediateCA1ResponderURL) 2344 sconfA := createConfFile(t, []byte(srvConfA)) 2345 srvA, optsA := RunServerWithConfig(sconfA) 2346 defer srvA.Shutdown() 2347 2348 srvConfB := ` 2349 host: "127.0.0.1" 2350 port: -1 2351 2352 server_name: "BBB" 2353 2354 ocsp: { 2355 mode: always 2356 url: %s 2357 } 2358 2359 gateway { 2360 name: B 2361 host: "127.0.0.1" 2362 advertise: "127.0.0.1" 2363 port: -1 2364 gateways: [{ 2365 name: "A" 2366 url: "nats://127.0.0.1:%d" 2367 }] 2368 tls { 2369 cert_file: "configs/certs/ocsp_peer/mini-ca/server1/TestServer2_bundle.pem" 2370 key_file: "configs/certs/ocsp_peer/mini-ca/server1/private/TestServer2_keypair.pem" 2371 ca_file: "configs/certs/ocsp_peer/mini-ca/root/root_cert.pem" 2372 timeout: 5 2373 } 2374 } 2375 ` 2376 srvConfB = fmt.Sprintf(srvConfB, intermediateCA1ResponderURL, optsA.Gateway.Port) 2377 conf := createConfFile(t, []byte(srvConfB)) 2378 srvB, optsB := RunServerWithConfig(conf) 2379 defer srvB.Shutdown() 2380 2381 // Client connects to server A. 2382 cA, err := nats.Connect(fmt.Sprintf("nats://127.0.0.1:%d", optsA.Port), 2383 nats.ErrorHandler(noOpErrHandler), 2384 ) 2385 if err != nil { 2386 t.Fatal(err) 2387 } 2388 defer cA.Close() 2389 waitForOutboundGateways(t, srvB, 1, 5*time.Second) 2390 2391 cB, err := nats.Connect(fmt.Sprintf("nats://127.0.0.1:%d", optsB.Port), 2392 nats.ErrorHandler(noOpErrHandler), 2393 ) 2394 if err != nil { 2395 t.Fatal(err) 2396 } 2397 defer cB.Close() 2398 } 2399 2400 func TestOCSPGatewayReload(t *testing.T) { 2401 const ( 2402 caCert = "configs/certs/ocsp/ca-cert.pem" 2403 caKey = "configs/certs/ocsp/ca-key.pem" 2404 ) 2405 ctx, cancel := context.WithCancel(context.Background()) 2406 defer cancel() 2407 ocspr := newOCSPResponder(t, caCert, caKey) 2408 defer ocspr.Shutdown(ctx) 2409 addr := fmt.Sprintf("http://%s", ocspr.Addr) 2410 2411 // Node A 2412 setOCSPStatus(t, addr, "configs/certs/ocsp/server-status-request-url-01-cert.pem", ocsp.Good) 2413 setOCSPStatus(t, addr, "configs/certs/ocsp/server-status-request-url-02-cert.pem", ocsp.Good) 2414 2415 // Node B 2416 setOCSPStatus(t, addr, "configs/certs/ocsp/server-status-request-url-03-cert.pem", ocsp.Good) 2417 setOCSPStatus(t, addr, "configs/certs/ocsp/server-status-request-url-04-cert.pem", ocsp.Good) 2418 2419 // Node C 2420 setOCSPStatus(t, addr, "configs/certs/ocsp/server-status-request-url-05-cert.pem", ocsp.Good) 2421 setOCSPStatus(t, addr, "configs/certs/ocsp/server-status-request-url-06-cert.pem", ocsp.Good) 2422 2423 // Node A rotated certs 2424 setOCSPStatus(t, addr, "configs/certs/ocsp/server-status-request-url-07-cert.pem", ocsp.Good) 2425 setOCSPStatus(t, addr, "configs/certs/ocsp/server-status-request-url-08-cert.pem", ocsp.Good) 2426 2427 // Store Dirs 2428 storeDirA := t.TempDir() 2429 storeDirB := t.TempDir() 2430 storeDirC := t.TempDir() 2431 2432 // Gateway server configuration 2433 srvConfA := ` 2434 host: "127.0.0.1" 2435 port: -1 2436 2437 server_name: "AAA" 2438 2439 ocsp { mode = always } 2440 2441 store_dir: '%s' 2442 gateway { 2443 name: A 2444 host: "127.0.0.1" 2445 port: -1 2446 advertise: "127.0.0.1" 2447 2448 tls { 2449 cert_file: "configs/certs/ocsp/server-status-request-url-02-cert.pem" 2450 key_file: "configs/certs/ocsp/server-status-request-url-02-key.pem" 2451 ca_file: "configs/certs/ocsp/ca-cert.pem" 2452 timeout: 5 2453 } 2454 } 2455 ` 2456 srvConfA = fmt.Sprintf(srvConfA, storeDirA) 2457 sconfA := createConfFile(t, []byte(srvConfA)) 2458 srvA, optsA := RunServerWithConfig(sconfA) 2459 defer srvA.Shutdown() 2460 2461 // Gateway B connects to Gateway A. 2462 srvConfB := ` 2463 host: "127.0.0.1" 2464 port: -1 2465 2466 server_name: "BBB" 2467 2468 ocsp { mode = always } 2469 2470 store_dir: '%s' 2471 gateway { 2472 name: B 2473 host: "127.0.0.1" 2474 advertise: "127.0.0.1" 2475 port: -1 2476 gateways: [{ 2477 name: "A" 2478 url: "nats://127.0.0.1:%d" 2479 }] 2480 tls { 2481 cert_file: "configs/certs/ocsp/server-status-request-url-04-cert.pem" 2482 key_file: "configs/certs/ocsp/server-status-request-url-04-key.pem" 2483 ca_file: "configs/certs/ocsp/ca-cert.pem" 2484 timeout: 5 2485 } 2486 } 2487 ` 2488 srvConfB = fmt.Sprintf(srvConfB, storeDirB, optsA.Gateway.Port) 2489 conf := createConfFile(t, []byte(srvConfB)) 2490 srvB, optsB := RunServerWithConfig(conf) 2491 defer srvB.Shutdown() 2492 2493 // Client connects to server A. 2494 cA, err := nats.Connect(fmt.Sprintf("nats://127.0.0.1:%d", optsA.Port), 2495 nats.ErrorHandler(noOpErrHandler), 2496 ) 2497 if err != nil { 2498 t.Fatal(err) 2499 } 2500 defer cA.Close() 2501 2502 // Wait for connectivity between A and B. 2503 waitForOutboundGateways(t, srvB, 1, 5*time.Second) 2504 2505 // Gateway C also connects to Gateway A. 2506 srvConfC := ` 2507 host: "127.0.0.1" 2508 port: -1 2509 2510 server_name: "CCC" 2511 2512 ocsp { mode = always } 2513 2514 store_dir: '%s' 2515 gateway { 2516 name: C 2517 host: "127.0.0.1" 2518 advertise: "127.0.0.1" 2519 port: -1 2520 gateways: [{name: "A", url: "nats://127.0.0.1:%d" }] 2521 tls { 2522 cert_file: "configs/certs/ocsp/server-status-request-url-06-cert.pem" 2523 key_file: "configs/certs/ocsp/server-status-request-url-06-key.pem" 2524 ca_file: "configs/certs/ocsp/ca-cert.pem" 2525 timeout: 5 2526 } 2527 } 2528 ` 2529 srvConfC = fmt.Sprintf(srvConfC, storeDirC, optsA.Gateway.Port) 2530 conf = createConfFile(t, []byte(srvConfC)) 2531 srvC, optsC := RunServerWithConfig(conf) 2532 defer srvC.Shutdown() 2533 2534 //////////////////////////////////////////////////////////////////////////// 2535 // // 2536 // A and B are connected at this point and C is starting with certs that // 2537 // will be rotated, in v2.10.8 on reload now all OCSP monitors are also // 2538 // always restarted. // 2539 // // 2540 //////////////////////////////////////////////////////////////////////////// 2541 cB, err := nats.Connect(fmt.Sprintf("nats://127.0.0.1:%d", optsB.Port), 2542 nats.ErrorHandler(noOpErrHandler), 2543 ) 2544 if err != nil { 2545 t.Fatal(err) 2546 } 2547 defer cB.Close() 2548 cC, err := nats.Connect(fmt.Sprintf("nats://127.0.0.1:%d", optsC.Port), 2549 nats.ErrorHandler(noOpErrHandler), 2550 ) 2551 if err != nil { 2552 t.Fatal(err) 2553 } 2554 defer cC.Close() 2555 2556 _, err = cA.Subscribe("foo", func(m *nats.Msg) { 2557 m.Respond(nil) 2558 }) 2559 if err != nil { 2560 t.Errorf("%v", err) 2561 } 2562 cA.Flush() 2563 _, err = cB.Subscribe("bar", func(m *nats.Msg) { 2564 m.Respond(nil) 2565 }) 2566 if err != nil { 2567 t.Fatal(err) 2568 } 2569 cB.Flush() 2570 2571 ///////////////////////////////////////////////////////////////////////////////// 2572 // // 2573 // Switch all the certs from server A, all OCSP monitors should be restarted // 2574 // so it should have new staples. // 2575 // // 2576 ///////////////////////////////////////////////////////////////////////////////// 2577 srvConfA = ` 2578 host: "127.0.0.1" 2579 port: -1 2580 2581 server_name: "AAA" 2582 2583 ocsp { mode = always } 2584 2585 store_dir: '%s' 2586 gateway { 2587 name: A 2588 host: "127.0.0.1" 2589 port: -1 2590 advertise: "127.0.0.1" 2591 2592 tls { 2593 cert_file: "configs/certs/ocsp/server-status-request-url-08-cert.pem" 2594 key_file: "configs/certs/ocsp/server-status-request-url-08-key.pem" 2595 ca_file: "configs/certs/ocsp/ca-cert.pem" 2596 timeout: 5 2597 } 2598 } 2599 ` 2600 2601 srvConfA = fmt.Sprintf(srvConfA, storeDirA) 2602 if err := os.WriteFile(sconfA, []byte(srvConfA), 0666); err != nil { 2603 t.Fatalf("Error writing config: %v", err) 2604 } 2605 if err := srvA.Reload(); err != nil { 2606 t.Fatal(err) 2607 } 2608 waitForOutboundGateways(t, srvA, 2, 5*time.Second) 2609 waitForOutboundGateways(t, srvB, 2, 5*time.Second) 2610 waitForOutboundGateways(t, srvC, 2, 5*time.Second) 2611 2612 // Now clients connect to C can communicate with B and A. 2613 _, err = cC.Request("foo", nil, 2*time.Second) 2614 if err != nil { 2615 t.Errorf("%v", err) 2616 } 2617 _, err = cC.Request("bar", nil, 2*time.Second) 2618 if err != nil { 2619 t.Errorf("%v", err) 2620 } 2621 } 2622 2623 func TestOCSPCustomConfig(t *testing.T) { 2624 const ( 2625 caCert = "configs/certs/ocsp/ca-cert.pem" 2626 caKey = "configs/certs/ocsp/ca-key.pem" 2627 serverCert = "configs/certs/ocsp/server-cert.pem" 2628 serverKey = "configs/certs/ocsp/server-key.pem" 2629 ) 2630 2631 ctx, cancel := context.WithCancel(context.Background()) 2632 defer cancel() 2633 ocspr := newOCSPResponder(t, caCert, caKey) 2634 ocspURL := fmt.Sprintf("http://%s", ocspr.Addr) 2635 defer ocspr.Shutdown(ctx) 2636 2637 var ( 2638 errExpectedNoStaple = fmt.Errorf("expected no staple") 2639 errMissingStaple = fmt.Errorf("missing OCSP Staple from server") 2640 ) 2641 2642 for _, test := range []struct { 2643 name string 2644 config string 2645 opts []nats.Option 2646 err error 2647 rerr error 2648 configure func() 2649 }{ 2650 { 2651 "OCSP Stapling in auto mode makes server fail to boot if status is revoked", 2652 ` 2653 port: -1 2654 2655 ocsp { 2656 mode: auto 2657 } 2658 2659 tls { 2660 cert_file: "configs/certs/ocsp/server-cert.pem" 2661 key_file: "configs/certs/ocsp/server-key.pem" 2662 ca_file: "configs/certs/ocsp/ca-cert.pem" 2663 timeout: 5 2664 } 2665 `, 2666 []nats.Option{ 2667 nats.Secure(&tls.Config{ 2668 VerifyConnection: func(s tls.ConnectionState) error { 2669 if s.OCSPResponse != nil { 2670 return errExpectedNoStaple 2671 } 2672 return nil 2673 }, 2674 }), 2675 nats.ClientCert("./configs/certs/ocsp/client-cert.pem", "./configs/certs/ocsp/client-key.pem"), 2676 nats.RootCAs(caCert), 2677 nats.ErrorHandler(noOpErrHandler), 2678 }, 2679 nil, 2680 nil, 2681 func() { setOCSPStatus(t, ocspURL, serverCert, ocsp.Revoked) }, 2682 }, 2683 { 2684 "OCSP Stapling must staple ignored if disabled with ocsp: false", 2685 ` 2686 port: -1 2687 2688 ocsp: false 2689 2690 tls { 2691 cert_file: "configs/certs/ocsp/server-status-request-url-01-cert.pem" 2692 key_file: "configs/certs/ocsp/server-status-request-url-01-key.pem" 2693 ca_file: "configs/certs/ocsp/ca-cert.pem" 2694 timeout: 5 2695 } 2696 `, 2697 []nats.Option{ 2698 nats.Secure(&tls.Config{ 2699 VerifyConnection: func(s tls.ConnectionState) error { 2700 if s.OCSPResponse != nil { 2701 return errExpectedNoStaple 2702 } 2703 return nil 2704 }, 2705 }), 2706 nats.ClientCert("./configs/certs/ocsp/client-cert.pem", "./configs/certs/ocsp/client-key.pem"), 2707 nats.RootCAs(caCert), 2708 nats.ErrorHandler(noOpErrHandler), 2709 }, 2710 nil, 2711 nil, 2712 func() { 2713 setOCSPStatus(t, ocspURL, "configs/certs/ocsp/server-status-request-url-01-cert.pem", ocsp.Good) 2714 }, 2715 }, 2716 { 2717 "OCSP Stapling must staple ignored if disabled with ocsp mode never", 2718 ` 2719 port: -1 2720 2721 ocsp: { mode: never } 2722 2723 tls { 2724 cert_file: "configs/certs/ocsp/server-status-request-url-01-cert.pem" 2725 key_file: "configs/certs/ocsp/server-status-request-url-01-key.pem" 2726 ca_file: "configs/certs/ocsp/ca-cert.pem" 2727 timeout: 5 2728 } 2729 `, 2730 []nats.Option{ 2731 nats.Secure(&tls.Config{ 2732 VerifyConnection: func(s tls.ConnectionState) error { 2733 if s.OCSPResponse != nil { 2734 return errExpectedNoStaple 2735 } 2736 return nil 2737 }, 2738 }), 2739 nats.ClientCert("./configs/certs/ocsp/client-cert.pem", "./configs/certs/ocsp/client-key.pem"), 2740 nats.RootCAs(caCert), 2741 nats.ErrorHandler(noOpErrHandler), 2742 }, 2743 nil, 2744 nil, 2745 func() { 2746 setOCSPStatus(t, ocspURL, "configs/certs/ocsp/server-status-request-url-01-cert.pem", ocsp.Good) 2747 }, 2748 }, 2749 { 2750 "OCSP Stapling in always mode fetches a staple even if cert does not have one", 2751 ` 2752 port: -1 2753 2754 ocsp { 2755 mode: always 2756 url: "http://127.0.0.1:8888" 2757 } 2758 2759 tls { 2760 cert_file: "configs/certs/ocsp/server-cert.pem" 2761 key_file: "configs/certs/ocsp/server-key.pem" 2762 ca_file: "configs/certs/ocsp/ca-cert.pem" 2763 timeout: 5 2764 } 2765 `, 2766 []nats.Option{ 2767 nats.Secure(&tls.Config{ 2768 VerifyConnection: func(s tls.ConnectionState) error { 2769 if s.OCSPResponse == nil { 2770 return errMissingStaple 2771 } 2772 return nil 2773 }, 2774 }), 2775 nats.ClientCert("./configs/certs/ocsp/client-cert.pem", "./configs/certs/ocsp/client-key.pem"), 2776 nats.RootCAs(caCert), 2777 nats.ErrorHandler(noOpErrHandler), 2778 }, 2779 nil, 2780 nil, 2781 func() { setOCSPStatus(t, ocspURL, serverCert, ocsp.Good) }, 2782 }, 2783 { 2784 "OCSP Stapling in must staple mode does not fetch staple if there is no must staple flag", 2785 ` 2786 port: -1 2787 2788 ocsp { 2789 mode: must 2790 url: "http://127.0.0.1:8888" 2791 } 2792 2793 tls { 2794 cert_file: "configs/certs/ocsp/server-cert.pem" 2795 key_file: "configs/certs/ocsp/server-key.pem" 2796 ca_file: "configs/certs/ocsp/ca-cert.pem" 2797 timeout: 5 2798 } 2799 `, 2800 []nats.Option{ 2801 nats.Secure(&tls.Config{ 2802 VerifyConnection: func(s tls.ConnectionState) error { 2803 if s.OCSPResponse != nil { 2804 return errExpectedNoStaple 2805 } 2806 return nil 2807 }, 2808 }), 2809 nats.ClientCert("./configs/certs/ocsp/client-cert.pem", "./configs/certs/ocsp/client-key.pem"), 2810 nats.RootCAs(caCert), 2811 nats.ErrorHandler(noOpErrHandler), 2812 }, 2813 nil, 2814 nil, 2815 func() { setOCSPStatus(t, ocspURL, serverCert, ocsp.Good) }, 2816 }, 2817 { 2818 "OCSP Stapling in must staple mode fetches staple if there is a must staple flag", 2819 ` 2820 port: -1 2821 2822 ocsp { 2823 mode: must 2824 url: "http://127.0.0.1:8888" 2825 } 2826 2827 tls { 2828 cert_file: "configs/certs/ocsp/server-status-request-url-01-cert.pem" 2829 key_file: "configs/certs/ocsp/server-status-request-url-01-key.pem" 2830 ca_file: "configs/certs/ocsp/ca-cert.pem" 2831 timeout: 5 2832 } 2833 `, 2834 []nats.Option{ 2835 nats.Secure(&tls.Config{ 2836 VerifyConnection: func(s tls.ConnectionState) error { 2837 if s.OCSPResponse == nil { 2838 return errMissingStaple 2839 } 2840 return nil 2841 }, 2842 }), 2843 nats.ClientCert("./configs/certs/ocsp/client-cert.pem", "./configs/certs/ocsp/client-key.pem"), 2844 nats.RootCAs(caCert), 2845 nats.ErrorHandler(noOpErrHandler), 2846 }, 2847 nil, 2848 nil, 2849 func() { 2850 setOCSPStatus(t, ocspURL, "configs/certs/ocsp/server-status-request-url-01-cert.pem", ocsp.Good) 2851 }, 2852 }, 2853 } { 2854 t.Run(test.name, func(t *testing.T) { 2855 test.configure() 2856 content := test.config 2857 conf := createConfFile(t, []byte(content)) 2858 s, opts := RunServerWithConfig(conf) 2859 defer s.Shutdown() 2860 2861 nc, err := nats.Connect(fmt.Sprintf("tls://localhost:%d", opts.Port), test.opts...) 2862 if test.err == nil && err != nil { 2863 t.Errorf("Expected to connect, got %v", err) 2864 } else if test.err != nil && err == nil { 2865 t.Errorf("Expected error on connect") 2866 } else if test.err != nil && err != nil { 2867 // Error on connect was expected 2868 if test.err.Error() != err.Error() { 2869 t.Errorf("Expected error %s, got: %s", test.err, err) 2870 } 2871 return 2872 } 2873 defer nc.Close() 2874 2875 nc.Subscribe("ping", func(m *nats.Msg) { 2876 m.Respond([]byte("pong")) 2877 }) 2878 nc.Flush() 2879 2880 _, err = nc.Request("ping", []byte("ping"), 250*time.Millisecond) 2881 if test.rerr != nil && err == nil { 2882 t.Errorf("Expected error getting response") 2883 } else if test.rerr == nil && err != nil { 2884 t.Errorf("Expected response") 2885 } 2886 }) 2887 } 2888 } 2889 2890 func TestOCSPCustomConfigReloadDisable(t *testing.T) { 2891 const ( 2892 caCert = "configs/certs/ocsp/ca-cert.pem" 2893 caKey = "configs/certs/ocsp/ca-key.pem" 2894 serverCert = "configs/certs/ocsp/server-cert.pem" 2895 updatedServerCert = "configs/certs/ocsp/server-status-request-url-01-cert.pem" 2896 ) 2897 ctx, cancel := context.WithCancel(context.Background()) 2898 defer cancel() 2899 ocspr := newOCSPResponder(t, caCert, caKey) 2900 defer ocspr.Shutdown(ctx) 2901 addr := fmt.Sprintf("http://%s", ocspr.Addr) 2902 setOCSPStatus(t, addr, serverCert, ocsp.Good) 2903 setOCSPStatus(t, addr, updatedServerCert, ocsp.Good) 2904 2905 // Start with server without OCSP Stapling MustStaple 2906 content := ` 2907 port: -1 2908 2909 ocsp: { mode: always, url: "http://127.0.0.1:8888" } 2910 2911 tls { 2912 cert_file: "configs/certs/ocsp/server-cert.pem" 2913 key_file: "configs/certs/ocsp/server-key.pem" 2914 ca_file: "configs/certs/ocsp/ca-cert.pem" 2915 timeout: 5 2916 } 2917 ` 2918 conf := createConfFile(t, []byte(content)) 2919 s, opts := RunServerWithConfig(conf) 2920 defer s.Shutdown() 2921 2922 nc, err := nats.Connect(fmt.Sprintf("tls://localhost:%d", opts.Port), 2923 nats.Secure(&tls.Config{ 2924 VerifyConnection: func(s tls.ConnectionState) error { 2925 if s.OCSPResponse == nil { 2926 return fmt.Errorf("missing OCSP Staple!") 2927 } 2928 return nil 2929 }, 2930 }), 2931 nats.RootCAs(caCert), 2932 nats.ErrorHandler(noOpErrHandler), 2933 ) 2934 if err != nil { 2935 t.Fatal(err) 2936 } 2937 defer nc.Close() 2938 sub, err := nc.SubscribeSync("foo") 2939 if err != nil { 2940 t.Fatal(err) 2941 } 2942 nc.Publish("foo", []byte("hello world")) 2943 nc.Flush() 2944 2945 _, err = sub.NextMsg(1 * time.Second) 2946 if err != nil { 2947 t.Fatal(err) 2948 } 2949 nc.Close() 2950 2951 // Change and disable OCSP Stapling. 2952 content = ` 2953 port: -1 2954 2955 ocsp: { mode: never } 2956 2957 tls { 2958 cert_file: "configs/certs/ocsp/server-status-request-url-01-cert.pem" 2959 key_file: "configs/certs/ocsp/server-status-request-url-01-key.pem" 2960 ca_file: "configs/certs/ocsp/ca-cert.pem" 2961 timeout: 5 2962 } 2963 ` 2964 if err := os.WriteFile(conf, []byte(content), 0666); err != nil { 2965 t.Fatalf("Error writing config: %v", err) 2966 } 2967 if err := s.Reload(); err != nil { 2968 t.Fatal(err) 2969 } 2970 2971 // The new certificate has must staple but OCSP Stapling is disabled. 2972 time.Sleep(2 * time.Second) 2973 2974 nc, err = nats.Connect(fmt.Sprintf("tls://localhost:%d", opts.Port), 2975 nats.Secure(&tls.Config{ 2976 VerifyConnection: func(s tls.ConnectionState) error { 2977 if s.OCSPResponse != nil { 2978 return fmt.Errorf("unexpected OCSP Staple!") 2979 } 2980 return nil 2981 }, 2982 }), 2983 nats.RootCAs(caCert), 2984 nats.ErrorHandler(noOpErrHandler), 2985 ) 2986 if err != nil { 2987 t.Fatal(err) 2988 } 2989 nc.Close() 2990 } 2991 2992 func TestOCSPCustomConfigReloadEnable(t *testing.T) { 2993 const ( 2994 caCert = "configs/certs/ocsp/ca-cert.pem" 2995 caKey = "configs/certs/ocsp/ca-key.pem" 2996 serverCert = "configs/certs/ocsp/server-cert.pem" 2997 updatedServerCert = "configs/certs/ocsp/server-status-request-url-01-cert.pem" 2998 ) 2999 ctx, cancel := context.WithCancel(context.Background()) 3000 defer cancel() 3001 ocspr := newOCSPResponder(t, caCert, caKey) 3002 defer ocspr.Shutdown(ctx) 3003 addr := fmt.Sprintf("http://%s", ocspr.Addr) 3004 setOCSPStatus(t, addr, serverCert, ocsp.Good) 3005 setOCSPStatus(t, addr, updatedServerCert, ocsp.Good) 3006 3007 // Start with server without OCSP Stapling MustStaple 3008 content := ` 3009 port: -1 3010 3011 ocsp: { mode: never, url: "http://127.0.0.1:8888" } 3012 3013 tls { 3014 cert_file: "configs/certs/ocsp/server-status-request-url-01-cert.pem" 3015 key_file: "configs/certs/ocsp/server-status-request-url-01-key.pem" 3016 ca_file: "configs/certs/ocsp/ca-cert.pem" 3017 timeout: 5 3018 } 3019 ` 3020 conf := createConfFile(t, []byte(content)) 3021 s, opts := RunServerWithConfig(conf) 3022 defer s.Shutdown() 3023 3024 nc, err := nats.Connect(fmt.Sprintf("tls://localhost:%d", opts.Port), 3025 nats.Secure(&tls.Config{ 3026 VerifyConnection: func(s tls.ConnectionState) error { 3027 if s.OCSPResponse != nil { 3028 return fmt.Errorf("unexpected OCSP Staple!") 3029 } 3030 return nil 3031 }, 3032 }), 3033 nats.RootCAs(caCert), 3034 nats.ErrorHandler(noOpErrHandler), 3035 ) 3036 if err != nil { 3037 t.Fatal(err) 3038 } 3039 defer nc.Close() 3040 sub, err := nc.SubscribeSync("foo") 3041 if err != nil { 3042 t.Fatal(err) 3043 } 3044 nc.Publish("foo", []byte("hello world")) 3045 nc.Flush() 3046 3047 _, err = sub.NextMsg(1 * time.Second) 3048 if err != nil { 3049 t.Fatal(err) 3050 } 3051 nc.Close() 3052 3053 // Change and disable OCSP Stapling. 3054 content = ` 3055 port: -1 3056 3057 ocsp: { mode: always, url: "http://127.0.0.1:8888" } 3058 3059 tls { 3060 cert_file: "configs/certs/ocsp/server-status-request-url-01-cert.pem" 3061 key_file: "configs/certs/ocsp/server-status-request-url-01-key.pem" 3062 ca_file: "configs/certs/ocsp/ca-cert.pem" 3063 timeout: 5 3064 } 3065 ` 3066 if err := os.WriteFile(conf, []byte(content), 0666); err != nil { 3067 t.Fatalf("Error writing config: %v", err) 3068 } 3069 if err := s.Reload(); err != nil { 3070 t.Fatal(err) 3071 } 3072 time.Sleep(2 * time.Second) 3073 3074 nc, err = nats.Connect(fmt.Sprintf("tls://localhost:%d", opts.Port), 3075 nats.Secure(&tls.Config{ 3076 VerifyConnection: func(s tls.ConnectionState) error { 3077 if s.OCSPResponse == nil { 3078 return fmt.Errorf("missing OCSP Staple!") 3079 } 3080 return nil 3081 }, 3082 }), 3083 nats.RootCAs(caCert), 3084 nats.ErrorHandler(noOpErrHandler), 3085 ) 3086 if err != nil { 3087 t.Fatal(err) 3088 } 3089 nc.Close() 3090 } 3091 3092 func newOCSPResponderCustomAddress(t *testing.T, issuerCertPEM, issuerKeyPEM string, addr string) *http.Server { 3093 t.Helper() 3094 return newOCSPResponderBase(t, issuerCertPEM, issuerCertPEM, issuerKeyPEM, false, addr, defaultResponseTTL, "") 3095 } 3096 3097 func newOCSPResponder(t *testing.T, issuerCertPEM, issuerKeyPEM string) *http.Server { 3098 t.Helper() 3099 return newOCSPResponderBase(t, issuerCertPEM, issuerCertPEM, issuerKeyPEM, false, defaultAddress, defaultResponseTTL, "") 3100 } 3101 3102 func newOCSPResponderDesignatedCustomAddress(t *testing.T, issuerCertPEM, respCertPEM, respKeyPEM string, addr string) *http.Server { 3103 t.Helper() 3104 return newOCSPResponderBase(t, issuerCertPEM, respCertPEM, respKeyPEM, true, addr, defaultResponseTTL, "") 3105 } 3106 3107 func newOCSPResponderPreferringHTTPMethod(t *testing.T, issuerCertPEM, issuerKeyPEM, method string) *http.Server { 3108 t.Helper() 3109 return newOCSPResponderBase(t, issuerCertPEM, issuerCertPEM, issuerKeyPEM, false, defaultAddress, defaultResponseTTL, method) 3110 } 3111 3112 func newOCSPResponderBase(t *testing.T, issuerCertPEM, respCertPEM, respKeyPEM string, embed bool, addr string, responseTTL time.Duration, method string) *http.Server { 3113 t.Helper() 3114 var mu sync.Mutex 3115 status := make(map[string]int) 3116 3117 issuerCert := parseCertPEM(t, issuerCertPEM) 3118 respCert := parseCertPEM(t, respCertPEM) 3119 respKey := parseKeyPEM(t, respKeyPEM) 3120 3121 mux := http.NewServeMux() 3122 // The "/statuses/" endpoint is for directly setting a key-value pair in 3123 // the CA's status database. 3124 mux.HandleFunc("/statuses/", func(rw http.ResponseWriter, r *http.Request) { 3125 defer r.Body.Close() 3126 3127 key := r.URL.Path[len("/statuses/"):] 3128 switch r.Method { 3129 case "GET": 3130 mu.Lock() 3131 n, ok := status[key] 3132 if !ok { 3133 n = ocsp.Unknown 3134 } 3135 mu.Unlock() 3136 3137 fmt.Fprintf(rw, "%s %d", key, n) 3138 case "POST": 3139 data, err := io.ReadAll(r.Body) 3140 if err != nil { 3141 http.Error(rw, err.Error(), http.StatusBadRequest) 3142 return 3143 } 3144 3145 n, err := strconv.Atoi(string(data)) 3146 if err != nil { 3147 http.Error(rw, err.Error(), http.StatusBadRequest) 3148 return 3149 } 3150 3151 mu.Lock() 3152 status[key] = n 3153 mu.Unlock() 3154 3155 fmt.Fprintf(rw, "%s %d", key, n) 3156 default: 3157 http.Error(rw, "Method Not Allowed", http.StatusMethodNotAllowed) 3158 return 3159 } 3160 }) 3161 // The "/" endpoint is for normal OCSP requests. This actually parses an 3162 // OCSP status request and signs a response with a CA. Lightly based off: 3163 // https://www.ietf.org/rfc/rfc2560.txt 3164 mux.HandleFunc("/", func(rw http.ResponseWriter, r *http.Request) { 3165 var reqData []byte 3166 var err error 3167 3168 switch { 3169 case r.Method == "GET": 3170 if method != "" && r.Method != method { 3171 http.Error(rw, "", http.StatusBadRequest) 3172 return 3173 } 3174 reqData, err = base64.StdEncoding.DecodeString(r.URL.Path[1:]) 3175 case r.Method == "POST": 3176 if method != "" && r.Method != method { 3177 http.Error(rw, "", http.StatusBadRequest) 3178 return 3179 } 3180 reqData, err = io.ReadAll(r.Body) 3181 default: 3182 http.Error(rw, "Method Not Allowed", http.StatusMethodNotAllowed) 3183 return 3184 } 3185 if err != nil { 3186 http.Error(rw, err.Error(), http.StatusBadRequest) 3187 return 3188 } 3189 3190 ocspReq, err := ocsp.ParseRequest(reqData) 3191 if err != nil { 3192 http.Error(rw, err.Error(), http.StatusBadRequest) 3193 return 3194 } 3195 3196 mu.Lock() 3197 n, ok := status[ocspReq.SerialNumber.String()] 3198 if !ok { 3199 n = ocsp.Unknown 3200 } 3201 mu.Unlock() 3202 3203 tmpl := ocsp.Response{ 3204 Status: n, 3205 SerialNumber: ocspReq.SerialNumber, 3206 ThisUpdate: time.Now(), 3207 } 3208 if responseTTL != 0 { 3209 tmpl.NextUpdate = tmpl.ThisUpdate.Add(responseTTL) 3210 } 3211 if embed { 3212 tmpl.Certificate = respCert 3213 } 3214 respData, err := ocsp.CreateResponse(issuerCert, respCert, tmpl, respKey) 3215 if err != nil { 3216 http.Error(rw, err.Error(), http.StatusInternalServerError) 3217 return 3218 } 3219 3220 rw.Header().Set("Content-Type", "application/ocsp-response") 3221 rw.Header().Set("Content-Length", fmt.Sprint(len(respData))) 3222 3223 fmt.Fprint(rw, string(respData)) 3224 }) 3225 3226 srv := &http.Server{ 3227 Addr: addr, 3228 Handler: mux, 3229 } 3230 go srv.ListenAndServe() 3231 time.Sleep(1 * time.Second) 3232 return srv 3233 } 3234 3235 func setOCSPStatus(t *testing.T, ocspURL, certPEM string, status int) { 3236 t.Helper() 3237 3238 cert := parseCertPEM(t, certPEM) 3239 3240 hc := &http.Client{Timeout: 10 * time.Second} 3241 resp, err := hc.Post( 3242 fmt.Sprintf("%s/statuses/%s", ocspURL, cert.SerialNumber), 3243 "", 3244 strings.NewReader(fmt.Sprint(status)), 3245 ) 3246 if err != nil { 3247 t.Fatal(err) 3248 } 3249 defer resp.Body.Close() 3250 3251 data, err := io.ReadAll(resp.Body) 3252 if err != nil { 3253 t.Fatalf("failed to read OCSP HTTP response body: %s", err) 3254 } 3255 3256 if got, want := resp.Status, "200 OK"; got != want { 3257 t.Error(strings.TrimSpace(string(data))) 3258 t.Fatalf("unexpected OCSP HTTP set status, got %q, want %q", got, want) 3259 } 3260 } 3261 3262 func parseCertPEM(t *testing.T, certPEM string) *x509.Certificate { 3263 t.Helper() 3264 block := parsePEM(t, certPEM) 3265 3266 cert, err := x509.ParseCertificate(block.Bytes) 3267 if err != nil { 3268 t.Fatalf("failed to parse cert '%s': %s", certPEM, err) 3269 } 3270 return cert 3271 } 3272 3273 func parseKeyPEM(t *testing.T, keyPEM string) crypto.Signer { 3274 t.Helper() 3275 block := parsePEM(t, keyPEM) 3276 3277 key, err := x509.ParsePKCS8PrivateKey(block.Bytes) 3278 if err != nil { 3279 key, err = x509.ParsePKCS1PrivateKey(block.Bytes) 3280 if err != nil { 3281 t.Fatalf("failed to parse ikey %s: %s", keyPEM, err) 3282 } 3283 } 3284 keyc := key.(crypto.Signer) 3285 return keyc 3286 } 3287 3288 func parsePEM(t *testing.T, pemPath string) *pem.Block { 3289 t.Helper() 3290 data, err := os.ReadFile(pemPath) 3291 if err != nil { 3292 t.Fatal(err) 3293 } 3294 3295 block, _ := pem.Decode(data) 3296 if block == nil { 3297 t.Fatalf("failed to decode PEM %s", pemPath) 3298 } 3299 return block 3300 } 3301 3302 func getOCSPStatus(s tls.ConnectionState) (*ocsp.Response, error) { 3303 if len(s.VerifiedChains) == 0 { 3304 return nil, fmt.Errorf("missing TLS verified chains") 3305 } 3306 chain := s.VerifiedChains[0] 3307 3308 if got, want := len(chain), 2; got < want { 3309 return nil, fmt.Errorf("incomplete cert chain, got %d, want at least %d", got, want) 3310 } 3311 leaf, issuer := chain[0], chain[1] 3312 3313 resp, err := ocsp.ParseResponseForCert(s.OCSPResponse, leaf, issuer) 3314 if err != nil { 3315 return nil, fmt.Errorf("failed to parse OCSP response: %w", err) 3316 } 3317 if err := resp.CheckSignatureFrom(issuer); err != nil { 3318 return resp, err 3319 } 3320 return resp, nil 3321 } 3322 3323 func TestOCSPTLSConfigNoLeafSet(t *testing.T) { 3324 o := DefaultTestOptions 3325 o.HTTPHost = "127.0.0.1" 3326 o.HTTPSPort = -1 3327 o.TLSConfig = &tls.Config{ServerName: "localhost"} 3328 cert, err := tls.LoadX509KeyPair("configs/certs/server-cert.pem", "configs/certs/server-key.pem") 3329 if err != nil { 3330 t.Fatalf("Got error reading certificates: %s", err) 3331 } 3332 o.TLSConfig.Certificates = []tls.Certificate{cert} 3333 s := RunServer(&o) 3334 s.Shutdown() 3335 } 3336 3337 func TestOCSPSuperCluster(t *testing.T) { 3338 const ( 3339 caCert = "configs/certs/ocsp/ca-cert.pem" 3340 caKey = "configs/certs/ocsp/ca-key.pem" 3341 ) 3342 ctx, cancel := context.WithCancel(context.Background()) 3343 defer cancel() 3344 ocspr := newOCSPResponder(t, caCert, caKey) 3345 defer ocspr.Shutdown(ctx) 3346 addr := fmt.Sprintf("http://%s", ocspr.Addr) 3347 setOCSPStatus(t, addr, "configs/certs/ocsp/server-status-request-url-01-cert.pem", ocsp.Good) 3348 setOCSPStatus(t, addr, "configs/certs/ocsp/server-status-request-url-02-cert.pem", ocsp.Good) 3349 setOCSPStatus(t, addr, "configs/certs/ocsp/server-status-request-url-03-cert.pem", ocsp.Good) 3350 setOCSPStatus(t, addr, "configs/certs/ocsp/server-status-request-url-04-cert.pem", ocsp.Good) 3351 setOCSPStatus(t, addr, "configs/certs/ocsp/server-status-request-url-05-cert.pem", ocsp.Good) 3352 setOCSPStatus(t, addr, "configs/certs/ocsp/server-status-request-url-06-cert.pem", ocsp.Good) 3353 setOCSPStatus(t, addr, "configs/certs/ocsp/server-status-request-url-07-cert.pem", ocsp.Good) 3354 setOCSPStatus(t, addr, "configs/certs/ocsp/server-status-request-url-08-cert.pem", ocsp.Good) 3355 setOCSPStatus(t, addr, "configs/certs/ocsp/server-cert.pem", ocsp.Good) 3356 3357 // Store Dirs 3358 storeDirA := t.TempDir() 3359 storeDirB := t.TempDir() 3360 storeDirC := t.TempDir() 3361 storeDirD := t.TempDir() 3362 3363 // Gateway server configuration 3364 srvConfA := ` 3365 host: "127.0.0.1" 3366 port: -1 3367 3368 server_name: "A" 3369 3370 ocsp { mode: "always" } 3371 3372 tls { 3373 cert_file: "configs/certs/ocsp/server-status-request-url-01-cert.pem" 3374 key_file: "configs/certs/ocsp/server-status-request-url-01-key.pem" 3375 ca_file: "configs/certs/ocsp/ca-cert.pem" 3376 timeout: 5 3377 } 3378 store_dir: '%s' 3379 3380 cluster { 3381 name: A 3382 host: "127.0.0.1" 3383 advertise: 127.0.0.1 3384 port: -1 3385 3386 tls { 3387 cert_file: "configs/certs/ocsp/server-status-request-url-02-cert.pem" 3388 key_file: "configs/certs/ocsp/server-status-request-url-02-key.pem" 3389 ca_file: "configs/certs/ocsp/ca-cert.pem" 3390 timeout: 5 3391 } 3392 } 3393 3394 gateway { 3395 name: A 3396 host: "127.0.0.1" 3397 port: -1 3398 advertise: "127.0.0.1" 3399 3400 tls { 3401 cert_file: "configs/certs/ocsp/server-status-request-url-03-cert.pem" 3402 key_file: "configs/certs/ocsp/server-status-request-url-03-key.pem" 3403 ca_file: "configs/certs/ocsp/ca-cert.pem" 3404 timeout: 5 3405 verify: true 3406 } 3407 } 3408 ` 3409 srvConfA = fmt.Sprintf(srvConfA, storeDirA) 3410 sconfA := createConfFile(t, []byte(srvConfA)) 3411 srvA, optsA := RunServerWithConfig(sconfA) 3412 defer srvA.Shutdown() 3413 3414 // Server that has the original as a cluster. 3415 srvConfB := ` 3416 host: "127.0.0.1" 3417 port: -1 3418 3419 server_name: "B" 3420 3421 ocsp { mode: "always" } 3422 3423 tls { 3424 cert_file: "configs/certs/ocsp/server-status-request-url-01-cert.pem" 3425 key_file: "configs/certs/ocsp/server-status-request-url-01-key.pem" 3426 ca_file: "configs/certs/ocsp/ca-cert.pem" 3427 timeout: 5 3428 } 3429 store_dir: '%s' 3430 3431 cluster { 3432 name: A 3433 host: "127.0.0.1" 3434 advertise: 127.0.0.1 3435 port: -1 3436 3437 routes: [ nats://127.0.0.1:%d ] 3438 3439 tls { 3440 cert_file: "configs/certs/ocsp/server-status-request-url-02-cert.pem" 3441 key_file: "configs/certs/ocsp/server-status-request-url-02-key.pem" 3442 ca_file: "configs/certs/ocsp/ca-cert.pem" 3443 timeout: 5 3444 } 3445 } 3446 3447 gateway { 3448 name: A 3449 host: "127.0.0.1" 3450 advertise: "127.0.0.1" 3451 port: -1 3452 3453 tls { 3454 cert_file: "configs/certs/ocsp/server-status-request-url-03-cert.pem" 3455 key_file: "configs/certs/ocsp/server-status-request-url-03-key.pem" 3456 ca_file: "configs/certs/ocsp/ca-cert.pem" 3457 timeout: 5 3458 verify: true 3459 } 3460 } 3461 ` 3462 srvConfB = fmt.Sprintf(srvConfB, storeDirB, optsA.Cluster.Port) 3463 conf := createConfFile(t, []byte(srvConfB)) 3464 srvB, optsB := RunServerWithConfig(conf) 3465 defer srvB.Shutdown() 3466 3467 // Client connects to server A. 3468 cA, err := nats.Connect(fmt.Sprintf("tls://127.0.0.1:%d", optsA.Port), 3469 nats.Secure(&tls.Config{ 3470 VerifyConnection: func(s tls.ConnectionState) error { 3471 if s.OCSPResponse == nil { 3472 return fmt.Errorf("missing OCSP Staple from server") 3473 } 3474 return nil 3475 }, 3476 }), 3477 nats.RootCAs(caCert), 3478 nats.ErrorHandler(noOpErrHandler), 3479 ) 3480 if err != nil { 3481 t.Fatal(err) 3482 3483 } 3484 defer cA.Close() 3485 3486 // Start another server that will make connect as a gateway to cluster A. 3487 srvConfC := ` 3488 host: "127.0.0.1" 3489 port: -1 3490 3491 server_name: "C" 3492 3493 ocsp { mode: "always" } 3494 3495 tls { 3496 cert_file: "configs/certs/ocsp/server-status-request-url-05-cert.pem" 3497 key_file: "configs/certs/ocsp/server-status-request-url-05-key.pem" 3498 ca_file: "configs/certs/ocsp/ca-cert.pem" 3499 timeout: 5 3500 } 3501 store_dir: '%s' 3502 gateway { 3503 name: C 3504 host: "127.0.0.1" 3505 advertise: "127.0.0.1" 3506 port: -1 3507 gateways: [{ 3508 name: "A", 3509 urls: ["nats://127.0.0.1:%d"] 3510 tls { 3511 cert_file: "configs/certs/ocsp/server-status-request-url-06-cert.pem" 3512 key_file: "configs/certs/ocsp/server-status-request-url-06-key.pem" 3513 ca_file: "configs/certs/ocsp/ca-cert.pem" 3514 timeout: 5 3515 } 3516 }] 3517 tls { 3518 cert_file: "configs/certs/ocsp/server-status-request-url-06-cert.pem" 3519 key_file: "configs/certs/ocsp/server-status-request-url-06-key.pem" 3520 ca_file: "configs/certs/ocsp/ca-cert.pem" 3521 timeout: 5 3522 verify: true 3523 } 3524 } 3525 ` 3526 srvConfC = fmt.Sprintf(srvConfC, storeDirC, optsA.Gateway.Port) 3527 conf = createConfFile(t, []byte(srvConfC)) 3528 srvC, optsC := RunServerWithConfig(conf) 3529 defer srvC.Shutdown() 3530 3531 // Check that server is connected to any server from the other cluster. 3532 checkClusterFormed(t, srvA, srvB) 3533 waitForOutboundGateways(t, srvC, 1, 5*time.Second) 3534 3535 // Start one more server that will become another gateway. 3536 srvConfD := ` 3537 host: "127.0.0.1" 3538 port: -1 3539 3540 server_name: "D" 3541 3542 ocsp { mode: "auto", url: "%s" } 3543 3544 tls { 3545 cert_file: "configs/certs/ocsp/server-status-request-url-07-cert.pem" 3546 key_file: "configs/certs/ocsp/server-status-request-url-07-key.pem" 3547 ca_file: "configs/certs/ocsp/ca-cert.pem" 3548 timeout: 5 3549 } 3550 store_dir: '%s' 3551 gateway { 3552 name: D 3553 host: "127.0.0.1" 3554 advertise: "127.0.0.1" 3555 port: -1 3556 gateways: [{ 3557 name: "A", 3558 urls: ["nats://127.0.0.1:%d"] 3559 tls { 3560 cert_file: "configs/certs/ocsp/server-status-request-url-08-cert.pem" 3561 key_file: "configs/certs/ocsp/server-status-request-url-08-key.pem" 3562 ca_file: "configs/certs/ocsp/ca-cert.pem" 3563 timeout: 5 3564 }}, 3565 { 3566 name: "C", 3567 urls: ["nats://127.0.0.1:%d"] 3568 3569 #################################################################### 3570 ## TEST NOTE: This cert does not have an OCSP Staple intentionally## 3571 #################################################################### 3572 tls { 3573 ca_file: "configs/certs/ocsp/ca-cert.pem" 3574 cert_file: "configs/certs/ocsp/server-cert.pem" 3575 key_file: "configs/certs/ocsp/server-key.pem" 3576 timeout: 5 3577 }} 3578 ] 3579 tls { 3580 cert_file: "configs/certs/ocsp/server-status-request-url-08-cert.pem" 3581 key_file: "configs/certs/ocsp/server-status-request-url-08-key.pem" 3582 ca_file: "configs/certs/ocsp/ca-cert.pem" 3583 timeout: 5 3584 verify: true 3585 } 3586 } 3587 ` 3588 srvConfD = fmt.Sprintf(srvConfD, addr, storeDirD, optsA.Gateway.Port, optsC.Gateway.Port) 3589 conf = createConfFile(t, []byte(srvConfD)) 3590 srvD, _ := RunServerWithConfig(conf) 3591 defer srvD.Shutdown() 3592 3593 // There should be a single gateway here because one of the gateway connections does not have a OCSP staple. 3594 waitForOutboundGateways(t, srvD, 1, 10*time.Second) 3595 3596 // Connect to cluster A using server B. 3597 cB, err := nats.Connect(fmt.Sprintf("tls://127.0.0.1:%d", optsB.Port), 3598 nats.Secure(&tls.Config{ 3599 VerifyConnection: func(s tls.ConnectionState) error { 3600 if s.OCSPResponse == nil { 3601 return fmt.Errorf("missing OCSP Staple from server") 3602 } 3603 return nil 3604 }, 3605 }), 3606 nats.RootCAs(caCert), 3607 nats.ErrorHandler(noOpErrHandler), 3608 ) 3609 if err != nil { 3610 t.Fatal(err) 3611 } 3612 defer cB.Close() 3613 3614 // Connects to cluster C using server C. 3615 cC, err := nats.Connect(fmt.Sprintf("tls://127.0.0.1:%d", optsC.Port), 3616 nats.Secure(&tls.Config{ 3617 VerifyConnection: func(s tls.ConnectionState) error { 3618 if s.OCSPResponse == nil { 3619 return fmt.Errorf("missing OCSP Staple from server") 3620 } 3621 return nil 3622 }, 3623 }), 3624 nats.RootCAs(caCert), 3625 nats.ErrorHandler(noOpErrHandler), 3626 ) 3627 if err != nil { 3628 t.Fatal(err) 3629 } 3630 defer cC.Close() 3631 3632 _, err = cA.Subscribe("foo", func(m *nats.Msg) { 3633 m.Respond([]byte("From Server A")) 3634 }) 3635 if err != nil { 3636 t.Errorf("%v", err) 3637 } 3638 cA.Flush() 3639 3640 _, err = cB.Subscribe("bar", func(m *nats.Msg) { 3641 m.Respond([]byte("From Server B")) 3642 }) 3643 if err != nil { 3644 t.Fatal(err) 3645 } 3646 cB.Flush() 3647 3648 // Confirm that a message from server C can flow back to server A via gateway.. 3649 var ( 3650 resp *nats.Msg 3651 lerr error 3652 ) 3653 for i := 0; i < 10; i++ { 3654 resp, lerr = cC.Request("foo", nil, 500*time.Millisecond) 3655 if lerr != nil { 3656 continue 3657 } 3658 got := string(resp.Data) 3659 expected := "From Server A" 3660 if got != expected { 3661 t.Fatalf("Expected %v, got: %v", expected, got) 3662 } 3663 3664 // Make request to B 3665 resp, lerr = cC.Request("bar", nil, 500*time.Millisecond) 3666 if lerr != nil { 3667 continue 3668 } 3669 got = string(resp.Data) 3670 expected = "From Server B" 3671 if got != expected { 3672 t.Errorf("Expected %v, got: %v", expected, got) 3673 } 3674 lerr = nil 3675 break 3676 } 3677 if lerr != nil { 3678 t.Errorf("Unexpected error: %v", lerr) 3679 } 3680 if n := srvD.NumOutboundGateways(); n > 1 { 3681 t.Errorf("Expected single gateway, got: %v", n) 3682 } 3683 } 3684 3685 func TestOCSPLocalIssuerDetermination(t *testing.T) { 3686 ctx, cancel := context.WithCancel(context.Background()) 3687 defer cancel() 3688 3689 intermediateCA1Responder := newOCSPResponderIntermediateCA1(t) 3690 intermediateCA1ResponderURL := fmt.Sprintf("http://%s", intermediateCA1Responder.Addr) 3691 defer intermediateCA1Responder.Shutdown(ctx) 3692 3693 // Test constants 3694 ocspURL := intermediateCA1ResponderURL 3695 clientTrustBundle := "configs/certs/ocsp_peer/mini-ca/misc/trust_config1_bundle.pem" 3696 serverCert := "configs/certs/ocsp_peer/mini-ca/server1/TestServer1_cert.pem" 3697 3698 var ( 3699 errMissingStaple = fmt.Errorf("missing OCSP Staple from server") 3700 ) 3701 3702 for _, test := range []struct { 3703 name string 3704 config string 3705 opts []nats.Option 3706 err error 3707 rerr error 3708 serverStart bool 3709 configure func() 3710 }{ 3711 { 3712 "Correct issuer configured in cert bundle", 3713 ` 3714 port: -1 3715 3716 ocsp { 3717 mode: always 3718 } 3719 3720 tls { 3721 cert_file: "configs/certs/ocsp_peer/mini-ca/server1/TestServer1_bundle.pem" 3722 key_file: "configs/certs/ocsp_peer/mini-ca/server1/private/TestServer1_keypair.pem" 3723 ca_file: "configs/certs/ocsp_peer/mini-ca/root/root_cert.pem" 3724 timeout: 5 3725 } 3726 `, 3727 []nats.Option{ 3728 nats.Secure(&tls.Config{ 3729 VerifyConnection: func(s tls.ConnectionState) error { 3730 if s.OCSPResponse == nil { 3731 return errMissingStaple 3732 } 3733 return nil 3734 }, 3735 }), 3736 nats.ClientCert("./configs/certs/ocsp/client-cert.pem", "./configs/certs/ocsp/client-key.pem"), 3737 nats.RootCAs(clientTrustBundle), 3738 nats.ErrorHandler(noOpErrHandler), 3739 }, 3740 nil, 3741 nil, 3742 true, 3743 func() { 3744 setOCSPStatus(t, ocspURL, serverCert, ocsp.Good) 3745 }, 3746 }, 3747 { 3748 "Wrong issuer configured in cert bundle, server no start", 3749 ` 3750 port: -1 3751 3752 ocsp { 3753 mode: always 3754 } 3755 3756 tls { 3757 cert_file: "configs/certs/ocsp_peer/mini-ca/misc/misconfig_TestServer1_bundle.pem" 3758 key_file: "configs/certs/ocsp_peer/mini-ca/server1/private/TestServer1_keypair.pem" 3759 ca_file: "configs/certs/ocsp_peer/mini-ca/root/root_cert.pem" 3760 timeout: 5 3761 } 3762 `, 3763 []nats.Option{ 3764 nats.Secure(&tls.Config{ 3765 VerifyConnection: func(s tls.ConnectionState) error { 3766 if s.OCSPResponse == nil { 3767 return errMissingStaple 3768 } 3769 return nil 3770 }, 3771 }), 3772 nats.ClientCert("./configs/certs/ocsp/client-cert.pem", "./configs/certs/ocsp/client-key.pem"), 3773 nats.RootCAs(clientTrustBundle), 3774 nats.ErrorHandler(noOpErrHandler), 3775 }, 3776 nil, 3777 nil, 3778 false, 3779 func() { 3780 setOCSPStatus(t, ocspURL, serverCert, ocsp.Good) 3781 }, 3782 }, 3783 { 3784 "Issuer configured in CA bundle only, configuration 1", 3785 ` 3786 port: -1 3787 3788 ocsp { 3789 mode: always 3790 } 3791 3792 tls { 3793 cert_file: "configs/certs/ocsp_peer/mini-ca/server1/TestServer1_cert.pem" 3794 key_file: "configs/certs/ocsp_peer/mini-ca/server1/private/TestServer1_keypair.pem" 3795 ca_file: "configs/certs/ocsp_peer/mini-ca/misc/trust_config1_bundle.pem" 3796 timeout: 5 3797 } 3798 `, 3799 []nats.Option{ 3800 nats.Secure(&tls.Config{ 3801 VerifyConnection: func(s tls.ConnectionState) error { 3802 if s.OCSPResponse == nil { 3803 return errMissingStaple 3804 } 3805 return nil 3806 }, 3807 }), 3808 nats.ClientCert("./configs/certs/ocsp/client-cert.pem", "./configs/certs/ocsp/client-key.pem"), 3809 nats.RootCAs(clientTrustBundle), 3810 nats.ErrorHandler(noOpErrHandler), 3811 }, 3812 nil, 3813 nil, 3814 true, 3815 func() { 3816 setOCSPStatus(t, ocspURL, serverCert, ocsp.Good) 3817 }, 3818 }, 3819 { 3820 "Issuer configured in CA bundle only, configuration 2", 3821 ` 3822 port: -1 3823 3824 ocsp { 3825 mode: always 3826 } 3827 3828 tls { 3829 cert_file: "configs/certs/ocsp_peer/mini-ca/server1/TestServer1_cert.pem" 3830 key_file: "configs/certs/ocsp_peer/mini-ca/server1/private/TestServer1_keypair.pem" 3831 ca_file: "configs/certs/ocsp_peer/mini-ca/misc/trust_config2_bundle.pem" 3832 timeout: 5 3833 } 3834 `, 3835 []nats.Option{ 3836 nats.Secure(&tls.Config{ 3837 VerifyConnection: func(s tls.ConnectionState) error { 3838 if s.OCSPResponse == nil { 3839 return errMissingStaple 3840 } 3841 return nil 3842 }, 3843 }), 3844 nats.ClientCert("./configs/certs/ocsp/client-cert.pem", "./configs/certs/ocsp/client-key.pem"), 3845 nats.RootCAs(clientTrustBundle), 3846 nats.ErrorHandler(noOpErrHandler), 3847 }, 3848 nil, 3849 nil, 3850 true, 3851 func() { 3852 setOCSPStatus(t, ocspURL, serverCert, ocsp.Good) 3853 }, 3854 }, 3855 { 3856 "Issuer configured in CA bundle only, configuration 3", 3857 ` 3858 port: -1 3859 3860 ocsp { 3861 mode: always 3862 } 3863 3864 tls { 3865 cert_file: "configs/certs/ocsp_peer/mini-ca/server1/TestServer1_cert.pem" 3866 key_file: "configs/certs/ocsp_peer/mini-ca/server1/private/TestServer1_keypair.pem" 3867 ca_file: "configs/certs/ocsp_peer/mini-ca/misc/trust_config3_bundle.pem" 3868 timeout: 5 3869 } 3870 `, 3871 []nats.Option{ 3872 nats.Secure(&tls.Config{ 3873 VerifyConnection: func(s tls.ConnectionState) error { 3874 if s.OCSPResponse == nil { 3875 return errMissingStaple 3876 } 3877 return nil 3878 }, 3879 }), 3880 nats.ClientCert("./configs/certs/ocsp/client-cert.pem", "./configs/certs/ocsp/client-key.pem"), 3881 nats.RootCAs(clientTrustBundle), 3882 nats.ErrorHandler(noOpErrHandler), 3883 }, 3884 nil, 3885 nil, 3886 true, 3887 func() { 3888 setOCSPStatus(t, ocspURL, serverCert, ocsp.Good) 3889 }, 3890 }, 3891 } { 3892 t.Run(test.name, func(t *testing.T) { 3893 defer func() { 3894 r := recover() 3895 if r != nil && test.serverStart { 3896 t.Fatalf("Expected server start, unexpected panic: %v", r) 3897 } 3898 if r == nil && !test.serverStart { 3899 t.Fatalf("Expected server to not start and panic thrown") 3900 } 3901 }() 3902 test.configure() 3903 content := test.config 3904 conf := createConfFile(t, []byte(content)) 3905 s, opts := RunServerWithConfig(conf) 3906 // server may not start for some tests 3907 if s != nil { 3908 defer s.Shutdown() 3909 } 3910 3911 nc, err := nats.Connect(fmt.Sprintf("tls://localhost:%d", opts.Port), test.opts...) 3912 if test.err == nil && err != nil { 3913 t.Errorf("Expected to connect, got %v", err) 3914 } else if test.err != nil && err == nil { 3915 t.Errorf("Expected error on connect") 3916 } else if test.err != nil && err != nil { 3917 // Error on connect was expected 3918 if test.err.Error() != err.Error() { 3919 t.Errorf("Expected error %s, got: %s", test.err, err) 3920 } 3921 return 3922 } 3923 defer nc.Close() 3924 3925 nc.Subscribe("ping", func(m *nats.Msg) { 3926 m.Respond([]byte("pong")) 3927 }) 3928 nc.Flush() 3929 3930 _, err = nc.Request("ping", []byte("ping"), 250*time.Millisecond) 3931 if test.rerr != nil && err == nil { 3932 t.Errorf("Expected error getting response") 3933 } else if test.rerr == nil && err != nil { 3934 t.Errorf("Expected response") 3935 } 3936 }) 3937 } 3938 } 3939 3940 func TestMixedCAOCSPSuperCluster(t *testing.T) { 3941 const ( 3942 caCert = "configs/certs/ocsp_peer/mini-ca/root/root_cert.pem" 3943 caKey = "configs/certs/ocsp/ca-key.pem" 3944 ) 3945 ctx, cancel := context.WithCancel(context.Background()) 3946 defer cancel() 3947 3948 intermediateCA1Responder := newOCSPResponderIntermediateCA1(t) 3949 intermediateCA1ResponderURL := fmt.Sprintf("http://%s", intermediateCA1Responder.Addr) 3950 defer intermediateCA1Responder.Shutdown(ctx) 3951 setOCSPStatus(t, intermediateCA1ResponderURL, "configs/certs/ocsp_peer/mini-ca/server1/TestServer1_cert.pem", ocsp.Good) 3952 3953 intermediateCA2Responder := newOCSPResponderIntermediateCA2(t) 3954 intermediateCA2ResponderURL := fmt.Sprintf("http://%s", intermediateCA2Responder.Addr) 3955 defer intermediateCA2Responder.Shutdown(ctx) 3956 setOCSPStatus(t, intermediateCA2ResponderURL, "configs/certs/ocsp_peer/mini-ca/server2/TestServer3_cert.pem", ocsp.Good) 3957 3958 // Store Dirs 3959 storeDirA := t.TempDir() 3960 storeDirB := t.TempDir() 3961 storeDirC := t.TempDir() 3962 3963 // Gateway server configuration 3964 srvConfA := ` 3965 host: "127.0.0.1" 3966 port: -1 3967 3968 server_name: "A" 3969 3970 ocsp { mode: "always" } 3971 3972 tls { 3973 cert_file: "configs/certs/ocsp_peer/mini-ca/server1/TestServer1_bundle.pem" 3974 key_file: "configs/certs/ocsp_peer/mini-ca/server1/private/TestServer1_keypair.pem" 3975 ca_file: "configs/certs/ocsp_peer/mini-ca/root/root_cert.pem" 3976 timeout: 5 3977 } 3978 store_dir: '%s' 3979 3980 cluster { 3981 name: A 3982 host: "127.0.0.1" 3983 advertise: 127.0.0.1 3984 port: -1 3985 3986 tls { 3987 cert_file: "configs/certs/ocsp_peer/mini-ca/server1/TestServer1_bundle.pem" 3988 key_file: "configs/certs/ocsp_peer/mini-ca/server1/private/TestServer1_keypair.pem" 3989 ca_file: "configs/certs/ocsp_peer/mini-ca/root/root_cert.pem" 3990 timeout: 5 3991 } 3992 } 3993 3994 gateway { 3995 name: A 3996 host: "127.0.0.1" 3997 port: -1 3998 advertise: "127.0.0.1" 3999 4000 tls { 4001 cert_file: "configs/certs/ocsp_peer/mini-ca/server1/TestServer1_bundle.pem" 4002 key_file: "configs/certs/ocsp_peer/mini-ca/server1/private/TestServer1_keypair.pem" 4003 ca_file: "configs/certs/ocsp_peer/mini-ca/root/root_cert.pem" 4004 timeout: 5 4005 verify: true 4006 } 4007 } 4008 ` 4009 srvConfA = fmt.Sprintf(srvConfA, storeDirA) 4010 sconfA := createConfFile(t, []byte(srvConfA)) 4011 srvA, optsA := RunServerWithConfig(sconfA) 4012 defer srvA.Shutdown() 4013 4014 // Server that has the original as a cluster. 4015 srvConfB := ` 4016 host: "127.0.0.1" 4017 port: -1 4018 4019 server_name: "B" 4020 4021 ocsp { mode: "always" } 4022 4023 tls { 4024 cert_file: "configs/certs/ocsp_peer/mini-ca/server1/TestServer1_bundle.pem" 4025 key_file: "configs/certs/ocsp_peer/mini-ca/server1/private/TestServer1_keypair.pem" 4026 ca_file: "configs/certs/ocsp_peer/mini-ca/root/root_cert.pem" 4027 timeout: 5 4028 } 4029 store_dir: '%s' 4030 4031 cluster { 4032 name: A 4033 host: "127.0.0.1" 4034 advertise: 127.0.0.1 4035 port: -1 4036 4037 routes: [ nats://127.0.0.1:%d ] 4038 4039 tls { 4040 cert_file: "configs/certs/ocsp_peer/mini-ca/server1/TestServer1_bundle.pem" 4041 key_file: "configs/certs/ocsp_peer/mini-ca/server1/private/TestServer1_keypair.pem" 4042 ca_file: "configs/certs/ocsp_peer/mini-ca/root/root_cert.pem" 4043 timeout: 5 4044 } 4045 } 4046 4047 gateway { 4048 name: A 4049 host: "127.0.0.1" 4050 advertise: "127.0.0.1" 4051 port: -1 4052 4053 tls { 4054 cert_file: "configs/certs/ocsp_peer/mini-ca/server1/TestServer1_bundle.pem" 4055 key_file: "configs/certs/ocsp_peer/mini-ca/server1/private/TestServer1_keypair.pem" 4056 ca_file: "configs/certs/ocsp_peer/mini-ca/root/root_cert.pem" 4057 timeout: 5 4058 verify: true 4059 } 4060 } 4061 ` 4062 srvConfB = fmt.Sprintf(srvConfB, storeDirB, optsA.Cluster.Port) 4063 conf := createConfFile(t, []byte(srvConfB)) 4064 srvB, optsB := RunServerWithConfig(conf) 4065 defer srvB.Shutdown() 4066 4067 // Client connects to server A. 4068 cA, err := nats.Connect(fmt.Sprintf("tls://127.0.0.1:%d", optsA.Port), 4069 nats.Secure(&tls.Config{ 4070 VerifyConnection: func(s tls.ConnectionState) error { 4071 if s.OCSPResponse == nil { 4072 return fmt.Errorf("missing OCSP Staple from server") 4073 } 4074 return nil 4075 }, 4076 }), 4077 nats.RootCAs(caCert), 4078 nats.ErrorHandler(noOpErrHandler), 4079 ) 4080 if err != nil { 4081 t.Fatal(err) 4082 4083 } 4084 defer cA.Close() 4085 4086 // Start another server that will make connect as a gateway to cluster A but with different CA issuer. 4087 srvConfC := ` 4088 host: "127.0.0.1" 4089 port: -1 4090 4091 server_name: "C" 4092 4093 ocsp { mode: "always" } 4094 4095 tls { 4096 cert_file: "configs/certs/ocsp_peer/mini-ca/server2/TestServer3_bundle.pem" 4097 key_file: "configs/certs/ocsp_peer/mini-ca/server2/private/TestServer3_keypair.pem" 4098 ca_file: "configs/certs/ocsp_peer/mini-ca/root/root_cert.pem" 4099 timeout: 5 4100 } 4101 store_dir: '%s' 4102 gateway { 4103 name: C 4104 host: "127.0.0.1" 4105 advertise: "127.0.0.1" 4106 port: -1 4107 gateways: [{ 4108 name: "A", 4109 urls: ["nats://127.0.0.1:%d"] 4110 tls { 4111 cert_file: "configs/certs/ocsp_peer/mini-ca/server2/TestServer3_bundle.pem" 4112 key_file: "configs/certs/ocsp_peer/mini-ca/server2/private/TestServer3_keypair.pem" 4113 ca_file: "configs/certs/ocsp_peer/mini-ca/root/root_cert.pem" 4114 timeout: 5 4115 } 4116 }] 4117 tls { 4118 cert_file: "configs/certs/ocsp_peer/mini-ca/server2/TestServer3_bundle.pem" 4119 key_file: "configs/certs/ocsp_peer/mini-ca/server2/private/TestServer3_keypair.pem" 4120 ca_file: "configs/certs/ocsp_peer/mini-ca/root/root_cert.pem" 4121 timeout: 5 4122 verify: true 4123 } 4124 } 4125 ` 4126 srvConfC = fmt.Sprintf(srvConfC, storeDirC, optsA.Gateway.Port) 4127 conf = createConfFile(t, []byte(srvConfC)) 4128 srvC, optsC := RunServerWithConfig(conf) 4129 defer srvC.Shutdown() 4130 4131 // Check that server is connected to any server from the other cluster. 4132 checkClusterFormed(t, srvA, srvB) 4133 waitForOutboundGateways(t, srvC, 1, 5*time.Second) 4134 4135 // Connect to cluster A using server B. 4136 cB, err := nats.Connect(fmt.Sprintf("tls://127.0.0.1:%d", optsB.Port), 4137 nats.Secure(&tls.Config{ 4138 VerifyConnection: func(s tls.ConnectionState) error { 4139 if s.OCSPResponse == nil { 4140 return fmt.Errorf("missing OCSP Staple from server") 4141 } 4142 return nil 4143 }, 4144 }), 4145 nats.RootCAs(caCert), 4146 nats.ErrorHandler(noOpErrHandler), 4147 ) 4148 if err != nil { 4149 t.Fatal(err) 4150 } 4151 defer cB.Close() 4152 4153 // Connects to cluster C using server C. 4154 cC, err := nats.Connect(fmt.Sprintf("tls://127.0.0.1:%d", optsC.Port), 4155 nats.Secure(&tls.Config{ 4156 VerifyConnection: func(s tls.ConnectionState) error { 4157 if s.OCSPResponse == nil { 4158 return fmt.Errorf("missing OCSP Staple from server") 4159 } 4160 return nil 4161 }, 4162 }), 4163 nats.RootCAs(caCert), 4164 nats.ErrorHandler(noOpErrHandler), 4165 ) 4166 if err != nil { 4167 t.Fatal(err) 4168 } 4169 defer cC.Close() 4170 4171 _, err = cA.Subscribe("foo", func(m *nats.Msg) { 4172 m.Respond([]byte("From Server A")) 4173 }) 4174 if err != nil { 4175 t.Errorf("%v", err) 4176 } 4177 cA.Flush() 4178 4179 _, err = cB.Subscribe("bar", func(m *nats.Msg) { 4180 m.Respond([]byte("From Server B")) 4181 }) 4182 if err != nil { 4183 t.Fatal(err) 4184 } 4185 cB.Flush() 4186 4187 // Confirm that a message from server C can flow back to server A via gateway.. 4188 var ( 4189 resp *nats.Msg 4190 lerr error 4191 ) 4192 for i := 0; i < 10; i++ { 4193 resp, lerr = cC.Request("foo", nil, 500*time.Millisecond) 4194 if lerr != nil { 4195 continue 4196 } 4197 got := string(resp.Data) 4198 expected := "From Server A" 4199 if got != expected { 4200 t.Fatalf("Expected %v, got: %v", expected, got) 4201 } 4202 4203 // Make request to B 4204 resp, lerr = cC.Request("bar", nil, 500*time.Millisecond) 4205 if lerr != nil { 4206 continue 4207 } 4208 got = string(resp.Data) 4209 expected = "From Server B" 4210 if got != expected { 4211 t.Errorf("Expected %v, got: %v", expected, got) 4212 } 4213 lerr = nil 4214 break 4215 } 4216 if lerr != nil { 4217 t.Errorf("Unexpected error: %v", lerr) 4218 } 4219 } 4220 4221 func TestOCSPResponderHTTPMethods(t *testing.T) { 4222 t.Run("prefer get", func(t *testing.T) { 4223 testOCSPResponderHTTPMethods(t, "GET") 4224 }) 4225 t.Run("prefer post", func(t *testing.T) { 4226 testOCSPResponderHTTPMethods(t, "POST") 4227 }) 4228 t.Run("all methods failing", func(t *testing.T) { 4229 testOCSPResponderFailing(t, "TEST") 4230 }) 4231 } 4232 4233 func testOCSPResponderHTTPMethods(t *testing.T, method string) { 4234 const ( 4235 caCert = "configs/certs/ocsp/ca-cert.pem" 4236 caKey = "configs/certs/ocsp/ca-key.pem" 4237 serverCert = "configs/certs/ocsp/server-cert.pem" 4238 serverKey = "configs/certs/ocsp/server-key.pem" 4239 ) 4240 4241 ctx, cancel := context.WithCancel(context.Background()) 4242 defer cancel() 4243 ocspr := newOCSPResponderPreferringHTTPMethod(t, caCert, caKey, method) 4244 defer ocspr.Shutdown(ctx) 4245 addr := fmt.Sprintf("http://%s", ocspr.Addr) 4246 setOCSPStatus(t, addr, serverCert, ocsp.Good) 4247 4248 // Add another responder that fails. 4249 badaddr := "http://127.0.0.1:8889" 4250 badocsp := newOCSPResponderCustomAddress(t, caCert, caKey, badaddr) 4251 defer badocsp.Shutdown(ctx) 4252 4253 opts := server.Options{} 4254 opts.Host = "127.0.0.1" 4255 opts.NoLog = true 4256 opts.NoSigs = true 4257 opts.MaxControlLine = 4096 4258 opts.Port = -1 4259 opts.TLSCert = serverCert 4260 opts.TLSKey = serverKey 4261 opts.TLSCaCert = caCert 4262 opts.TLSTimeout = 5 4263 tcOpts := &server.TLSConfigOpts{ 4264 CertFile: opts.TLSCert, 4265 KeyFile: opts.TLSKey, 4266 CaFile: opts.TLSCaCert, 4267 Timeout: opts.TLSTimeout, 4268 } 4269 4270 tlsConf, err := server.GenTLSConfig(tcOpts) 4271 if err != nil { 4272 t.Fatal(err) 4273 } 4274 opts.TLSConfig = tlsConf 4275 4276 opts.OCSPConfig = &server.OCSPConfig{ 4277 Mode: server.OCSPModeAlways, 4278 OverrideURLs: []string{badaddr, addr}, 4279 } 4280 srv := RunServer(&opts) 4281 defer srv.Shutdown() 4282 4283 nc, err := nats.Connect(fmt.Sprintf("tls://localhost:%d", opts.Port), 4284 nats.Secure(&tls.Config{ 4285 VerifyConnection: func(s tls.ConnectionState) error { 4286 resp, err := getOCSPStatus(s) 4287 if err != nil { 4288 return err 4289 } 4290 if resp.Status != ocsp.Good { 4291 return fmt.Errorf("invalid staple") 4292 } 4293 return nil 4294 }, 4295 }), 4296 nats.RootCAs(caCert), 4297 nats.ErrorHandler(noOpErrHandler), 4298 ) 4299 if err != nil { 4300 t.Fatal(err) 4301 } 4302 defer nc.Close() 4303 sub, err := nc.SubscribeSync("foo") 4304 if err != nil { 4305 t.Fatal(err) 4306 } 4307 nc.Publish("foo", []byte("hello world")) 4308 nc.Flush() 4309 4310 _, err = sub.NextMsg(1 * time.Second) 4311 if err != nil { 4312 t.Fatal(err) 4313 } 4314 nc.Close() 4315 } 4316 4317 func testOCSPResponderFailing(t *testing.T, method string) { 4318 const ( 4319 caCert = "configs/certs/ocsp/ca-cert.pem" 4320 caKey = "configs/certs/ocsp/ca-key.pem" 4321 serverCert = "configs/certs/ocsp/server-cert.pem" 4322 serverKey = "configs/certs/ocsp/server-key.pem" 4323 ) 4324 4325 ctx, cancel := context.WithCancel(context.Background()) 4326 defer cancel() 4327 ocspr := newOCSPResponderPreferringHTTPMethod(t, caCert, caKey, method) 4328 defer ocspr.Shutdown(ctx) 4329 addr := fmt.Sprintf("http://%s", ocspr.Addr) 4330 setOCSPStatus(t, addr, serverCert, ocsp.Good) 4331 4332 opts := server.Options{} 4333 opts.Host = "127.0.0.1" 4334 opts.NoLog = true 4335 opts.NoSigs = true 4336 opts.MaxControlLine = 4096 4337 opts.Port = -1 4338 opts.TLSCert = serverCert 4339 opts.TLSKey = serverKey 4340 opts.TLSCaCert = caCert 4341 opts.TLSTimeout = 5 4342 tcOpts := &server.TLSConfigOpts{ 4343 CertFile: opts.TLSCert, 4344 KeyFile: opts.TLSKey, 4345 CaFile: opts.TLSCaCert, 4346 Timeout: opts.TLSTimeout, 4347 } 4348 4349 tlsConf, err := server.GenTLSConfig(tcOpts) 4350 if err != nil { 4351 t.Fatal(err) 4352 } 4353 opts.TLSConfig = tlsConf 4354 4355 opts.OCSPConfig = &server.OCSPConfig{ 4356 Mode: server.OCSPModeAlways, 4357 OverrideURLs: []string{addr}, 4358 } 4359 expected := "bad OCSP status update for certificate at 'configs/certs/ocsp/server-cert.pem': " 4360 expected += "exhausted ocsp servers: non-ok http status on POST request (reqlen=68): 400\nnon-ok http status on GET request (reqlen=92): 400" 4361 _, err = server.NewServer(&opts) 4362 if err == nil { 4363 t.Error("Unexpected success setting up server") 4364 } else if err.Error() != expected { 4365 t.Errorf("Expected %q, got: %q", expected, err.Error()) 4366 } 4367 }