get.pme.sh/pnats@v0.0.0-20240304004023-26bb5a137ed0/test/ocsp_peer_test.go (about) 1 // Copyright 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 "context" 18 "crypto/tls" 19 "encoding/json" 20 "errors" 21 "fmt" 22 "io" 23 "net/http" 24 "os" 25 "path/filepath" 26 "testing" 27 "time" 28 29 "golang.org/x/crypto/ocsp" 30 31 "get.pme.sh/pnats/server" 32 "github.com/nats-io/nats.go" 33 ) 34 35 func newOCSPResponderRootCA(t *testing.T) *http.Server { 36 t.Helper() 37 respCertPEM := "configs/certs/ocsp_peer/mini-ca/caocsp/caocsp_cert.pem" 38 respKeyPEM := "configs/certs/ocsp_peer/mini-ca/caocsp/private/caocsp_keypair.pem" 39 issuerCertPEM := "configs/certs/ocsp_peer/mini-ca/root/root_cert.pem" 40 return newOCSPResponderDesignatedCustomAddress(t, issuerCertPEM, respCertPEM, respKeyPEM, "127.0.0.1:8888") 41 } 42 43 func newOCSPResponderIntermediateCA1(t *testing.T) *http.Server { 44 t.Helper() 45 respCertPEM := "configs/certs/ocsp_peer/mini-ca/ocsp1/ocsp1_bundle.pem" 46 respKeyPEM := "configs/certs/ocsp_peer/mini-ca/ocsp1/private/ocsp1_keypair.pem" 47 issuerCertPEM := "configs/certs/ocsp_peer/mini-ca/intermediate1/intermediate1_cert.pem" 48 return newOCSPResponderDesignatedCustomAddress(t, issuerCertPEM, respCertPEM, respKeyPEM, "127.0.0.1:18888") 49 } 50 51 func newOCSPResponderIntermediateCA1Undelegated(t *testing.T) *http.Server { 52 t.Helper() 53 issuerCertPEM := "configs/certs/ocsp_peer/mini-ca/intermediate1/intermediate1_cert.pem" 54 issuerCertKey := "configs/certs/ocsp_peer/mini-ca/intermediate1/private/intermediate1_keypair.pem" 55 return newOCSPResponderCustomAddress(t, issuerCertPEM, issuerCertKey, "127.0.0.1:18888") 56 } 57 58 func newOCSPResponderBadDelegateIntermediateCA1(t *testing.T) *http.Server { 59 t.Helper() 60 // UserA2 is a cert issued by intermediate1, but intermediate1 did not add OCSP signing extension 61 respCertPEM := "configs/certs/ocsp_peer/mini-ca/client1/UserA2_bundle.pem" 62 respKeyPEM := "configs/certs/ocsp_peer/mini-ca/client1/private/UserA2_keypair.pem" 63 issuerCertPEM := "configs/certs/ocsp_peer/mini-ca/intermediate1/intermediate1_cert.pem" 64 return newOCSPResponderDesignatedCustomAddress(t, issuerCertPEM, respCertPEM, respKeyPEM, "127.0.0.1:18888") 65 } 66 67 func newOCSPResponderIntermediateCA2(t *testing.T) *http.Server { 68 t.Helper() 69 respCertPEM := "configs/certs/ocsp_peer/mini-ca/ocsp2/ocsp2_bundle.pem" 70 respKeyPEM := "configs/certs/ocsp_peer/mini-ca/ocsp2/private/ocsp2_keypair.pem" 71 issuerCertPEM := "configs/certs/ocsp_peer/mini-ca/intermediate2/intermediate2_cert.pem" 72 return newOCSPResponderDesignatedCustomAddress(t, issuerCertPEM, respCertPEM, respKeyPEM, "127.0.0.1:28888") 73 } 74 75 // TestOCSPPeerGoodClients is test of two NATS client (AIA enabled at leaf and cert) under good path (different intermediates) 76 // and default ocsp_cache implementation and oscp_cache=false configuration 77 func TestOCSPPeerGoodClients(t *testing.T) { 78 ctx, cancel := context.WithCancel(context.Background()) 79 defer cancel() 80 81 rootCAResponder := newOCSPResponderRootCA(t) 82 rootCAResponderURL := fmt.Sprintf("http://%s", rootCAResponder.Addr) 83 defer rootCAResponder.Shutdown(ctx) 84 setOCSPStatus(t, rootCAResponderURL, "configs/certs/ocsp_peer/mini-ca/intermediate1/intermediate1_cert.pem", ocsp.Good) 85 setOCSPStatus(t, rootCAResponderURL, "configs/certs/ocsp_peer/mini-ca/intermediate2/intermediate2_cert.pem", ocsp.Good) 86 87 intermediateCA1Responder := newOCSPResponderIntermediateCA1(t) 88 intermediateCA1ResponderURL := fmt.Sprintf("http://%s", intermediateCA1Responder.Addr) 89 defer intermediateCA1Responder.Shutdown(ctx) 90 setOCSPStatus(t, intermediateCA1ResponderURL, "configs/certs/ocsp_peer/mini-ca/client1/UserA1_cert.pem", ocsp.Good) 91 92 intermediateCA2Responder := newOCSPResponderIntermediateCA2(t) 93 intermediateCA2ResponderURL := fmt.Sprintf("http://%s", intermediateCA2Responder.Addr) 94 defer intermediateCA2Responder.Shutdown(ctx) 95 setOCSPStatus(t, intermediateCA2ResponderURL, "configs/certs/ocsp_peer/mini-ca/client2/UserB1_cert.pem", ocsp.Good) 96 97 for _, test := range []struct { 98 name string 99 config string 100 opts []nats.Option 101 err error 102 rerr error 103 configure func() 104 }{ 105 { 106 "Default cache: mTLS OCSP peer check on inbound client connection, client of intermediate CA 1", 107 ` 108 port: -1 109 # default ocsp_cache since omitted 110 tls: { 111 cert_file: "configs/certs/ocsp_peer/mini-ca/server1/TestServer1_bundle.pem" 112 key_file: "configs/certs/ocsp_peer/mini-ca/server1/private/TestServer1_keypair.pem" 113 ca_file: "configs/certs/ocsp_peer/mini-ca/root/root_cert.pem" 114 timeout: 5 115 verify: true 116 # Long form configuration, non-default ca_timeout 117 ocsp_peer: { 118 verify: true 119 ca_timeout: 5 120 allowed_clockskew: 30 121 } 122 } 123 `, 124 []nats.Option{ 125 nats.ClientCert("./configs/certs/ocsp_peer/mini-ca/client1/UserA1_bundle.pem", "./configs/certs/ocsp_peer/mini-ca/client1/private/UserA1_keypair.pem"), 126 nats.RootCAs("./configs/certs/ocsp_peer/mini-ca/root/root_cert.pem"), 127 nats.ErrorHandler(noOpErrHandler), 128 }, 129 nil, 130 nil, 131 func() {}, 132 }, 133 { 134 "Default cache: mTLS OCSP peer check on inbound client connection, client of intermediate CA 2", 135 ` 136 port: -1 137 # default ocsp_cache since omitted 138 tls: { 139 cert_file: "configs/certs/ocsp_peer/mini-ca/server1/TestServer1_bundle.pem" 140 key_file: "configs/certs/ocsp_peer/mini-ca/server1/private/TestServer1_keypair.pem" 141 ca_file: "configs/certs/ocsp_peer/mini-ca/root/root_cert.pem" 142 timeout: 5 143 verify: true 144 # Short form configuration 145 ocsp_peer: true 146 } 147 `, 148 []nats.Option{ 149 nats.ClientCert("./configs/certs/ocsp_peer/mini-ca/client2/UserB1_bundle.pem", "./configs/certs/ocsp_peer/mini-ca/client2/private/UserB1_keypair.pem"), 150 nats.RootCAs("./configs/certs/ocsp_peer/mini-ca/root/root_cert.pem"), 151 nats.ErrorHandler(noOpErrHandler), 152 }, 153 nil, 154 nil, 155 func() {}, 156 }, 157 { 158 "Explicit true cache: mTLS OCSP peer check on inbound client connection, client of intermediate CA 1", 159 ` 160 port: -1 161 # Short form configuration 162 ocsp_cache: true 163 tls: { 164 cert_file: "configs/certs/ocsp_peer/mini-ca/server1/TestServer1_bundle.pem" 165 key_file: "configs/certs/ocsp_peer/mini-ca/server1/private/TestServer1_keypair.pem" 166 ca_file: "configs/certs/ocsp_peer/mini-ca/root/root_cert.pem" 167 timeout: 5 168 verify: true 169 # Long form configuration 170 ocsp_peer: { 171 verify: true 172 ca_timeout: 5 173 allowed_clockskew: 30 174 } 175 } 176 `, 177 []nats.Option{ 178 nats.ClientCert("./configs/certs/ocsp_peer/mini-ca/client1/UserA1_bundle.pem", "./configs/certs/ocsp_peer/mini-ca/client1/private/UserA1_keypair.pem"), 179 nats.RootCAs("./configs/certs/ocsp_peer/mini-ca/root/root_cert.pem"), 180 nats.ErrorHandler(noOpErrHandler), 181 }, 182 nil, 183 nil, 184 func() {}, 185 }, 186 } { 187 t.Run(test.name, func(t *testing.T) { 188 deleteLocalStore(t, "") 189 test.configure() 190 content := test.config 191 conf := createConfFile(t, []byte(content)) 192 s, opts := RunServerWithConfig(conf) 193 defer s.Shutdown() 194 nc, err := nats.Connect(fmt.Sprintf("tls://localhost:%d", opts.Port), test.opts...) 195 if test.err == nil && err != nil { 196 t.Errorf("Expected to connect, got %v", err) 197 } else if test.err != nil && err == nil { 198 t.Errorf("Expected error on connect") 199 } else if test.err != nil && err != nil { 200 // Error on connect was expected 201 if test.err.Error() != err.Error() { 202 t.Errorf("Expected error %s, got: %s", test.err, err) 203 } 204 return 205 } 206 defer nc.Close() 207 nc.Subscribe("ping", func(m *nats.Msg) { 208 m.Respond([]byte("pong")) 209 }) 210 nc.Flush() 211 _, err = nc.Request("ping", []byte("ping"), 250*time.Millisecond) 212 if test.rerr != nil && err == nil { 213 t.Errorf("Expected error getting response") 214 } else if test.rerr == nil && err != nil { 215 t.Errorf("Expected response") 216 } 217 }) 218 } 219 } 220 221 // TestOCSPPeerUnknownClient is test of NATS client that is OCSP status Unknown from its OCSP Responder 222 func TestOCSPPeerUnknownClient(t *testing.T) { 223 ctx, cancel := context.WithCancel(context.Background()) 224 defer cancel() 225 226 rootCAResponder := newOCSPResponderRootCA(t) 227 rootCAResponderURL := fmt.Sprintf("http://%s", rootCAResponder.Addr) 228 defer rootCAResponder.Shutdown(ctx) 229 setOCSPStatus(t, rootCAResponderURL, "configs/certs/ocsp_peer/mini-ca/intermediate1/intermediate1_cert.pem", ocsp.Good) 230 231 intermediateCA1Responder := newOCSPResponderIntermediateCA1(t) 232 defer intermediateCA1Responder.Shutdown(ctx) 233 234 for _, test := range []struct { 235 name string 236 config string 237 opts []nats.Option 238 err error 239 rerr error 240 configure func() 241 }{ 242 { 243 "Default cache, mTLS OCSP peer check on inbound client connection, client unknown to intermediate CA 1", 244 ` 245 port: -1 246 # Cache configuration is default 247 tls: { 248 cert_file: "configs/certs/ocsp_peer/mini-ca/server1/TestServer1_bundle.pem" 249 key_file: "configs/certs/ocsp_peer/mini-ca/server1/private/TestServer1_keypair.pem" 250 ca_file: "configs/certs/ocsp_peer/mini-ca/root/root_cert.pem" 251 timeout: 5 252 verify: true 253 # Short form configuration 254 ocsp_peer: true 255 } 256 `, 257 []nats.Option{ 258 nats.ClientCert("./configs/certs/ocsp_peer/mini-ca/client1/UserA1_bundle.pem", "./configs/certs/ocsp_peer/mini-ca/client1/private/UserA1_keypair.pem"), 259 nats.RootCAs("./configs/certs/ocsp_peer/mini-ca/root/root_cert.pem"), 260 nats.ErrorHandler(noOpErrHandler), 261 }, 262 errors.New("remote error: tls: bad certificate"), 263 errors.New("expect error"), 264 func() {}, 265 }, 266 } { 267 t.Run(test.name, func(t *testing.T) { 268 deleteLocalStore(t, "") 269 test.configure() 270 content := test.config 271 conf := createConfFile(t, []byte(content)) 272 s, opts := RunServerWithConfig(conf) 273 defer s.Shutdown() 274 nc, err := nats.Connect(fmt.Sprintf("tls://localhost:%d", opts.Port), test.opts...) 275 if test.err == nil && err != nil { 276 t.Errorf("Expected to connect, got %v", err) 277 } else if test.err != nil && err == nil { 278 t.Errorf("Expected error on connect") 279 } else if test.err != nil && err != nil { 280 // Error on connect was expected 281 if test.err.Error() != err.Error() { 282 t.Errorf("Expected error %s, got: %s", test.err, err) 283 } 284 return 285 } 286 defer nc.Close() 287 288 t.Errorf("Expected connection error, fell through") 289 }) 290 } 291 } 292 293 // TestOCSPPeerRevokedClient is test of NATS client that is OCSP status Revoked from its OCSP Responder 294 func TestOCSPPeerRevokedClient(t *testing.T) { 295 ctx, cancel := context.WithCancel(context.Background()) 296 defer cancel() 297 298 rootCAResponder := newOCSPResponderRootCA(t) 299 rootCAResponderURL := fmt.Sprintf("http://%s", rootCAResponder.Addr) 300 defer rootCAResponder.Shutdown(ctx) 301 setOCSPStatus(t, rootCAResponderURL, "configs/certs/ocsp_peer/mini-ca/intermediate1/intermediate1_cert.pem", ocsp.Good) 302 303 intermediateCA1Responder := newOCSPResponderIntermediateCA1(t) 304 intermediateCA1ResponderURL := fmt.Sprintf("http://%s", intermediateCA1Responder.Addr) 305 defer intermediateCA1Responder.Shutdown(ctx) 306 setOCSPStatus(t, intermediateCA1ResponderURL, "configs/certs/ocsp_peer/mini-ca/client1/UserA1_cert.pem", ocsp.Revoked) 307 308 for _, test := range []struct { 309 name string 310 config string 311 opts []nats.Option 312 err error 313 rerr error 314 configure func() 315 }{ 316 { 317 "mTLS OCSP peer check on inbound client connection, client revoked by intermediate CA 1", 318 ` 319 port: -1 320 # Cache configuration is default 321 tls: { 322 cert_file: "configs/certs/ocsp_peer/mini-ca/server1/TestServer1_bundle.pem" 323 key_file: "configs/certs/ocsp_peer/mini-ca/server1/private/TestServer1_keypair.pem" 324 ca_file: "configs/certs/ocsp_peer/mini-ca/root/root_cert.pem" 325 timeout: 5 326 verify: true 327 # Turn on CA OCSP check so this revoked client should NOT be able to connect 328 ocsp_peer: true 329 } 330 `, 331 []nats.Option{ 332 nats.ClientCert("./configs/certs/ocsp_peer/mini-ca/client1/UserA1_bundle.pem", "./configs/certs/ocsp_peer/mini-ca/client1/private/UserA1_keypair.pem"), 333 nats.RootCAs("./configs/certs/ocsp_peer/mini-ca/root/root_cert.pem"), 334 nats.ErrorHandler(noOpErrHandler), 335 }, 336 errors.New("remote error: tls: bad certificate"), 337 errors.New("expect error"), 338 func() {}, 339 }, 340 { 341 "Explicit disable, mTLS OCSP peer check on inbound client connection, client revoked by intermediate CA 1 but no OCSP check", 342 ` 343 port: -1 344 # Cache configuration is default 345 tls: { 346 cert_file: "configs/certs/ocsp_peer/mini-ca/server1/TestServer1_bundle.pem" 347 key_file: "configs/certs/ocsp_peer/mini-ca/server1/private/TestServer1_keypair.pem" 348 ca_file: "configs/certs/ocsp_peer/mini-ca/root/root_cert.pem" 349 timeout: 5 350 verify: true 351 # Explicit disable of OCSP peer check 352 ocsp_peer: false 353 } 354 `, 355 []nats.Option{ 356 nats.ClientCert("./configs/certs/ocsp_peer/mini-ca/client1/UserA1_bundle.pem", "./configs/certs/ocsp_peer/mini-ca/client1/private/UserA1_keypair.pem"), 357 nats.RootCAs("./configs/certs/ocsp_peer/mini-ca/root/root_cert.pem"), 358 nats.ErrorHandler(noOpErrHandler), 359 }, 360 nil, 361 nil, 362 func() {}, 363 }, 364 { 365 "Implicit disable, mTLS OCSP peer check on inbound client connection, client revoked by intermediate CA 1 but no OCSP check", 366 ` 367 port: -1 368 # Cache configuration is default 369 tls: { 370 cert_file: "configs/certs/ocsp_peer/mini-ca/server1/TestServer1_bundle.pem" 371 key_file: "configs/certs/ocsp_peer/mini-ca/server1/private/TestServer1_keypair.pem" 372 ca_file: "configs/certs/ocsp_peer/mini-ca/root/root_cert.pem" 373 timeout: 5 374 verify: true 375 # Implicit disable of OCSP peer check (i.e. not configured) 376 # ocsp_peer: false 377 } 378 `, 379 []nats.Option{ 380 nats.ClientCert("./configs/certs/ocsp_peer/mini-ca/client1/UserA1_bundle.pem", "./configs/certs/ocsp_peer/mini-ca/client1/private/UserA1_keypair.pem"), 381 nats.RootCAs("./configs/certs/ocsp_peer/mini-ca/root/root_cert.pem"), 382 nats.ErrorHandler(noOpErrHandler), 383 }, 384 nil, 385 nil, 386 func() {}, 387 }, 388 { 389 "Explicit disable (long form), mTLS OCSP peer check on inbound client connection, client revoked by intermediate CA 1 but no OCSP check", 390 ` 391 port: -1 392 # Cache configuration is default 393 tls: { 394 cert_file: "configs/certs/ocsp_peer/mini-ca/server1/TestServer1_bundle.pem" 395 key_file: "configs/certs/ocsp_peer/mini-ca/server1/private/TestServer1_keypair.pem" 396 ca_file: "configs/certs/ocsp_peer/mini-ca/root/root_cert.pem" 397 timeout: 5 398 verify: true 399 # Explicit disable of OCSP peer check, long form 400 ocsp_peer: { verify: false } 401 } 402 `, 403 []nats.Option{ 404 nats.ClientCert("./configs/certs/ocsp_peer/mini-ca/client1/UserA1_bundle.pem", "./configs/certs/ocsp_peer/mini-ca/client1/private/UserA1_keypair.pem"), 405 nats.RootCAs("./configs/certs/ocsp_peer/mini-ca/root/root_cert.pem"), 406 nats.ErrorHandler(noOpErrHandler), 407 }, 408 nil, 409 nil, 410 func() {}, 411 }, 412 } { 413 t.Run(test.name, func(t *testing.T) { 414 deleteLocalStore(t, "") 415 test.configure() 416 content := test.config 417 conf := createConfFile(t, []byte(content)) 418 s, opts := RunServerWithConfig(conf) 419 defer s.Shutdown() 420 nc, err := nats.Connect(fmt.Sprintf("tls://localhost:%d", opts.Port), test.opts...) 421 if test.err == nil && err != nil { 422 t.Errorf("Expected to connect, got %v", err) 423 } else if test.err != nil && err == nil { 424 t.Errorf("Expected error on connect") 425 } else if test.err != nil && err != nil { 426 // Error on connect was expected 427 if test.err.Error() != err.Error() { 428 t.Errorf("Expected error %s, got: %s", test.err, err) 429 } 430 return 431 } 432 defer nc.Close() 433 }) 434 } 435 } 436 437 // TestOCSPPeerUnknownAndRevokedIntermediate test of NATS client that is OCSP good but either its intermediate is unknown or revoked 438 func TestOCSPPeerUnknownAndRevokedIntermediate(t *testing.T) { 439 ctx, cancel := context.WithCancel(context.Background()) 440 defer cancel() 441 442 rootCAResponder := newOCSPResponderRootCA(t) 443 rootCAResponderURL := fmt.Sprintf("http://%s", rootCAResponder.Addr) 444 defer rootCAResponder.Shutdown(ctx) 445 setOCSPStatus(t, rootCAResponderURL, "configs/certs/ocsp_peer/mini-ca/intermediate1/intermediate1_cert.pem", ocsp.Revoked) 446 // No test OCSP status set on intermediate2, so unknown 447 448 intermediateCA1Responder := newOCSPResponderIntermediateCA1(t) 449 intermediateCA1ResponderURL := fmt.Sprintf("http://%s", intermediateCA1Responder.Addr) 450 defer intermediateCA1Responder.Shutdown(ctx) 451 setOCSPStatus(t, intermediateCA1ResponderURL, "configs/certs/ocsp_peer/mini-ca/client1/UserA1_cert.pem", ocsp.Good) 452 453 intermediateCA2Responder := newOCSPResponderIntermediateCA2(t) 454 intermediateCA2ResponderURL := fmt.Sprintf("http://%s", intermediateCA2Responder.Addr) 455 defer intermediateCA2Responder.Shutdown(ctx) 456 setOCSPStatus(t, intermediateCA2ResponderURL, "configs/certs/ocsp_peer/mini-ca/client2/UserB1_cert.pem", ocsp.Good) 457 458 for _, test := range []struct { 459 name string 460 config string 461 opts []nats.Option 462 err error 463 rerr error 464 configure func() 465 }{ 466 { 467 "mTLS OCSP peer check on inbound client connection, client's intermediate is revoked", 468 ` 469 port: -1 470 # Cache configuration is default 471 tls: { 472 cert_file: "configs/certs/ocsp_peer/mini-ca/server1/TestServer1_bundle.pem" 473 key_file: "configs/certs/ocsp_peer/mini-ca/server1/private/TestServer1_keypair.pem" 474 ca_file: "configs/certs/ocsp_peer/mini-ca/root/root_cert.pem" 475 timeout: 5 476 verify: true 477 # Short form configuration 478 ocsp_peer: true 479 } 480 `, 481 []nats.Option{ 482 nats.ClientCert("./configs/certs/ocsp_peer/mini-ca/client1/UserA1_bundle.pem", "./configs/certs/ocsp_peer/mini-ca/client1/private/UserA1_keypair.pem"), 483 nats.RootCAs("./configs/certs/ocsp_peer/mini-ca/root/root_cert.pem"), 484 nats.ErrorHandler(noOpErrHandler), 485 }, 486 errors.New("remote error: tls: bad certificate"), 487 errors.New("expect error"), 488 func() {}, 489 }, 490 { 491 "mTLS OCSP peer check on inbound client connection, client's intermediate is unknown'", 492 ` 493 port: -1 494 # Cache configuration is default 495 tls: { 496 cert_file: "configs/certs/ocsp_peer/mini-ca/server1/TestServer1_bundle.pem" 497 key_file: "configs/certs/ocsp_peer/mini-ca/server1/private/TestServer1_keypair.pem" 498 ca_file: "configs/certs/ocsp_peer/mini-ca/root/root_cert.pem" 499 timeout: 5 500 verify: true 501 # Short form configuration 502 ocsp_peer: true 503 } 504 `, 505 []nats.Option{ 506 nats.ClientCert("./configs/certs/ocsp_peer/mini-ca/client2/UserB1_bundle.pem", "./configs/certs/ocsp_peer/mini-ca/client2/private/UserB1_keypair.pem"), 507 nats.RootCAs("./configs/certs/ocsp_peer/mini-ca/root/root_cert.pem"), 508 nats.ErrorHandler(noOpErrHandler), 509 }, 510 errors.New("remote error: tls: bad certificate"), 511 errors.New("expect error"), 512 func() {}, 513 }, 514 } { 515 t.Run(test.name, func(t *testing.T) { 516 deleteLocalStore(t, "") 517 test.configure() 518 content := test.config 519 conf := createConfFile(t, []byte(content)) 520 s, opts := RunServerWithConfig(conf) 521 defer s.Shutdown() 522 523 nc, err := nats.Connect(fmt.Sprintf("tls://localhost:%d", opts.Port), test.opts...) 524 if test.err == nil && err != nil { 525 t.Errorf("Expected to connect, got %v", err) 526 } else if test.err != nil && err == nil { 527 t.Errorf("Expected error on connect") 528 } else if test.err != nil && err != nil { 529 // Error on connect was expected 530 if test.err.Error() != err.Error() { 531 t.Errorf("Expected error %s, got: %s", test.err, err) 532 } 533 return 534 } 535 defer nc.Close() 536 537 t.Errorf("Expected connection error, fell through") 538 }) 539 } 540 } 541 542 // TestOCSPPeerLeafGood tests Leaf Spoke peer checking Leaf Hub, Leaf Hub peer checking Leaf Spoke, and both peer checking 543 func TestOCSPPeerLeafGood(t *testing.T) { 544 ctx, cancel := context.WithCancel(context.Background()) 545 defer cancel() 546 547 rootCAResponder := newOCSPResponderRootCA(t) 548 rootCAResponderURL := fmt.Sprintf("http://%s", rootCAResponder.Addr) 549 defer rootCAResponder.Shutdown(ctx) 550 setOCSPStatus(t, rootCAResponderURL, "configs/certs/ocsp_peer/mini-ca/intermediate1/intermediate1_cert.pem", ocsp.Good) 551 552 intermediateCA1Responder := newOCSPResponderIntermediateCA1(t) 553 intermediateCA1ResponderURL := fmt.Sprintf("http://%s", intermediateCA1Responder.Addr) 554 defer intermediateCA1Responder.Shutdown(ctx) 555 setOCSPStatus(t, intermediateCA1ResponderURL, "configs/certs/ocsp_peer/mini-ca/server1/TestServer1_cert.pem", ocsp.Good) 556 setOCSPStatus(t, intermediateCA1ResponderURL, "configs/certs/ocsp_peer/mini-ca/server1/TestServer2_cert.pem", ocsp.Good) 557 558 for _, test := range []struct { 559 name string 560 hubconfig string 561 spokeconfig string 562 expected int 563 }{ 564 { 565 "OCSP peer check on Leaf Hub by Leaf Spoke (TLS client OCSP verification of TLS server)", 566 ` 567 port: -1 568 # Cache configuration is default 569 leaf: { 570 listen: 127.0.0.1:7444 571 tls: { 572 cert_file: "configs/certs/ocsp_peer/mini-ca/server1/TestServer1_bundle.pem" 573 key_file: "configs/certs/ocsp_peer/mini-ca/server1/private/TestServer1_keypair.pem" 574 ca_file: "configs/certs/ocsp_peer/mini-ca/root/root_cert.pem" 575 timeout: 5 576 } 577 } 578 `, 579 ` 580 port: -1 581 leaf: { 582 remotes: [ 583 { 584 url: "nats://127.0.0.1:7444", 585 tls: { 586 ca_file: "configs/certs/ocsp_peer/mini-ca/root/root_cert.pem" 587 timeout: 5 588 # Short form configuration 589 ocsp_peer: true 590 } 591 } 592 ] 593 } 594 `, 595 1, 596 }, 597 { 598 "OCSP peer check on Leaf Spoke by Leaf Hub (TLS server OCSP verification of TLS client)", 599 ` 600 port: -1 601 # Cache configuration is default 602 leaf: { 603 listen: 127.0.0.1:7444 604 tls: { 605 cert_file: "configs/certs/ocsp_peer/mini-ca/server1/TestServer1_bundle.pem" 606 key_file: "configs/certs/ocsp_peer/mini-ca/server1/private/TestServer1_keypair.pem" 607 ca_file: "configs/certs/ocsp_peer/mini-ca/root/root_cert.pem" 608 timeout: 5 609 verify: true 610 # Short form configuration 611 ocsp_peer: true 612 } 613 } 614 `, 615 ` 616 port: -1 617 leaf: { 618 remotes: [ 619 { 620 url: "nats://127.0.0.1:7444", 621 tls: { 622 cert_file: "configs/certs/ocsp_peer/mini-ca/server1/TestServer2_bundle.pem" 623 key_file: "configs/certs/ocsp_peer/mini-ca/server1/private/TestServer2_keypair.pem" 624 ca_file: "configs/certs/ocsp_peer/mini-ca/root/root_cert.pem" 625 timeout: 5 626 } 627 } 628 ] 629 } 630 `, 631 1, 632 }, 633 { 634 "OCSP peer check bi-directionally", 635 ` 636 port: -1 637 # Cache configuration is default 638 leaf: { 639 listen: 127.0.0.1:7444 640 tls: { 641 cert_file: "configs/certs/ocsp_peer/mini-ca/server1/TestServer1_bundle.pem" 642 key_file: "configs/certs/ocsp_peer/mini-ca/server1/private/TestServer1_keypair.pem" 643 ca_file: "configs/certs/ocsp_peer/mini-ca/root/root_cert.pem" 644 timeout: 5 645 verify: true 646 # Short form configuration 647 ocsp_peer: true 648 } 649 } 650 `, 651 ` 652 port: -1 653 leaf: { 654 remotes: [ 655 { 656 url: "nats://127.0.0.1:7444", 657 tls: { 658 cert_file: "configs/certs/ocsp_peer/mini-ca/server1/TestServer2_bundle.pem" 659 key_file: "configs/certs/ocsp_peer/mini-ca/server1/private/TestServer2_keypair.pem" 660 ca_file: "configs/certs/ocsp_peer/mini-ca/root/root_cert.pem" 661 timeout: 5 662 # Short form configuration 663 ocsp_peer: true 664 } 665 } 666 ] 667 } 668 `, 669 1, 670 }, 671 } { 672 t.Run(test.name, func(t *testing.T) { 673 deleteLocalStore(t, "") 674 hubcontent := test.hubconfig 675 hubconf := createConfFile(t, []byte(hubcontent)) 676 hub, _ := RunServerWithConfig(hubconf) 677 defer hub.Shutdown() 678 679 spokecontent := test.spokeconfig 680 spokeconf := createConfFile(t, []byte(spokecontent)) 681 spoke, _ := RunServerWithConfig(spokeconf) 682 defer spoke.Shutdown() 683 684 checkLeafNodeConnectedCount(t, hub, test.expected) 685 }) 686 } 687 } 688 689 // TestOCSPPeerLeafRejects tests rejected Leaf Hub, rejected Leaf Spoke, and both rejecting each other 690 func TestOCSPPeerLeafReject(t *testing.T) { 691 ctx, cancel := context.WithCancel(context.Background()) 692 defer cancel() 693 694 rootCAResponder := newOCSPResponderRootCA(t) 695 rootCAResponderURL := fmt.Sprintf("http://%s", rootCAResponder.Addr) 696 defer rootCAResponder.Shutdown(ctx) 697 setOCSPStatus(t, rootCAResponderURL, "configs/certs/ocsp_peer/mini-ca/intermediate1/intermediate1_cert.pem", ocsp.Good) 698 699 intermediateCA1Responder := newOCSPResponderIntermediateCA1(t) 700 intermediateCA1ResponderURL := fmt.Sprintf("http://%s", intermediateCA1Responder.Addr) 701 defer intermediateCA1Responder.Shutdown(ctx) 702 setOCSPStatus(t, intermediateCA1ResponderURL, "configs/certs/ocsp_peer/mini-ca/server1/TestServer1_cert.pem", ocsp.Revoked) 703 setOCSPStatus(t, intermediateCA1ResponderURL, "configs/certs/ocsp_peer/mini-ca/server1/TestServer2_cert.pem", ocsp.Revoked) 704 705 for _, test := range []struct { 706 name string 707 hubconfig string 708 spokeconfig string 709 expected int 710 }{ 711 { 712 "OCSP peer check on Leaf Hub by Leaf Spoke (TLS client OCSP verification of TLS server)", 713 ` 714 port: -1 715 # Cache configuration is default 716 leaf: { 717 listen: 127.0.0.1:7444 718 tls: { 719 cert_file: "configs/certs/ocsp_peer/mini-ca/server1/TestServer1_bundle.pem" 720 key_file: "configs/certs/ocsp_peer/mini-ca/server1/private/TestServer1_keypair.pem" 721 ca_file: "configs/certs/ocsp_peer/mini-ca/root/root_cert.pem" 722 timeout: 5 723 } 724 } 725 `, 726 ` 727 port: -1 728 leaf: { 729 remotes: [ 730 { 731 url: "nats://127.0.0.1:7444", 732 tls: { 733 ca_file: "configs/certs/ocsp_peer/mini-ca/root/root_cert.pem" 734 timeout: 5 735 # Short form configuration 736 ocsp_peer: true 737 } 738 } 739 ] 740 } 741 `, 742 0, 743 }, 744 { 745 "OCSP peer check on Leaf Spoke by Leaf Hub (TLS server OCSP verification of TLS client)", 746 ` 747 port: -1 748 leaf: { 749 listen: 127.0.0.1:7444 750 tls: { 751 cert_file: "configs/certs/ocsp_peer/mini-ca/server1/TestServer1_bundle.pem" 752 key_file: "configs/certs/ocsp_peer/mini-ca/server1/private/TestServer1_keypair.pem" 753 ca_file: "configs/certs/ocsp_peer/mini-ca/root/root_cert.pem" 754 timeout: 5 755 verify: true 756 # Short form configuration 757 ocsp_peer: true 758 } 759 } 760 `, 761 ` 762 port: -1 763 leaf: { 764 remotes: [ 765 { 766 url: "nats://127.0.0.1:7444", 767 tls: { 768 cert_file: "configs/certs/ocsp_peer/mini-ca/server1/TestServer2_bundle.pem" 769 key_file: "configs/certs/ocsp_peer/mini-ca/server1/private/TestServer2_keypair.pem" 770 ca_file: "configs/certs/ocsp_peer/mini-ca/root/root_cert.pem" 771 timeout: 5 772 } 773 } 774 ] 775 } 776 `, 777 0, 778 }, 779 { 780 "OCSP peer check bi-directionally", 781 ` 782 port: -1 783 leaf: { 784 listen: 127.0.0.1:7444 785 tls: { 786 cert_file: "configs/certs/ocsp_peer/mini-ca/server1/TestServer1_bundle.pem" 787 key_file: "configs/certs/ocsp_peer/mini-ca/server1/private/TestServer1_keypair.pem" 788 ca_file: "configs/certs/ocsp_peer/mini-ca/root/root_cert.pem" 789 timeout: 5 790 verify: true 791 # Short form configuration 792 ocsp_peer: true 793 } 794 } 795 `, 796 ` 797 port: -1 798 leaf: { 799 remotes: [ 800 { 801 url: "nats://127.0.0.1:7444", 802 tls: { 803 cert_file: "configs/certs/ocsp_peer/mini-ca/server1/TestServer2_bundle.pem" 804 key_file: "configs/certs/ocsp_peer/mini-ca/server1/private/TestServer2_keypair.pem" 805 ca_file: "configs/certs/ocsp_peer/mini-ca/root/root_cert.pem" 806 timeout: 5 807 # Short form configuration 808 ocsp_peer: true 809 } 810 } 811 ] 812 } 813 `, 814 0, 815 }, 816 } { 817 t.Run(test.name, func(t *testing.T) { 818 deleteLocalStore(t, "") 819 hubcontent := test.hubconfig 820 hubconf := createConfFile(t, []byte(hubcontent)) 821 hub, _ := RunServerWithConfig(hubconf) 822 defer hub.Shutdown() 823 spokecontent := test.spokeconfig 824 spokeconf := createConfFile(t, []byte(spokecontent)) 825 spoke, _ := RunServerWithConfig(spokeconf) 826 defer spoke.Shutdown() 827 // Need to inject some time for leaf connection attempts to complete, could refine this to better 828 // negative test 829 time.Sleep(2000 * time.Millisecond) 830 checkLeafNodeConnectedCount(t, hub, test.expected) 831 }) 832 } 833 } 834 835 func checkLeafNodeConnectedCount(t testing.TB, s *server.Server, lnCons int) { 836 t.Helper() 837 checkFor(t, 5*time.Second, 15*time.Millisecond, func() error { 838 if nln := s.NumLeafNodes(); nln != lnCons { 839 return fmt.Errorf("expected %d connected leafnode(s) for server %q, got %d", 840 lnCons, s.ID(), nln) 841 } 842 return nil 843 }) 844 } 845 846 // TestOCSPPeerGoodClientsNoneCache is test of two NATS client (AIA enabled at leaf and cert) under good path (different intermediates) 847 // and ocsp cache type of none (no-op) 848 func TestOCSPPeerGoodClientsNoneCache(t *testing.T) { 849 ctx, cancel := context.WithCancel(context.Background()) 850 defer cancel() 851 852 rootCAResponder := newOCSPResponderRootCA(t) 853 rootCAResponderURL := fmt.Sprintf("http://%s", rootCAResponder.Addr) 854 defer rootCAResponder.Shutdown(ctx) 855 setOCSPStatus(t, rootCAResponderURL, "configs/certs/ocsp_peer/mini-ca/intermediate1/intermediate1_cert.pem", ocsp.Good) 856 setOCSPStatus(t, rootCAResponderURL, "configs/certs/ocsp_peer/mini-ca/intermediate2/intermediate2_cert.pem", ocsp.Good) 857 858 intermediateCA1Responder := newOCSPResponderIntermediateCA1(t) 859 intermediateCA1ResponderURL := fmt.Sprintf("http://%s", intermediateCA1Responder.Addr) 860 defer intermediateCA1Responder.Shutdown(ctx) 861 setOCSPStatus(t, intermediateCA1ResponderURL, "configs/certs/ocsp_peer/mini-ca/client1/UserA1_cert.pem", ocsp.Good) 862 863 intermediateCA2Responder := newOCSPResponderIntermediateCA2(t) 864 intermediateCA2ResponderURL := fmt.Sprintf("http://%s", intermediateCA2Responder.Addr) 865 defer intermediateCA2Responder.Shutdown(ctx) 866 setOCSPStatus(t, intermediateCA2ResponderURL, "configs/certs/ocsp_peer/mini-ca/client2/UserB1_cert.pem", ocsp.Good) 867 868 deleteLocalStore(t, "") 869 870 for _, test := range []struct { 871 name string 872 config string 873 opts []nats.Option 874 err error 875 rerr error 876 configure func() 877 }{ 878 { 879 "None cache explicit long form: mTLS OCSP peer check on inbound client connection, client of intermediate CA 1", 880 ` 881 port: -1 882 tls: { 883 cert_file: "configs/certs/ocsp_peer/mini-ca/server1/TestServer1_bundle.pem" 884 key_file: "configs/certs/ocsp_peer/mini-ca/server1/private/TestServer1_keypair.pem" 885 ca_file: "configs/certs/ocsp_peer/mini-ca/root/root_cert.pem" 886 timeout: 5 887 verify: true 888 # Long form configuration 889 ocsp_peer: { 890 verify: true 891 ca_timeout: 5 892 allowed_clockskew: 30 893 } 894 } 895 # Long form configuration 896 ocsp_cache: { 897 type: none 898 } 899 `, 900 []nats.Option{ 901 nats.ClientCert("./configs/certs/ocsp_peer/mini-ca/client1/UserA1_bundle.pem", "./configs/certs/ocsp_peer/mini-ca/client1/private/UserA1_keypair.pem"), 902 nats.RootCAs("./configs/certs/ocsp_peer/mini-ca/root/root_cert.pem"), 903 nats.ErrorHandler(noOpErrHandler), 904 }, 905 nil, 906 nil, 907 func() {}, 908 }, 909 { 910 "None cache explicit short form: mTLS OCSP peer check on inbound client connection, client of intermediate CA 1", 911 ` 912 port: -1 913 tls: { 914 cert_file: "configs/certs/ocsp_peer/mini-ca/server1/TestServer1_bundle.pem" 915 key_file: "configs/certs/ocsp_peer/mini-ca/server1/private/TestServer1_keypair.pem" 916 ca_file: "configs/certs/ocsp_peer/mini-ca/root/root_cert.pem" 917 timeout: 5 918 verify: true 919 # Long form configuration 920 ocsp_peer: { 921 verify: true 922 ca_timeout: 5 923 allowed_clockskew: 30 924 } 925 } 926 # Short form configuration 927 ocsp_cache: false 928 `, 929 []nats.Option{ 930 nats.ClientCert("./configs/certs/ocsp_peer/mini-ca/client1/UserA1_bundle.pem", "./configs/certs/ocsp_peer/mini-ca/client1/private/UserA1_keypair.pem"), 931 nats.RootCAs("./configs/certs/ocsp_peer/mini-ca/root/root_cert.pem"), 932 nats.ErrorHandler(noOpErrHandler), 933 }, 934 nil, 935 nil, 936 func() {}, 937 }, 938 } { 939 t.Run(test.name, func(t *testing.T) { 940 test.configure() 941 content := test.config 942 conf := createConfFile(t, []byte(content)) 943 s, opts := RunServerWithConfig(conf) 944 defer s.Shutdown() 945 nc, err := nats.Connect(fmt.Sprintf("tls://localhost:%d", opts.Port), test.opts...) 946 if test.err == nil && err != nil { 947 t.Errorf("Expected to connect, got %v", err) 948 } else if test.err != nil && err == nil { 949 t.Errorf("Expected error on connect") 950 } else if test.err != nil && err != nil { 951 // Error on connect was expected 952 if test.err.Error() != err.Error() { 953 t.Errorf("Expected error %s, got: %s", test.err, err) 954 } 955 return 956 } 957 defer nc.Close() 958 nc.Subscribe("ping", func(m *nats.Msg) { 959 m.Respond([]byte("pong")) 960 }) 961 nc.Flush() 962 _, err = nc.Request("ping", []byte("ping"), 250*time.Millisecond) 963 if test.rerr != nil && err == nil { 964 t.Errorf("Expected error getting response") 965 } else if test.rerr == nil && err != nil { 966 t.Errorf("Expected response") 967 } 968 }) 969 } 970 } 971 972 // TestOCSPPeerGoodClientsLocalCache is test of two NATS client (AIA enabled at leaf and cert) under good path (different intermediates) 973 // and leveraging the local ocsp cache type 974 func TestOCSPPeerGoodClientsLocalCache(t *testing.T) { 975 ctx, cancel := context.WithCancel(context.Background()) 976 defer cancel() 977 978 rootCAResponder := newOCSPResponderRootCA(t) 979 rootCAResponderURL := fmt.Sprintf("http://%s", rootCAResponder.Addr) 980 defer rootCAResponder.Shutdown(ctx) 981 setOCSPStatus(t, rootCAResponderURL, "configs/certs/ocsp_peer/mini-ca/intermediate1/intermediate1_cert.pem", ocsp.Good) 982 setOCSPStatus(t, rootCAResponderURL, "configs/certs/ocsp_peer/mini-ca/intermediate2/intermediate2_cert.pem", ocsp.Good) 983 984 intermediateCA1Responder := newOCSPResponderIntermediateCA1(t) 985 intermediateCA1ResponderURL := fmt.Sprintf("http://%s", intermediateCA1Responder.Addr) 986 defer intermediateCA1Responder.Shutdown(ctx) 987 setOCSPStatus(t, intermediateCA1ResponderURL, "configs/certs/ocsp_peer/mini-ca/client1/UserA1_cert.pem", ocsp.Good) 988 989 intermediateCA2Responder := newOCSPResponderIntermediateCA2(t) 990 intermediateCA2ResponderURL := fmt.Sprintf("http://%s", intermediateCA2Responder.Addr) 991 defer intermediateCA2Responder.Shutdown(ctx) 992 setOCSPStatus(t, intermediateCA2ResponderURL, "configs/certs/ocsp_peer/mini-ca/client2/UserB1_cert.pem", ocsp.Good) 993 994 for _, test := range []struct { 995 name string 996 config string 997 opts []nats.Option 998 err error 999 rerr error 1000 configure func() 1001 }{ 1002 { 1003 "Default cache, short form: mTLS OCSP peer check on inbound client connection, UserA1 client of intermediate CA 1", 1004 ` 1005 port: -1 1006 http_port: 8222 1007 tls: { 1008 cert_file: "configs/certs/ocsp_peer/mini-ca/server1/TestServer1_bundle.pem" 1009 key_file: "configs/certs/ocsp_peer/mini-ca/server1/private/TestServer1_keypair.pem" 1010 ca_file: "configs/certs/ocsp_peer/mini-ca/root/root_cert.pem" 1011 timeout: 5 1012 verify: true 1013 # Long form configuration 1014 ocsp_peer: { 1015 verify: true 1016 ca_timeout: 5 1017 allowed_clockskew: 30 1018 } 1019 } 1020 # Short form configuration, local as default 1021 ocsp_cache: true 1022 `, 1023 []nats.Option{ 1024 nats.ClientCert("./configs/certs/ocsp_peer/mini-ca/client1/UserA1_bundle.pem", "./configs/certs/ocsp_peer/mini-ca/client1/private/UserA1_keypair.pem"), 1025 nats.RootCAs("./configs/certs/ocsp_peer/mini-ca/root/root_cert.pem"), 1026 nats.ErrorHandler(noOpErrHandler), 1027 }, 1028 nil, 1029 nil, 1030 func() {}, 1031 }, 1032 { 1033 "Local cache long form: mTLS OCSP peer check on inbound client connection, UserB1 client of intermediate CA 2", 1034 ` 1035 port: -1 1036 http_port: 8222 1037 1038 tls: { 1039 cert_file: "configs/certs/ocsp_peer/mini-ca/server1/TestServer1_bundle.pem" 1040 key_file: "configs/certs/ocsp_peer/mini-ca/server1/private/TestServer1_keypair.pem" 1041 ca_file: "configs/certs/ocsp_peer/mini-ca/root/root_cert.pem" 1042 timeout: 5 1043 verify: true 1044 # Short form configuration 1045 ocsp_peer: true 1046 } 1047 # Long form configuration 1048 ocsp_cache: { 1049 type: local 1050 } 1051 `, 1052 []nats.Option{ 1053 nats.ClientCert("./configs/certs/ocsp_peer/mini-ca/client2/UserB1_bundle.pem", "./configs/certs/ocsp_peer/mini-ca/client2/private/UserB1_keypair.pem"), 1054 nats.RootCAs("./configs/certs/ocsp_peer/mini-ca/root/root_cert.pem"), 1055 nats.ErrorHandler(noOpErrHandler), 1056 }, 1057 nil, 1058 nil, 1059 func() {}, 1060 }, 1061 } { 1062 t.Run(test.name, func(t *testing.T) { 1063 // Cleanup any previous test that saved a local cache 1064 deleteLocalStore(t, "") 1065 test.configure() 1066 content := test.config 1067 conf := createConfFile(t, []byte(content)) 1068 s, opts := RunServerWithConfig(conf) 1069 defer s.Shutdown() 1070 nc, err := nats.Connect(fmt.Sprintf("tls://localhost:%d", opts.Port), test.opts...) 1071 if test.err == nil && err != nil { 1072 t.Errorf("Expected to connect, got %v", err) 1073 } else if test.err != nil && err == nil { 1074 t.Errorf("Expected error on connect") 1075 } else if test.err != nil && err != nil { 1076 // Error on connect was expected 1077 if test.err.Error() != err.Error() { 1078 t.Errorf("Expected error %s, got: %s", test.err, err) 1079 } 1080 return 1081 } 1082 nc.Close() 1083 1084 v := monitorGetVarzHelper(t, 8222) 1085 if v.OCSPResponseCache == nil { 1086 t.Fatalf("Expected OCSP statistics to be in varz") 1087 } 1088 if v.OCSPResponseCache.Misses != 2 || v.OCSPResponseCache.Responses != 2 { 1089 t.Errorf("Expected cache misses and cache items to be 2, got %d and %d", v.OCSPResponseCache.Misses, v.OCSPResponseCache.Responses) 1090 } 1091 1092 // Should get a cache hit now 1093 nc, err = nats.Connect(fmt.Sprintf("tls://localhost:%d", opts.Port), test.opts...) 1094 if test.err == nil && err != nil { 1095 t.Errorf("Expected to connect, got %v", err) 1096 } else if test.err != nil && err == nil { 1097 t.Errorf("Expected error on connect") 1098 } else if test.err != nil && err != nil { 1099 // Error on connect was expected 1100 if test.err.Error() != err.Error() { 1101 t.Errorf("Expected error %s, got: %s", test.err, err) 1102 } 1103 return 1104 } 1105 defer nc.Close() 1106 nc.Subscribe("ping", func(m *nats.Msg) { 1107 m.Respond([]byte("pong")) 1108 }) 1109 nc.Flush() 1110 _, err = nc.Request("ping", []byte("ping"), 250*time.Millisecond) 1111 if test.rerr != nil && err == nil { 1112 t.Errorf("Expected error getting response") 1113 } else if test.rerr == nil && err != nil { 1114 t.Errorf("Expected response") 1115 } 1116 1117 v = monitorGetVarzHelper(t, 8222) 1118 if v.OCSPResponseCache == nil { 1119 t.Fatalf("Expected OCSP statistics to be in varz") 1120 } 1121 if v.OCSPResponseCache.Misses != 2 || v.OCSPResponseCache.Hits != 2 || v.OCSPResponseCache.Responses != 2 { 1122 t.Errorf("Expected cache misses, hits and cache items to be 2, got %d and %d and %d", v.OCSPResponseCache.Misses, v.OCSPResponseCache.Hits, v.OCSPResponseCache.Responses) 1123 } 1124 }) 1125 } 1126 } 1127 1128 func TestOCSPPeerMonitor(t *testing.T) { 1129 for _, test := range []struct { 1130 name string 1131 config string 1132 NATSClient bool 1133 WSClient bool 1134 MQTTClient bool 1135 LeafClient bool 1136 LeafRemotes bool 1137 NumTrueLeafRemotes int 1138 }{ 1139 { 1140 "Monitor peer config setting on NATS client", 1141 ` 1142 port: -1 1143 http_port: 8222 1144 # Default cache configuration 1145 tls: { 1146 cert_file: "configs/certs/ocsp_peer/mini-ca/server1/TestServer1_bundle.pem" 1147 key_file: "configs/certs/ocsp_peer/mini-ca/server1/private/TestServer1_keypair.pem" 1148 ca_file: "configs/certs/ocsp_peer/mini-ca/root/root_cert.pem" 1149 timeout: 5 1150 verify: true 1151 # Long form configuration 1152 ocsp_peer: { 1153 verify: true 1154 } 1155 } 1156 `, 1157 true, 1158 false, 1159 false, 1160 false, 1161 false, 1162 0, 1163 }, 1164 { 1165 "Monitor peer config setting on Websockets client", 1166 ` 1167 port: -1 1168 http_port: 8222 1169 # Default cache configuration 1170 websocket: { 1171 port: 8443 1172 tls: { 1173 cert_file: "configs/certs/ocsp_peer/mini-ca/server1/TestServer1_bundle.pem" 1174 key_file: "configs/certs/ocsp_peer/mini-ca/server1/private/TestServer1_keypair.pem" 1175 ca_file: "configs/certs/ocsp_peer/mini-ca/root/root_cert.pem" 1176 timeout: 5 1177 verify: true 1178 # Long form configuration 1179 ocsp_peer: { 1180 verify: true 1181 } 1182 } 1183 } 1184 `, 1185 false, 1186 true, 1187 false, 1188 false, 1189 false, 1190 0, 1191 }, 1192 { 1193 "Monitor peer config setting on MQTT client", 1194 ` 1195 port: -1 1196 http_port: 8222 1197 # Default cache configuration 1198 # Required for MQTT 1199 server_name: "my_mqtt_server" 1200 jetstream: { 1201 enabled: true 1202 } 1203 mqtt: { 1204 port: 1883 1205 tls: { 1206 cert_file: "configs/certs/ocsp_peer/mini-ca/server1/TestServer1_bundle.pem" 1207 key_file: "configs/certs/ocsp_peer/mini-ca/server1/private/TestServer1_keypair.pem" 1208 ca_file: "configs/certs/ocsp_peer/mini-ca/root/root_cert.pem" 1209 timeout: 5 1210 verify: true 1211 # Long form configuration 1212 ocsp_peer: { 1213 verify: true 1214 } 1215 } 1216 } 1217 `, 1218 false, 1219 false, 1220 true, 1221 false, 1222 false, 1223 0, 1224 }, 1225 { 1226 "Monitor peer config setting on Leaf client", 1227 ` 1228 port: -1 1229 http_port: 8222 1230 # Default cache configuration 1231 leaf: { 1232 port: 7422 1233 tls: { 1234 cert_file: "configs/certs/ocsp_peer/mini-ca/server1/TestServer1_bundle.pem" 1235 key_file: "configs/certs/ocsp_peer/mini-ca/server1/private/TestServer1_keypair.pem" 1236 ca_file: "configs/certs/ocsp_peer/mini-ca/root/root_cert.pem" 1237 timeout: 5 1238 verify: true 1239 # Long form configuration 1240 ocsp_peer: { 1241 verify: true 1242 } 1243 } 1244 } 1245 `, 1246 false, 1247 false, 1248 false, 1249 true, 1250 false, 1251 0, 1252 }, 1253 { 1254 "Monitor peer config on some Leaf Remotes as well as Leaf client", 1255 ` 1256 port: -1 1257 http_port: 8222 1258 # Default cache configuration 1259 leaf: { 1260 port: 7422 1261 tls: { 1262 cert_file: "configs/certs/ocsp_peer/mini-ca/server1/TestServer1_bundle.pem" 1263 key_file: "configs/certs/ocsp_peer/mini-ca/server1/private/TestServer1_keypair.pem" 1264 ca_file: "configs/certs/ocsp_peer/mini-ca/root/root_cert.pem" 1265 timeout: 5 1266 verify: true 1267 # Long form configuration 1268 ocsp_peer: { 1269 verify: true 1270 } 1271 } 1272 remotes: [ 1273 { 1274 url: "nats-leaf://bogus:7422" 1275 tls: { 1276 cert_file: "configs/certs/ocsp_peer/mini-ca/server1/TestServer1_bundle.pem" 1277 key_file: "configs/certs/ocsp_peer/mini-ca/server1/private/TestServer1_keypair.pem" 1278 ca_file: "configs/certs/ocsp_peer/mini-ca/root/root_cert.pem" 1279 timeout: 5 1280 # Long form configuration 1281 ocsp_peer: { 1282 verify: true 1283 } 1284 } 1285 }, 1286 { 1287 url: "nats-leaf://anotherbogus:7422" 1288 tls: { 1289 cert_file: "configs/certs/ocsp_peer/mini-ca/server1/TestServer1_bundle.pem" 1290 key_file: "configs/certs/ocsp_peer/mini-ca/server1/private/TestServer1_keypair.pem" 1291 ca_file: "configs/certs/ocsp_peer/mini-ca/root/root_cert.pem" 1292 timeout: 5 1293 # Short form configuration 1294 ocsp_peer: true 1295 } 1296 }, 1297 { 1298 url: "nats-leaf://yetanotherbogus:7422" 1299 tls: { 1300 cert_file: "configs/certs/ocsp_peer/mini-ca/server1/TestServer1_bundle.pem" 1301 key_file: "configs/certs/ocsp_peer/mini-ca/server1/private/TestServer1_keypair.pem" 1302 ca_file: "configs/certs/ocsp_peer/mini-ca/root/root_cert.pem" 1303 timeout: 5 1304 # Peer not configured (default false) 1305 } 1306 } 1307 ] 1308 } 1309 `, 1310 false, 1311 false, 1312 false, 1313 true, 1314 true, 1315 2, 1316 }, 1317 } { 1318 t.Run(test.name, func(t *testing.T) { 1319 content := test.config 1320 conf := createConfFile(t, []byte(content)) 1321 s, _ := RunServerWithConfig(conf) 1322 defer s.Shutdown() 1323 v := monitorGetVarzHelper(t, 8222) 1324 if test.NATSClient { 1325 if !v.TLSOCSPPeerVerify { 1326 t.Fatalf("Expected NATS Client TLSOCSPPeerVerify to be true, got false") 1327 } 1328 } 1329 if test.WSClient { 1330 if !v.Websocket.TLSOCSPPeerVerify { 1331 t.Fatalf("Expected WS Client TLSOCSPPeerVerify to be true, got false") 1332 } 1333 } 1334 if test.LeafClient { 1335 if !v.LeafNode.TLSOCSPPeerVerify { 1336 t.Fatalf("Expected Leaf Client TLSOCSPPeerVerify to be true, got false") 1337 } 1338 } 1339 if test.LeafRemotes { 1340 cnt := 0 1341 for _, r := range v.LeafNode.Remotes { 1342 if r.TLSOCSPPeerVerify { 1343 cnt++ 1344 } 1345 } 1346 if cnt != test.NumTrueLeafRemotes { 1347 t.Fatalf("Expected %d Leaf Remotes with TLSOCSPPeerVerify true, got %d", test.NumTrueLeafRemotes, cnt) 1348 } 1349 } 1350 }) 1351 } 1352 } 1353 1354 func TestOCSPResponseCacheMonitor(t *testing.T) { 1355 for _, test := range []struct { 1356 name string 1357 config string 1358 expect string 1359 }{ 1360 { 1361 "Monitor local cache enabled, explicit cache true", 1362 ` 1363 port: -1 1364 http_port: 8222 1365 tls: { 1366 cert_file: "configs/certs/ocsp_peer/mini-ca/server1/TestServer1_bundle.pem" 1367 key_file: "configs/certs/ocsp_peer/mini-ca/server1/private/TestServer1_keypair.pem" 1368 ca_file: "configs/certs/ocsp_peer/mini-ca/root/root_cert.pem" 1369 timeout: 5 1370 verify: true 1371 # Long form configuration 1372 ocsp_peer: { 1373 verify: true 1374 } 1375 } 1376 # Short form configuration 1377 ocsp_cache: true 1378 `, 1379 "local", 1380 }, 1381 { 1382 "Monitor local cache enabled, explicit cache type local", 1383 ` 1384 port: -1 1385 http_port: 8222 1386 tls: { 1387 cert_file: "configs/certs/ocsp_peer/mini-ca/server1/TestServer1_bundle.pem" 1388 key_file: "configs/certs/ocsp_peer/mini-ca/server1/private/TestServer1_keypair.pem" 1389 ca_file: "configs/certs/ocsp_peer/mini-ca/root/root_cert.pem" 1390 timeout: 5 1391 verify: true 1392 # Long form configuration 1393 ocsp_peer: { 1394 verify: true 1395 } 1396 } 1397 # Long form configuration 1398 ocsp_cache: { 1399 type: local 1400 } 1401 `, 1402 "local", 1403 }, 1404 { 1405 "Monitor local cache enabled, implicit default", 1406 ` 1407 port: -1 1408 http_port: 8222 1409 tls: { 1410 cert_file: "configs/certs/ocsp_peer/mini-ca/server1/TestServer1_bundle.pem" 1411 key_file: "configs/certs/ocsp_peer/mini-ca/server1/private/TestServer1_keypair.pem" 1412 ca_file: "configs/certs/ocsp_peer/mini-ca/root/root_cert.pem" 1413 timeout: 5 1414 verify: true 1415 # Long form configuration 1416 ocsp_peer: { 1417 verify: true 1418 } 1419 } 1420 # Short form configuration 1421 # ocsp_cache: true 1422 `, 1423 "local", 1424 }, 1425 { 1426 "Monitor none cache enabled, explicit cache false (short)", 1427 ` 1428 port: -1 1429 http_port: 8222 1430 tls: { 1431 cert_file: "configs/certs/ocsp_peer/mini-ca/server1/TestServer1_bundle.pem" 1432 key_file: "configs/certs/ocsp_peer/mini-ca/server1/private/TestServer1_keypair.pem" 1433 ca_file: "configs/certs/ocsp_peer/mini-ca/root/root_cert.pem" 1434 timeout: 5 1435 verify: true 1436 # Long form configuration 1437 ocsp_peer: { 1438 verify: true 1439 } 1440 } 1441 # Short form configuration 1442 ocsp_cache: false 1443 `, 1444 "", 1445 }, 1446 { 1447 "Monitor none cache enabled, explicit cache false (long)", 1448 ` 1449 port: -1 1450 http_port: 8222 1451 tls: { 1452 cert_file: "configs/certs/ocsp_peer/mini-ca/server1/TestServer1_bundle.pem" 1453 key_file: "configs/certs/ocsp_peer/mini-ca/server1/private/TestServer1_keypair.pem" 1454 ca_file: "configs/certs/ocsp_peer/mini-ca/root/root_cert.pem" 1455 timeout: 5 1456 verify: true 1457 # Long form configuration 1458 ocsp_peer: { 1459 verify: true 1460 } 1461 } 1462 # Long form configuration 1463 ocsp_cache: { 1464 type: none 1465 } 1466 `, 1467 "", 1468 }, 1469 } { 1470 t.Run(test.name, func(t *testing.T) { 1471 deleteLocalStore(t, "") 1472 content := test.config 1473 conf := createConfFile(t, []byte(content)) 1474 s, _ := RunServerWithConfig(conf) 1475 defer s.Shutdown() 1476 v := monitorGetVarzHelper(t, 8222) 1477 fmt.Println("Expect:", test.expect) 1478 var ct string 1479 if v.OCSPResponseCache != nil { 1480 ct = v.OCSPResponseCache.Type 1481 } 1482 if ct != test.expect { 1483 t.Fatalf("Expected OCSP Response Cache to be %s, got %s", test.expect, ct) 1484 } 1485 }) 1486 } 1487 } 1488 1489 func TestOCSPResponseCacheChangeAndReload(t *testing.T) { 1490 deleteLocalStore(t, "") 1491 1492 // Start with ocsp cache set to none 1493 content := ` 1494 port: -1 1495 http_port: 8222 1496 tls { 1497 cert_file: "configs/certs/ocsp_peer/mini-ca/server1/TestServer1_bundle.pem" 1498 key_file: "configs/certs/ocsp_peer/mini-ca/server1/private/TestServer1_keypair.pem" 1499 ca_file: "configs/certs/ocsp_peer/mini-ca/root/root_cert.pem" 1500 timeout: 5 1501 verify: true 1502 # Short form configuration 1503 ocsp_peer: true 1504 } 1505 # Long form configuration 1506 ocsp_cache: { 1507 type: none 1508 } 1509 ` 1510 conf := createConfFile(t, []byte(content)) 1511 s, _ := RunServerWithConfig(conf) 1512 defer s.Shutdown() 1513 v := monitorGetVarzHelper(t, 8222) 1514 var ct string 1515 if v.OCSPResponseCache != nil { 1516 ct = v.OCSPResponseCache.Type 1517 } 1518 if ct != "" { 1519 t.Fatalf("Expected OCSP Response Cache to have empty type in varz indicating none") 1520 } 1521 1522 // Change to local cache 1523 content = ` 1524 port: -1 1525 http_port: 8222 1526 tls { 1527 cert_file: "configs/certs/ocsp_peer/mini-ca/server1/TestServer1_bundle.pem" 1528 key_file: "configs/certs/ocsp_peer/mini-ca/server1/private/TestServer1_keypair.pem" 1529 ca_file: "configs/certs/ocsp_peer/mini-ca/root/root_cert.pem" 1530 timeout: 5 1531 verify: true 1532 # Short form configuration 1533 ocsp_peer: true 1534 } 1535 # Long form configuration 1536 ocsp_cache: { 1537 type: local 1538 } 1539 ` 1540 if err := os.WriteFile(conf, []byte(content), 0666); err != nil { 1541 t.Fatalf("Error writing config: %v", err) 1542 } 1543 if err := s.Reload(); err != nil { 1544 t.Fatal(err) 1545 } 1546 time.Sleep(2 * time.Second) 1547 v = monitorGetVarzHelper(t, 8222) 1548 ct = "" 1549 if v.OCSPResponseCache != nil { 1550 ct = v.OCSPResponseCache.Type 1551 } 1552 if ct != "local" { 1553 t.Fatalf("Expected OCSP Response Cache type to be local, got %q", ct) 1554 } 1555 } 1556 1557 func deleteLocalStore(t *testing.T, dir string) { 1558 t.Helper() 1559 if dir == "" { 1560 // default 1561 dir = "_rc_" 1562 } 1563 if err := os.RemoveAll(dir); err != nil { 1564 t.Fatalf("Error cleaning up local store: %v", err) 1565 } 1566 } 1567 1568 func monitorGetVarzHelper(t *testing.T, httpPort int) *server.Varz { 1569 t.Helper() 1570 url := fmt.Sprintf("http://127.0.0.1:%d/", httpPort) 1571 resp, err := http.Get(url + "varz") 1572 if err != nil { 1573 t.Fatalf("Expected no error: Got %v\n", err) 1574 } 1575 if resp.StatusCode != 200 { 1576 t.Fatalf("Expected a 200 response, got %d\n", resp.StatusCode) 1577 } 1578 defer resp.Body.Close() 1579 body, err := io.ReadAll(resp.Body) 1580 if err != nil { 1581 t.Fatalf("Got an error reading the body: %v\n", err) 1582 } 1583 v := server.Varz{} 1584 if err := json.Unmarshal(body, &v); err != nil { 1585 t.Fatalf("Got an error unmarshalling the body: %v\n", err) 1586 } 1587 return &v 1588 } 1589 1590 func writeCacheFile(dir string, content []byte) error { 1591 if dir == "" { 1592 dir = "_rc_" 1593 } 1594 err := os.MkdirAll(filepath.Join(dir), os.ModePerm) 1595 if err != nil { 1596 return err 1597 } 1598 return os.WriteFile(filepath.Join(dir, "cache.json"), content, os.ModePerm) 1599 } 1600 1601 // TestOCSPPeerPreserveRevokedCacheItem is test of the preserve_revoked cache policy 1602 func TestOCSPPeerPreserveRevokedCacheItem(t *testing.T) { 1603 ctx, cancel := context.WithCancel(context.Background()) 1604 defer cancel() 1605 1606 rootCAResponder := newOCSPResponderRootCA(t) 1607 rootCAResponderURL := fmt.Sprintf("http://%s", rootCAResponder.Addr) 1608 defer rootCAResponder.Shutdown(ctx) 1609 setOCSPStatus(t, rootCAResponderURL, "configs/certs/ocsp_peer/mini-ca/intermediate1/intermediate1_cert.pem", ocsp.Good) 1610 1611 for _, test := range []struct { 1612 name string 1613 config string 1614 opts []nats.Option 1615 responses int64 1616 revokes int64 1617 goods int64 1618 unknowns int64 1619 err error 1620 rerr error 1621 clean bool 1622 }{ 1623 { 1624 "Test expired revoked cert not actually deleted", 1625 ` 1626 port: -1 1627 http_port: 8222 1628 tls: { 1629 cert_file: "configs/certs/ocsp_peer/mini-ca/server1/TestServer1_bundle.pem" 1630 key_file: "configs/certs/ocsp_peer/mini-ca/server1/private/TestServer1_keypair.pem" 1631 ca_file: "configs/certs/ocsp_peer/mini-ca/root/root_cert.pem" 1632 timeout: 5 1633 verify: true 1634 # Turn on CA OCSP check so this revoked client should NOT be able to connect 1635 ocsp_peer: { 1636 verify: true 1637 ca_timeout: 0.5 1638 } 1639 } 1640 # preserve revoked true 1641 ocsp_cache: { 1642 type: local 1643 preserve_revoked: true 1644 } 1645 `, 1646 []nats.Option{ 1647 nats.ClientCert("./configs/certs/ocsp_peer/mini-ca/client1/UserA1_bundle.pem", "./configs/certs/ocsp_peer/mini-ca/client1/private/UserA1_keypair.pem"), 1648 nats.RootCAs("./configs/certs/ocsp_peer/mini-ca/root/root_cert.pem"), 1649 nats.ErrorHandler(noOpErrHandler), 1650 }, 1651 1, 1652 1, 1653 0, 1654 0, 1655 errors.New("remote error: tls: bad certificate"), 1656 errors.New("expect error"), 1657 true, 1658 }, 1659 { 1660 "Test expired revoked cert replaced by current good cert", 1661 ` 1662 port: -1 1663 http_port: 8222 1664 tls: { 1665 cert_file: "configs/certs/ocsp_peer/mini-ca/server1/TestServer1_bundle.pem" 1666 key_file: "configs/certs/ocsp_peer/mini-ca/server1/private/TestServer1_keypair.pem" 1667 ca_file: "configs/certs/ocsp_peer/mini-ca/root/root_cert.pem" 1668 timeout: 5 1669 verify: true 1670 # Turn on CA OCSP check so this revoked client should NOT be able to connect 1671 ocsp_peer: true 1672 } 1673 # preserve revoked true 1674 ocsp_cache: { 1675 type: local 1676 preserve_revoked: true 1677 } 1678 `, 1679 []nats.Option{ 1680 nats.ClientCert("./configs/certs/ocsp_peer/mini-ca/client1/UserA1_bundle.pem", "./configs/certs/ocsp_peer/mini-ca/client1/private/UserA1_keypair.pem"), 1681 nats.RootCAs("./configs/certs/ocsp_peer/mini-ca/root/root_cert.pem"), 1682 nats.ErrorHandler(noOpErrHandler), 1683 }, 1684 2, 1685 0, 1686 2, 1687 0, 1688 nil, 1689 nil, 1690 false, 1691 }, 1692 } { 1693 t.Run(test.name, func(t *testing.T) { 1694 var intermediateCA1Responder *http.Server 1695 // clean slate starting the test and start the leaf CA responder for first run 1696 if test.clean { 1697 deleteLocalStore(t, "") 1698 // establish the revoked item (expired) in cache 1699 c := []byte(` 1700 { 1701 "5xL/SuHl6JN0OmxrNMpzVMTA73JVYcRfGX8+HvJinEI=": { 1702 "subject": "CN=UserA1,O=Testnats,L=Tacoma,ST=WA,C=US", 1703 "cached_at": "2023-05-29T17:56:45Z", 1704 "resp_status": "revoked", 1705 "resp_expires": "2023-05-29T17:56:49Z", 1706 "resp": "/wYAAFMyc1R3TwBSBQBao1Qr1QzUMIIGUQoBAKCCBkowggZGBgkrBgEFBQcwAQEEggY3MIIGMzCB46FZMFcxCzAJBgNVBAYTAlVTEQ0gCAwCV0ExDzANAQ0wBwwGVGFjb21hMREwDwEROAoMCFRlc3RuYXRzMRcwFQET8HQDDA5PQ1NQIFJlc3BvbmRlchgPMjAyMzA1MjkxNzU2MDBaMHUwczBNMAkGBSsOAwIaBQAEFKgwn5fplwQy+DsulBg5SRpx0iaYBBS1kW5PZLcWhHb5tL6ZzmCVmBqOnQIUXKGv1Xy7Fu/Cx+ZT/JQa7SS7tBc2ZAAQNDVaoBE2dwD0QQE0OVowDQYJKoZIhvcNAQELBQADggEBAGAax/vkv3SBFNbxp2utc/N6Rje4E0ceC972sWgqYjzYrH0oc/acg+OAXaxUjwqoQWaT+dHaI4D5qoTkMx7XlWATjI2L72IUTf6Luo92jPzyDFwb10CdeFHtRtEYD54Qbi/nD4oxQ8cSoLKC3wft2l3E/mK/1I4Mxwq15CioK4MhfzTISoeGZbjDXPKgloJOG3rn9v64vFGV6dosbLgaXEs+MPcCsPQYkwhOOyazuewRmIDOBp5QSsKPhqsT8Rs20t8LGTMkvjZniFWJs90l9QL9F1m3obq5nyuxrGt+7Rf5zoj4T+0XCOGtE+b7cRCLg43tFuTbaAQG8Z+qkPzpza+gggQ1MIIEMTCCBC0wggMVoAMCAQICFCnhUo39pSqH6x3kHUds4YpYaXOrOj8BBDBaUSLaLwIIGjAYSS+oEUludGVybWVkaWF0ZSBDQSAxMB4XDTIzMDUwMTE5MjgzOVoXDTMzMDQyOA0PUasVAEkMMIIBIi4nAgABBQD0QAEPADCCAQoCggEBAKMMyuuA66EOHnGb07P5Zc5wwiEGPDHBBn6lqErhIaN0VJ9XzlDWwyk8Q7CdPlSU7o36DXFs316eATB5bLuXXa+7WwV3cp9V5mZF9OLCz3sOWNYUanYprOMwKA3uvcqqrh8e70Dzw6sX8tfsDeH7aJoJg5kRWEKU+A3Umm+fO+hW8Km3GBqRQXxD49uxAfGtCznXZZjmFbAXqVZu+4R6wMxndfz2dYQxeMVtUY/QGdMWT4fvWzO5et3+X6hq/URUAPOkplv9O2U4T4JPucS9yZpW/FTxWC/L7vQI/bfsrSgIZpv4eJgy27FW3Q4xusbjVvUCL/t2KLvEi/Nr2qodOCECAwEAAaOB7TCB6jAdBgNVHQ4EFgQUy15QYHqrL6k7HiSrAkKN7IFgSBMwHwYDVR0jBBgwFoBSyQNQMAwGA1UdEwEB/wQCMAAwDgYDVR0PAQ4YBAMCB4AwFgEeACUBEBAMMAoGCIm0sAMJMD0GA1UdHwQ2MDQwMqAwoC6GLGh0dHA6Ly8xMjcuMC4wLjE6MTg4ODgvaV1WKDFfY3JsLmRlcjAzEUscAQEEJzAlMCMRWwwwAYYXWkoALhICkTnw/0hlzm2RRjA3tvJ2wELj9e7pMg5GtdWdrLDyI/U1qBxhZoHADbyku7W+R1iL8dFfc4PSmdo+owsygZakvahXjv49xJNX7wV3YMmIHC4lfurIlY2mSnPlu2zEOwEDkI0S9WkTxXmHrkXLSciQJDkwzye6MR5fW+APk4JmKDPc46Go/K1A0EgxY/ugahMYsYtZu++W+IOYbEoYNxoCrcJCHX4c3Ep3t/Wulz4X6DWWhaDkMMUDC2JVE8E/3xUbw0X3adZe9Xf8T+goOz7wLCAigXKj1hvRUmOGISIGelv0KsfluZesG1a1TGLp+W9JX0M9nOaFOvjJTDP96aqIjs8oXGk=" 1707 } 1708 }`) 1709 err := writeCacheFile("", c) 1710 if err != nil { 1711 t.Fatal(err) 1712 } 1713 } else { 1714 intermediateCA1Responder = newOCSPResponderIntermediateCA1(t) 1715 intermediateCA1ResponderURL := fmt.Sprintf("http://%s", intermediateCA1Responder.Addr) 1716 setOCSPStatus(t, intermediateCA1ResponderURL, "configs/certs/ocsp_peer/mini-ca/client1/UserA1_cert.pem", ocsp.Good) 1717 defer intermediateCA1Responder.Shutdown(ctx) 1718 } 1719 content := test.config 1720 conf := createConfFile(t, []byte(content)) 1721 s, opts := RunServerWithConfig(conf) 1722 defer s.Shutdown() 1723 nc, err := nats.Connect(fmt.Sprintf("tls://localhost:%d", opts.Port), test.opts...) 1724 if test.err == nil && err != nil { 1725 t.Errorf("Expected to connect, got %v", err) 1726 } else if test.err != nil && err == nil { 1727 t.Errorf("Expected error on connect") 1728 } else if test.err != nil && err != nil { 1729 // Error on connect was expected 1730 if test.err.Error() != err.Error() { 1731 t.Errorf("Expected error %s, got: %s", test.err, err) 1732 } 1733 return 1734 } 1735 defer nc.Close() 1736 v := monitorGetVarzHelper(t, 8222) 1737 if v.OCSPResponseCache == nil { 1738 t.Fatalf("Expected OCSP statistics to be in varz") 1739 } 1740 responses := v.OCSPResponseCache.Responses 1741 revokes := v.OCSPResponseCache.Revokes 1742 goods := v.OCSPResponseCache.Goods 1743 unknowns := v.OCSPResponseCache.Unknowns 1744 if !(responses == test.responses && revokes == test.revokes && goods == test.goods && unknowns == test.unknowns) { 1745 t.Fatalf("Expected %d response, %d revoked, %d good, %d unknown; got [%d] and [%d] and [%d] and [%d]", test.responses, test.revokes, test.goods, test.unknowns, responses, revokes, goods, unknowns) 1746 } 1747 }) 1748 } 1749 } 1750 1751 // TestOCSPStapleFeatureInterop is a test of a NATS client (AIA enabled at leaf and cert) connecting to a NATS Server 1752 // in which both ocsp_peer is enabled on NATS client connections (verify client) and the ocsp staple is enabled such 1753 // that the NATS Server will staple its own OCSP response and make available to the NATS client during handshake. 1754 func TestOCSPStapleFeatureInterop(t *testing.T) { 1755 ctx, cancel := context.WithCancel(context.Background()) 1756 defer cancel() 1757 1758 rootCAResponder := newOCSPResponderRootCA(t) 1759 rootCAResponderURL := fmt.Sprintf("http://%s", rootCAResponder.Addr) 1760 defer rootCAResponder.Shutdown(ctx) 1761 setOCSPStatus(t, rootCAResponderURL, "configs/certs/ocsp_peer/mini-ca/intermediate1/intermediate1_cert.pem", ocsp.Good) 1762 1763 intermediateCA1Responder := newOCSPResponderIntermediateCA1(t) 1764 intermediateCA1ResponderURL := fmt.Sprintf("http://%s", intermediateCA1Responder.Addr) 1765 defer intermediateCA1Responder.Shutdown(ctx) 1766 setOCSPStatus(t, intermediateCA1ResponderURL, "configs/certs/ocsp_peer/mini-ca/server1/TestServer1_cert.pem", ocsp.Good) 1767 1768 for _, test := range []struct { 1769 name string 1770 config string 1771 opts []nats.Option 1772 err error 1773 rerr error 1774 configure func() 1775 }{ 1776 { 1777 "Interop: Both Good: mTLS OCSP peer check on inbound client connection and server's OCSP staple validated at client", 1778 ` 1779 port: -1 1780 ocsp_cache: true 1781 ocsp: { 1782 mode: always 1783 } 1784 tls: { 1785 cert_file: "configs/certs/ocsp_peer/mini-ca/server1/TestServer1_bundle.pem" 1786 key_file: "configs/certs/ocsp_peer/mini-ca/server1/private/TestServer1_keypair.pem" 1787 ca_file: "configs/certs/ocsp_peer/mini-ca/root/root_cert.pem" 1788 timeout: 5 1789 verify: true 1790 # Long form configuration, non-default ca_timeout 1791 ocsp_peer: { 1792 verify: true 1793 ca_timeout: 5 1794 allowed_clockskew: 30 1795 } 1796 } 1797 `, 1798 []nats.Option{ 1799 nats.Secure(&tls.Config{ 1800 VerifyConnection: func(s tls.ConnectionState) error { 1801 if s.OCSPResponse == nil { 1802 return fmt.Errorf("expected OCSP staple to be present") 1803 } 1804 resp, err := ocsp.ParseResponse(s.OCSPResponse, s.VerifiedChains[0][1]) 1805 if err != nil || resp.Status != ocsp.Good { 1806 return fmt.Errorf("expected a valid GOOD stapled response") 1807 } 1808 return nil 1809 }, 1810 }), 1811 nats.ClientCert("./configs/certs/ocsp_peer/mini-ca/client1/UserA1_bundle.pem", "./configs/certs/ocsp_peer/mini-ca/client1/private/UserA1_keypair.pem"), 1812 nats.RootCAs("./configs/certs/ocsp_peer/mini-ca/root/root_cert.pem"), 1813 nats.ErrorHandler(noOpErrHandler), 1814 }, 1815 nil, 1816 nil, 1817 func() { 1818 setOCSPStatus(t, intermediateCA1ResponderURL, "configs/certs/ocsp_peer/mini-ca/client1/UserA1_cert.pem", ocsp.Good) 1819 }, 1820 }, 1821 { 1822 "Interop: Bad Client: mTLS OCSP peer check on inbound client connection and server's OCSP staple validated at client", 1823 ` 1824 port: -1 1825 ocsp_cache: true 1826 ocsp: { 1827 mode: always 1828 } 1829 tls: { 1830 cert_file: "configs/certs/ocsp_peer/mini-ca/server1/TestServer1_bundle.pem" 1831 key_file: "configs/certs/ocsp_peer/mini-ca/server1/private/TestServer1_keypair.pem" 1832 ca_file: "configs/certs/ocsp_peer/mini-ca/root/root_cert.pem" 1833 timeout: 5 1834 verify: true 1835 # Long form configuration, non-default ca_timeout 1836 ocsp_peer: { 1837 verify: true 1838 ca_timeout: 5 1839 allowed_clockskew: 30 1840 } 1841 } 1842 `, 1843 []nats.Option{ 1844 nats.Secure(&tls.Config{ 1845 VerifyConnection: func(s tls.ConnectionState) error { 1846 if s.OCSPResponse == nil { 1847 return fmt.Errorf("expected OCSP staple to be present") 1848 } 1849 resp, err := ocsp.ParseResponse(s.OCSPResponse, s.VerifiedChains[0][1]) 1850 if err != nil || resp.Status != ocsp.Good { 1851 return fmt.Errorf("expected a valid GOOD stapled response") 1852 } 1853 return nil 1854 }, 1855 }), 1856 nats.ClientCert("./configs/certs/ocsp_peer/mini-ca/client1/UserA1_bundle.pem", "./configs/certs/ocsp_peer/mini-ca/client1/private/UserA1_keypair.pem"), 1857 nats.RootCAs("./configs/certs/ocsp_peer/mini-ca/root/root_cert.pem"), 1858 nats.ErrorHandler(noOpErrHandler), 1859 }, 1860 fmt.Errorf("remote error: tls: bad certificate"), 1861 nil, 1862 func() { 1863 setOCSPStatus(t, intermediateCA1ResponderURL, "configs/certs/ocsp_peer/mini-ca/client1/UserA1_cert.pem", ocsp.Revoked) 1864 }, 1865 }, 1866 } { 1867 t.Run(test.name, func(t *testing.T) { 1868 deleteLocalStore(t, "") 1869 test.configure() 1870 content := test.config 1871 conf := createConfFile(t, []byte(content)) 1872 1873 s, opts := RunServerWithConfig(conf) 1874 defer s.Shutdown() 1875 nc, err := nats.Connect(fmt.Sprintf("tls://localhost:%d", opts.Port), test.opts...) 1876 if test.err == nil && err != nil { 1877 t.Errorf("Expected to connect, got %v", err) 1878 } else if test.err != nil && err == nil { 1879 t.Errorf("Expected error on connect") 1880 } else if test.err != nil && err != nil { 1881 // Error on connect was expected 1882 if test.err.Error() != err.Error() { 1883 t.Errorf("Expected error %s, got: %s", test.err, err) 1884 } 1885 return 1886 } 1887 defer nc.Close() 1888 nc.Subscribe("ping", func(m *nats.Msg) { 1889 m.Respond([]byte("pong")) 1890 }) 1891 nc.Flush() 1892 _, err = nc.Request("ping", []byte("ping"), 250*time.Millisecond) 1893 if test.rerr != nil && err == nil { 1894 t.Errorf("Expected error getting response") 1895 } else if test.rerr == nil && err != nil { 1896 t.Errorf("Expected response") 1897 } 1898 }) 1899 } 1900 } 1901 1902 // TestOCSPPeerWarnOnlyOption is test of NATS client that is OCSP Revoked status but allowed to pass with warn_only option 1903 func TestOCSPPeerWarnOnlyOption(t *testing.T) { 1904 ctx, cancel := context.WithCancel(context.Background()) 1905 defer cancel() 1906 1907 rootCAResponder := newOCSPResponderRootCA(t) 1908 rootCAResponderURL := fmt.Sprintf("http://%s", rootCAResponder.Addr) 1909 defer rootCAResponder.Shutdown(ctx) 1910 setOCSPStatus(t, rootCAResponderURL, "configs/certs/ocsp_peer/mini-ca/intermediate1/intermediate1_cert.pem", ocsp.Good) 1911 1912 intermediateCA1Responder := newOCSPResponderIntermediateCA1(t) 1913 intermediateCA1ResponderURL := fmt.Sprintf("http://%s", intermediateCA1Responder.Addr) 1914 defer intermediateCA1Responder.Shutdown(ctx) 1915 setOCSPStatus(t, intermediateCA1ResponderURL, "configs/certs/ocsp_peer/mini-ca/client1/UserA1_cert.pem", ocsp.Revoked) 1916 1917 for _, test := range []struct { 1918 name string 1919 config string 1920 opts []nats.Option 1921 err error 1922 rerr error 1923 configure func() 1924 }{ 1925 { 1926 "Revoked NATS client with warn_only explicitly set to false", 1927 ` 1928 port: -1 1929 # Cache configuration is default 1930 tls: { 1931 cert_file: "configs/certs/ocsp_peer/mini-ca/server1/TestServer1_bundle.pem" 1932 key_file: "configs/certs/ocsp_peer/mini-ca/server1/private/TestServer1_keypair.pem" 1933 ca_file: "configs/certs/ocsp_peer/mini-ca/root/root_cert.pem" 1934 timeout: 5 1935 verify: true 1936 # Enable OCSP peer but with warn_only option set to false 1937 ocsp_peer: { 1938 verify: true 1939 warn_only: false 1940 } 1941 } 1942 `, 1943 []nats.Option{ 1944 nats.ClientCert("./configs/certs/ocsp_peer/mini-ca/client1/UserA1_bundle.pem", "./configs/certs/ocsp_peer/mini-ca/client1/private/UserA1_keypair.pem"), 1945 nats.RootCAs("./configs/certs/ocsp_peer/mini-ca/root/root_cert.pem"), 1946 nats.ErrorHandler(noOpErrHandler), 1947 }, 1948 errors.New("remote error: tls: bad certificate"), 1949 errors.New("expect error"), 1950 func() {}, 1951 }, 1952 { 1953 "Revoked NATS client with warn_only explicitly set to true", 1954 ` 1955 port: -1 1956 # Cache configuration is default 1957 tls: { 1958 cert_file: "configs/certs/ocsp_peer/mini-ca/server1/TestServer1_bundle.pem" 1959 key_file: "configs/certs/ocsp_peer/mini-ca/server1/private/TestServer1_keypair.pem" 1960 ca_file: "configs/certs/ocsp_peer/mini-ca/root/root_cert.pem" 1961 timeout: 5 1962 verify: true 1963 # Enable OCSP peer but with warn_only option set to true 1964 ocsp_peer: { 1965 verify: true 1966 warn_only: true 1967 } 1968 } 1969 `, 1970 []nats.Option{ 1971 nats.ClientCert("./configs/certs/ocsp_peer/mini-ca/client1/UserA1_bundle.pem", "./configs/certs/ocsp_peer/mini-ca/client1/private/UserA1_keypair.pem"), 1972 nats.RootCAs("./configs/certs/ocsp_peer/mini-ca/root/root_cert.pem"), 1973 nats.ErrorHandler(noOpErrHandler), 1974 }, 1975 nil, 1976 nil, 1977 func() {}, 1978 }, 1979 } { 1980 t.Run(test.name, func(t *testing.T) { 1981 deleteLocalStore(t, "") 1982 test.configure() 1983 content := test.config 1984 conf := createConfFile(t, []byte(content)) 1985 s, opts := RunServerWithConfig(conf) 1986 defer s.Shutdown() 1987 nc, err := nats.Connect(fmt.Sprintf("tls://localhost:%d", opts.Port), test.opts...) 1988 if test.err == nil && err != nil { 1989 t.Errorf("Expected to connect, got %v", err) 1990 } else if test.err != nil && err == nil { 1991 t.Errorf("Expected error on connect") 1992 } else if test.err != nil && err != nil { 1993 // Error on connect was expected 1994 if test.err.Error() != err.Error() { 1995 t.Errorf("Expected error %s, got: %s", test.err, err) 1996 } 1997 return 1998 } 1999 defer nc.Close() 2000 }) 2001 } 2002 } 2003 2004 // TestOCSPPeerUnknownIsGoodOption is test of NATS client that is OCSP status Unknown from its OCSP Responder but we treat 2005 // status Unknown as "Good" 2006 func TestOCSPPeerUnknownIsGoodOption(t *testing.T) { 2007 ctx, cancel := context.WithCancel(context.Background()) 2008 defer cancel() 2009 2010 rootCAResponder := newOCSPResponderRootCA(t) 2011 rootCAResponderURL := fmt.Sprintf("http://%s", rootCAResponder.Addr) 2012 defer rootCAResponder.Shutdown(ctx) 2013 setOCSPStatus(t, rootCAResponderURL, "configs/certs/ocsp_peer/mini-ca/intermediate1/intermediate1_cert.pem", ocsp.Good) 2014 2015 intermediateCA1Responder := newOCSPResponderIntermediateCA1(t) 2016 defer intermediateCA1Responder.Shutdown(ctx) 2017 2018 for _, test := range []struct { 2019 name string 2020 config string 2021 opts []nats.Option 2022 err error 2023 rerr error 2024 configure func() 2025 }{ 2026 { 2027 "Unknown NATS client with no unknown_is_good option set (default false)", 2028 ` 2029 port: -1 2030 # Cache configuration is default 2031 tls: { 2032 cert_file: "configs/certs/ocsp_peer/mini-ca/server1/TestServer1_bundle.pem" 2033 key_file: "configs/certs/ocsp_peer/mini-ca/server1/private/TestServer1_keypair.pem" 2034 ca_file: "configs/certs/ocsp_peer/mini-ca/root/root_cert.pem" 2035 timeout: 5 2036 verify: true 2037 # Short form configuration 2038 ocsp_peer: true 2039 } 2040 `, 2041 []nats.Option{ 2042 nats.ClientCert("./configs/certs/ocsp_peer/mini-ca/client1/UserA1_bundle.pem", "./configs/certs/ocsp_peer/mini-ca/client1/private/UserA1_keypair.pem"), 2043 nats.RootCAs("./configs/certs/ocsp_peer/mini-ca/root/root_cert.pem"), 2044 nats.ErrorHandler(noOpErrHandler), 2045 }, 2046 errors.New("remote error: tls: bad certificate"), 2047 errors.New("expect error"), 2048 func() {}, 2049 }, 2050 { 2051 "Unknown NATS client with unknown_is_good set to true", 2052 ` 2053 port: -1 2054 # Cache configuration is default 2055 tls: { 2056 cert_file: "configs/certs/ocsp_peer/mini-ca/server1/TestServer1_bundle.pem" 2057 key_file: "configs/certs/ocsp_peer/mini-ca/server1/private/TestServer1_keypair.pem" 2058 ca_file: "configs/certs/ocsp_peer/mini-ca/root/root_cert.pem" 2059 timeout: 5 2060 verify: true 2061 # Long form configuration 2062 ocsp_peer: { 2063 verify: true 2064 unknown_is_good: true 2065 } 2066 } 2067 `, 2068 []nats.Option{ 2069 nats.ClientCert("./configs/certs/ocsp_peer/mini-ca/client1/UserA1_bundle.pem", "./configs/certs/ocsp_peer/mini-ca/client1/private/UserA1_keypair.pem"), 2070 nats.RootCAs("./configs/certs/ocsp_peer/mini-ca/root/root_cert.pem"), 2071 nats.ErrorHandler(noOpErrHandler), 2072 }, 2073 nil, 2074 nil, 2075 func() {}, 2076 }, 2077 } { 2078 t.Run(test.name, func(t *testing.T) { 2079 deleteLocalStore(t, "") 2080 test.configure() 2081 content := test.config 2082 conf := createConfFile(t, []byte(content)) 2083 s, opts := RunServerWithConfig(conf) 2084 defer s.Shutdown() 2085 nc, err := nats.Connect(fmt.Sprintf("tls://localhost:%d", opts.Port), test.opts...) 2086 if test.err == nil && err != nil { 2087 t.Errorf("Expected to connect, got %v", err) 2088 } else if test.err != nil && err == nil { 2089 t.Errorf("Expected error on connect") 2090 } else if test.err != nil && err != nil { 2091 // Error on connect was expected 2092 if test.err.Error() != err.Error() { 2093 t.Errorf("Expected error %s, got: %s", test.err, err) 2094 } 2095 return 2096 } 2097 defer nc.Close() 2098 }) 2099 } 2100 } 2101 2102 // TestOCSPPeerAllowWhenCAUnreachableOption is test of the allow_when_ca_unreachable peer option 2103 func TestOCSPPeerAllowWhenCAUnreachableOption(t *testing.T) { 2104 ctx, cancel := context.WithCancel(context.Background()) 2105 defer cancel() 2106 2107 rootCAResponder := newOCSPResponderRootCA(t) 2108 rootCAResponderURL := fmt.Sprintf("http://%s", rootCAResponder.Addr) 2109 defer rootCAResponder.Shutdown(ctx) 2110 setOCSPStatus(t, rootCAResponderURL, "configs/certs/ocsp_peer/mini-ca/intermediate1/intermediate1_cert.pem", ocsp.Good) 2111 2112 for _, test := range []struct { 2113 name string 2114 config string 2115 opts []nats.Option 2116 cachedResponse string 2117 err error 2118 rerr error 2119 }{ 2120 { 2121 "Expired Revoked response in cache for UserA1 -- should be rejected connection (expired revoke honored)", 2122 ` 2123 port: -1 2124 http_port: 8222 2125 tls: { 2126 cert_file: "configs/certs/ocsp_peer/mini-ca/server1/TestServer1_bundle.pem" 2127 key_file: "configs/certs/ocsp_peer/mini-ca/server1/private/TestServer1_keypair.pem" 2128 ca_file: "configs/certs/ocsp_peer/mini-ca/root/root_cert.pem" 2129 timeout: 5 2130 verify: true 2131 # Turn on CA OCSP check but allow when CA is unreachable 2132 ocsp_peer: { 2133 verify: true 2134 ca_timeout: 0.5 2135 allow_when_ca_unreachable: true 2136 } 2137 } 2138 # preserve revoked true 2139 ocsp_cache: { 2140 type: local 2141 preserve_revoked: true 2142 } 2143 `, 2144 []nats.Option{ 2145 nats.ClientCert("./configs/certs/ocsp_peer/mini-ca/client1/UserA1_bundle.pem", "./configs/certs/ocsp_peer/mini-ca/client1/private/UserA1_keypair.pem"), 2146 nats.RootCAs("./configs/certs/ocsp_peer/mini-ca/root/root_cert.pem"), 2147 nats.ErrorHandler(noOpErrHandler), 2148 }, 2149 ` 2150 { 2151 "5xL/SuHl6JN0OmxrNMpzVMTA73JVYcRfGX8+HvJinEI=": { 2152 "subject": "CN=UserA1,O=Testnats,L=Tacoma,ST=WA,C=US", 2153 "cached_at": "2023-05-29T17:56:45Z", 2154 "resp_status": "revoked", 2155 "resp_expires": "2023-05-29T17:56:49Z", 2156 "resp": "/wYAAFMyc1R3TwBSBQBao1Qr1QzUMIIGUQoBAKCCBkowggZGBgkrBgEFBQcwAQEEggY3MIIGMzCB46FZMFcxCzAJBgNVBAYTAlVTEQ0gCAwCV0ExDzANAQ0wBwwGVGFjb21hMREwDwEROAoMCFRlc3RuYXRzMRcwFQET8HQDDA5PQ1NQIFJlc3BvbmRlchgPMjAyMzA1MjkxNzU2MDBaMHUwczBNMAkGBSsOAwIaBQAEFKgwn5fplwQy+DsulBg5SRpx0iaYBBS1kW5PZLcWhHb5tL6ZzmCVmBqOnQIUXKGv1Xy7Fu/Cx+ZT/JQa7SS7tBc2ZAAQNDVaoBE2dwD0QQE0OVowDQYJKoZIhvcNAQELBQADggEBAGAax/vkv3SBFNbxp2utc/N6Rje4E0ceC972sWgqYjzYrH0oc/acg+OAXaxUjwqoQWaT+dHaI4D5qoTkMx7XlWATjI2L72IUTf6Luo92jPzyDFwb10CdeFHtRtEYD54Qbi/nD4oxQ8cSoLKC3wft2l3E/mK/1I4Mxwq15CioK4MhfzTISoeGZbjDXPKgloJOG3rn9v64vFGV6dosbLgaXEs+MPcCsPQYkwhOOyazuewRmIDOBp5QSsKPhqsT8Rs20t8LGTMkvjZniFWJs90l9QL9F1m3obq5nyuxrGt+7Rf5zoj4T+0XCOGtE+b7cRCLg43tFuTbaAQG8Z+qkPzpza+gggQ1MIIEMTCCBC0wggMVoAMCAQICFCnhUo39pSqH6x3kHUds4YpYaXOrOj8BBDBaUSLaLwIIGjAYSS+oEUludGVybWVkaWF0ZSBDQSAxMB4XDTIzMDUwMTE5MjgzOVoXDTMzMDQyOA0PUasVAEkMMIIBIi4nAgABBQD0QAEPADCCAQoCggEBAKMMyuuA66EOHnGb07P5Zc5wwiEGPDHBBn6lqErhIaN0VJ9XzlDWwyk8Q7CdPlSU7o36DXFs316eATB5bLuXXa+7WwV3cp9V5mZF9OLCz3sOWNYUanYprOMwKA3uvcqqrh8e70Dzw6sX8tfsDeH7aJoJg5kRWEKU+A3Umm+fO+hW8Km3GBqRQXxD49uxAfGtCznXZZjmFbAXqVZu+4R6wMxndfz2dYQxeMVtUY/QGdMWT4fvWzO5et3+X6hq/URUAPOkplv9O2U4T4JPucS9yZpW/FTxWC/L7vQI/bfsrSgIZpv4eJgy27FW3Q4xusbjVvUCL/t2KLvEi/Nr2qodOCECAwEAAaOB7TCB6jAdBgNVHQ4EFgQUy15QYHqrL6k7HiSrAkKN7IFgSBMwHwYDVR0jBBgwFoBSyQNQMAwGA1UdEwEB/wQCMAAwDgYDVR0PAQ4YBAMCB4AwFgEeACUBEBAMMAoGCIm0sAMJMD0GA1UdHwQ2MDQwMqAwoC6GLGh0dHA6Ly8xMjcuMC4wLjE6MTg4ODgvaV1WKDFfY3JsLmRlcjAzEUscAQEEJzAlMCMRWwwwAYYXWkoALhICkTnw/0hlzm2RRjA3tvJ2wELj9e7pMg5GtdWdrLDyI/U1qBxhZoHADbyku7W+R1iL8dFfc4PSmdo+owsygZakvahXjv49xJNX7wV3YMmIHC4lfurIlY2mSnPlu2zEOwEDkI0S9WkTxXmHrkXLSciQJDkwzye6MR5fW+APk4JmKDPc46Go/K1A0EgxY/ugahMYsYtZu++W+IOYbEoYNxoCrcJCHX4c3Ep3t/Wulz4X6DWWhaDkMMUDC2JVE8E/3xUbw0X3adZe9Xf8T+goOz7wLCAigXKj1hvRUmOGISIGelv0KsfluZesG1a1TGLp+W9JX0M9nOaFOvjJTDP96aqIjs8oXGk=" 2157 } 2158 }`, 2159 errors.New("remote error: tls: bad certificate"), 2160 errors.New("expect error"), 2161 }, 2162 { 2163 "Expired Good response in cache for UserA1 -- should be allowed connection (cached item irrelevant)", 2164 ` 2165 port: -1 2166 http_port: 8222 2167 tls: { 2168 cert_file: "configs/certs/ocsp_peer/mini-ca/server1/TestServer1_bundle.pem" 2169 key_file: "configs/certs/ocsp_peer/mini-ca/server1/private/TestServer1_keypair.pem" 2170 ca_file: "configs/certs/ocsp_peer/mini-ca/root/root_cert.pem" 2171 timeout: 5 2172 verify: true 2173 # Turn on CA OCSP check but allow when CA is unreachable 2174 ocsp_peer: { 2175 verify: true 2176 ca_timeout: 0.5 2177 allow_when_ca_unreachable: true 2178 } 2179 } 2180 # preserve revoked true 2181 ocsp_cache: { 2182 type: local 2183 preserve_revoked: true 2184 } 2185 `, 2186 []nats.Option{ 2187 nats.ClientCert("./configs/certs/ocsp_peer/mini-ca/client1/UserA1_bundle.pem", "./configs/certs/ocsp_peer/mini-ca/client1/private/UserA1_keypair.pem"), 2188 nats.RootCAs("./configs/certs/ocsp_peer/mini-ca/root/root_cert.pem"), 2189 nats.ErrorHandler(noOpErrHandler), 2190 }, 2191 ` 2192 { 2193 "5xL/SuHl6JN0OmxrNMpzVMTA73JVYcRfGX8+HvJinEI=": { 2194 "subject": "CN=UserA1,O=Testnats,L=Tacoma,ST=WA,C=US", 2195 "cached_at": "2023-06-05T16:33:52Z", 2196 "resp_status": "good", 2197 "resp_expires": "2023-06-05T16:33:55Z", 2198 "resp": "/wYAAFMyc1R3TwBYBQBgpzMn1wzUMIIGUwoBAKCCBkwwggZIBgkrBgEFBQcwAQEEggY5MIIGNTCB5aFZMFcxCzAJBgNVBAYTAlVTEQ0gCAwCV0ExDzANAQ0wBwwGVGFjb21hMREwDwEROAoMCFRlc3RuYXRzMRcwFQET8HYDDA5PQ1NQIFJlc3BvbmRlchgPMjAyMzA2MDUxNjMzMDBaMHcwdTBNMAkGBSsOAwIaBQAEFKgwn5fplwQy+DsulBg5SRpx0iaYBBS1kW5PZLcWhHb5tL6ZzmCVmBqOnQIUXKGv1Xy7Fu/Cx+ZT/JQa7SS7tBeAADZmABA1MVqgEToTAPRAATVaMA0GCSqGSIb3DQEBCwUAA4IBAQB9csJxA2VcpQYmC5lzI0dJJnEC1zcaP1oFbBm5VsZAbWh4mIGTqyEjMkucBqANTypnhWFRYcZE5nJE8tN8Aen0EBYkhk1wfEIhincaF3zs6x5RzigxQOqTPAanO55keKH5exYnfBcyCwAQiBbQaTXLJJdjerfqiRjqgsnLW8yl2IC8+kxTCfR4GHTK34mvqVWYYhP/xbaxTLJTp35t1vf1o78ct9R+z8W5sCSO4TsMNnExZlu4Ejeon/KivMR22j7nelTEaDCuaOl03WxKh9yhw2ix8V7lvR74wh5f4fjLZria6Y0+lUjwvvrZyBRwA62W/ihe3778q8KhLECFPQSaoIIENTCCBDEwggQtMIIDFaADAgECAhQp4VKN/aUqh+sd5B1HbOGKWGlzqzo/AQQwWlEk2jECCBowGEkxqBFJbnRlcm1lZGlhdGUgQ0EgMTAeFw0yMzA1MDExOTI4MzlaFw0zMzA0MjgND1GtFQBJDDCCASIuJwIAAQUA9EABDwAwggEKAoIBAQCjDMrrgOuhDh5xm9Oz+WXOcMIhBjwxwQZ+pahK4SGjdFSfV85Q1sMpPEOwnT5UlO6N+g1xbN9engEweWy7l12vu1sFd3KfVeZmRfTiws97DljWFGp2KazjMCgN7r3Kqq4fHu9A88OrF/LX7A3h+2iaCYOZEVhClPgN1JpvnzvoVvCptxgakUF8Q+PbsQHxrQs512WY5hWwF6lWbvuEesDMZ3X89nWEMXjFbVGP0BnTFk+H71szuXrd/l+oav1EVADzpKZb/TtlOE+CT7nEvcmaVvxU8Vgvy+70CP237K0oCGab+HiYMtuxVt0OMbrG41b1Ai/7dii7xIvza9qqHTghAgMBAAGjge0wgeowHQYDVR0OBBYEFMteUGB6qy+pOx4kqwJCjeyBYEgTMB8GA1UdIwQYMBaAUssDUDAMBgNVHRMBAf8EAjAAMA4GA1UdDwEOGAQDAgeAMBYBHgAlARAQDDAKBgiJtrADCTA9BgNVHR8ENjA0MDKgMKAuhixodHRwOi8vMTI3LjAuMC4xOjE4ODg4L2ldVigxX2NybC5kZXIwMxFLHAEBBCcwJTAjEVsMMAGGF1pKAC4SAgALBQD0AQEBAEhlzm2RRjA3tvJ2wELj9e7pMg5GtdWdrLDyI/U1qBxhZoHADbyku7W+R1iL8dFfc4PSmdo+owsygZakvahXjv49xJNX7wV3YMmIHC4lfurIlY2mSnPlu2zEOwEDkI0S9WkTxXmHrkXLSciQJDkwzye6MR5fW+APk4JmKDPc46Go/K1A0EgxY/ugahMYsYtZu++W+IOYbEoYNxoCrcJCHX4c3Ep3t/Wulz4X6DWWhaDkMMUDC2JVE8E/3xUbw0X3adZe9Xf8T+goOz7wLCAigXKj1hvRUmOGISIGelv0KsfluZesG1a1TGLp+W9JX0M9nOaFOvjJTDP96aqIjs8oXGk=" 2199 } 2200 }`, 2201 nil, 2202 nil, 2203 }, 2204 { 2205 "Expired Unknown response in cache for UserA1 -- should be allowed connection (cached item irrelevant)", 2206 ` 2207 port: -1 2208 http_port: 8222 2209 tls: { 2210 cert_file: "configs/certs/ocsp_peer/mini-ca/server1/TestServer1_bundle.pem" 2211 key_file: "configs/certs/ocsp_peer/mini-ca/server1/private/TestServer1_keypair.pem" 2212 ca_file: "configs/certs/ocsp_peer/mini-ca/root/root_cert.pem" 2213 timeout: 5 2214 verify: true 2215 # Turn on CA OCSP check but allow when CA is unreachable 2216 ocsp_peer: { 2217 verify: true 2218 ca_timeout: 0.5 2219 allow_when_ca_unreachable: true 2220 } 2221 } 2222 # preserve revoked true 2223 ocsp_cache: { 2224 type: local 2225 preserve_revoked: true 2226 } 2227 `, 2228 []nats.Option{ 2229 nats.ClientCert("./configs/certs/ocsp_peer/mini-ca/client1/UserA1_bundle.pem", "./configs/certs/ocsp_peer/mini-ca/client1/private/UserA1_keypair.pem"), 2230 nats.RootCAs("./configs/certs/ocsp_peer/mini-ca/root/root_cert.pem"), 2231 nats.ErrorHandler(noOpErrHandler), 2232 }, 2233 ` 2234 { 2235 "5xL/SuHl6JN0OmxrNMpzVMTA73JVYcRfGX8+HvJinEI=": { 2236 "subject": "CN=UserA1,O=Testnats,L=Tacoma,ST=WA,C=US", 2237 "cached_at": "2023-06-05T16:45:01Z", 2238 "resp_status": "unknown", 2239 "resp_expires": "2023-06-05T16:45:05Z", 2240 "resp": "/wYAAFMyc1R3TwBSBQBH1aW01wzUMIIGUwoBAKCCBkwwggZIBgkrBgEFBQcwAQEEggY5MIIGNTCB5aFZMFcxCzAJBgNVBAYTAlVTEQ0gCAwCV0ExDzANAQ0wBwwGVGFjb21hMREwDwEROAoMCFRlc3RuYXRzMRcwFQET8HYDDA5PQ1NQIFJlc3BvbmRlchgPMjAyMzA2MDUxNjQ1MDBaMHcwdTBNMAkGBSsOAwIaBQAEFKgwn5fplwQy+DsulBg5SRpx0iaYBBS1kW5PZLcWhHb5tL6ZzmCVmBqOnQIUXKGv1Xy7Fu/Cx+ZT/JQa7SS7tBeCADpmAAwxWqAROhMA9EABNVowDQYJKoZIhvcNAQELBQADggEBAAzwED88ngiFj3hLzIejZ8DE/ppticX0vgAjUM8oXjDjwNXpSQ5xdXHsDk4RAYAVpNyiAfL2fapwz91g3JuZot6npp8smtZC5D0YMKK8iMjrx2aMqVyv+ai/33WG8PRWpBNzSTYaLhlBFjhUrx8HDu97ozNbmfgDWzRS1LqkJRa5YXvkyppqYTFSX73DV9R9tOVOwZ0x5WEKst9IJ+88mXsOBGyuye2Gh9RK6KsLgaOwiD9FBf18WRKIixeVM1Y/xHc/iwFPi8k3Z6hZ6gHX8NboQ/djCyzYVSWsUedTo/62uuagHPRWoYci4HQl4bSFXfcEO/EkWGnqkWBHfYZ4soigggQ1MIIEMTCCBC0wggMVoAMCAQICFCnhUo39pSqH6x3kHUds4YpYaXOrOj8BBDBaUSTaMQIIGjAYSTGoEUludGVybWVkaWF0ZSBDQSAxMB4XDTIzMDUwMTE5MjgzOVoXDTMzMDQyOA0PUa0VAEkMMIIBIi4nAgABBQD0QAEPADCCAQoCggEBAKMMyuuA66EOHnGb07P5Zc5wwiEGPDHBBn6lqErhIaN0VJ9XzlDWwyk8Q7CdPlSU7o36DXFs316eATB5bLuXXa+7WwV3cp9V5mZF9OLCz3sOWNYUanYprOMwKA3uvcqqrh8e70Dzw6sX8tfsDeH7aJoJg5kRWEKU+A3Umm+fO+hW8Km3GBqRQXxD49uxAfGtCznXZZjmFbAXqVZu+4R6wMxndfz2dYQxeMVtUY/QGdMWT4fvWzO5et3+X6hq/URUAPOkplv9O2U4T4JPucS9yZpW/FTxWC/L7vQI/bfsrSgIZpv4eJgy27FW3Q4xusbjVvUCL/t2KLvEi/Nr2qodOCECAwEAAaOB7TCB6jAdBgNVHQ4EFgQUy15QYHqrL6k7HiSrAkKN7IFgSBMwHwYDVR0jBBgwFoBSywNQMAwGA1UdEwEB/wQCMAAwDgYDVR0PAQ4YBAMCB4AwFgEeACUBEBAMMAoGCIm2sAMJMD0GA1UdHwQ2MDQwMqAwoC6GLGh0dHA6Ly8xMjcuMC4wLjE6MTg4ODgvaV1WKDFfY3JsLmRlcjAzEUscAQEEJzAlMCMRWwwwAYYXWkoALhICkTnw/0hlzm2RRjA3tvJ2wELj9e7pMg5GtdWdrLDyI/U1qBxhZoHADbyku7W+R1iL8dFfc4PSmdo+owsygZakvahXjv49xJNX7wV3YMmIHC4lfurIlY2mSnPlu2zEOwEDkI0S9WkTxXmHrkXLSciQJDkwzye6MR5fW+APk4JmKDPc46Go/K1A0EgxY/ugahMYsYtZu++W+IOYbEoYNxoCrcJCHX4c3Ep3t/Wulz4X6DWWhaDkMMUDC2JVE8E/3xUbw0X3adZe9Xf8T+goOz7wLCAigXKj1hvRUmOGISIGelv0KsfluZesG1a1TGLp+W9JX0M9nOaFOvjJTDP96aqIjs8oXGk=" 2241 } 2242 }`, 2243 nil, 2244 nil, 2245 }, 2246 { 2247 "No response in cache for UserA1 -- should be allowed connection", 2248 ` 2249 port: -1 2250 http_port: 8222 2251 tls: { 2252 cert_file: "configs/certs/ocsp_peer/mini-ca/server1/TestServer1_bundle.pem" 2253 key_file: "configs/certs/ocsp_peer/mini-ca/server1/private/TestServer1_keypair.pem" 2254 ca_file: "configs/certs/ocsp_peer/mini-ca/root/root_cert.pem" 2255 timeout: 5 2256 verify: true 2257 # Turn on CA OCSP check but allow when CA is unreachable 2258 ocsp_peer: { 2259 verify: true 2260 ca_timeout: 0.5 2261 allow_when_ca_unreachable: true 2262 } 2263 } 2264 # preserve revoked true 2265 ocsp_cache: { 2266 type: local 2267 preserve_revoked: true 2268 } 2269 `, 2270 []nats.Option{ 2271 nats.ClientCert("./configs/certs/ocsp_peer/mini-ca/client1/UserA1_bundle.pem", "./configs/certs/ocsp_peer/mini-ca/client1/private/UserA1_keypair.pem"), 2272 nats.RootCAs("./configs/certs/ocsp_peer/mini-ca/root/root_cert.pem"), 2273 nats.ErrorHandler(noOpErrHandler), 2274 }, 2275 "", 2276 nil, 2277 nil, 2278 }, 2279 } { 2280 t.Run(test.name, func(t *testing.T) { 2281 deleteLocalStore(t, "") 2282 c := []byte(test.cachedResponse) 2283 err := writeCacheFile("", c) 2284 if err != nil { 2285 t.Fatal(err) 2286 } 2287 content := test.config 2288 conf := createConfFile(t, []byte(content)) 2289 s, opts := RunServerWithConfig(conf) 2290 defer s.Shutdown() 2291 nc, err := nats.Connect(fmt.Sprintf("tls://localhost:%d", opts.Port), test.opts...) 2292 if test.err == nil && err != nil { 2293 t.Errorf("Expected to connect, got %v", err) 2294 } else if test.err != nil && err == nil { 2295 t.Errorf("Expected error on connect") 2296 } else if test.err != nil && err != nil { 2297 // Error on connect was expected 2298 if test.err.Error() != err.Error() { 2299 t.Errorf("Expected error %s, got: %s", test.err, err) 2300 } 2301 return 2302 } 2303 defer nc.Close() 2304 }) 2305 } 2306 } 2307 2308 // TestOCSPResponseCacheLocalStoreOption is test of default and non-default local_store option 2309 func TestOCSPResponseCacheLocalStoreOpt(t *testing.T) { 2310 ctx, cancel := context.WithCancel(context.Background()) 2311 defer cancel() 2312 2313 rootCAResponder := newOCSPResponderRootCA(t) 2314 rootCAResponderURL := fmt.Sprintf("http://%s", rootCAResponder.Addr) 2315 defer rootCAResponder.Shutdown(ctx) 2316 setOCSPStatus(t, rootCAResponderURL, "configs/certs/ocsp_peer/mini-ca/intermediate1/intermediate1_cert.pem", ocsp.Good) 2317 2318 for _, test := range []struct { 2319 name string 2320 config string 2321 opts []nats.Option 2322 cachedResponse string 2323 err error 2324 rerr error 2325 storeLocation string 2326 }{ 2327 { 2328 "Test load from non-default local store _custom_; connect will reject only if cache file found and loaded", 2329 ` 2330 port: -1 2331 http_port: 8222 2332 tls: { 2333 cert_file: "configs/certs/ocsp_peer/mini-ca/server1/TestServer1_bundle.pem" 2334 key_file: "configs/certs/ocsp_peer/mini-ca/server1/private/TestServer1_keypair.pem" 2335 ca_file: "configs/certs/ocsp_peer/mini-ca/root/root_cert.pem" 2336 timeout: 5 2337 verify: true 2338 # Turn on CA OCSP check but allow when CA is unreachable 2339 ocsp_peer: { 2340 verify: true 2341 ca_timeout: 0.5 2342 allow_when_ca_unreachable: true 2343 } 2344 } 2345 # preserve revoked true 2346 ocsp_cache: { 2347 type: local 2348 local_store: "_custom_" 2349 preserve_revoked: true 2350 } 2351 `, 2352 []nats.Option{ 2353 nats.ClientCert("./configs/certs/ocsp_peer/mini-ca/client1/UserA1_bundle.pem", "./configs/certs/ocsp_peer/mini-ca/client1/private/UserA1_keypair.pem"), 2354 nats.RootCAs("./configs/certs/ocsp_peer/mini-ca/root/root_cert.pem"), 2355 nats.ErrorHandler(noOpErrHandler), 2356 }, 2357 ` 2358 { 2359 "5xL/SuHl6JN0OmxrNMpzVMTA73JVYcRfGX8+HvJinEI=": { 2360 "subject": "CN=UserA1,O=Testnats,L=Tacoma,ST=WA,C=US", 2361 "cached_at": "2023-05-29T17:56:45Z", 2362 "resp_status": "revoked", 2363 "resp_expires": "2023-05-29T17:56:49Z", 2364 "resp": "/wYAAFMyc1R3TwBSBQBao1Qr1QzUMIIGUQoBAKCCBkowggZGBgkrBgEFBQcwAQEEggY3MIIGMzCB46FZMFcxCzAJBgNVBAYTAlVTEQ0gCAwCV0ExDzANAQ0wBwwGVGFjb21hMREwDwEROAoMCFRlc3RuYXRzMRcwFQET8HQDDA5PQ1NQIFJlc3BvbmRlchgPMjAyMzA1MjkxNzU2MDBaMHUwczBNMAkGBSsOAwIaBQAEFKgwn5fplwQy+DsulBg5SRpx0iaYBBS1kW5PZLcWhHb5tL6ZzmCVmBqOnQIUXKGv1Xy7Fu/Cx+ZT/JQa7SS7tBc2ZAAQNDVaoBE2dwD0QQE0OVowDQYJKoZIhvcNAQELBQADggEBAGAax/vkv3SBFNbxp2utc/N6Rje4E0ceC972sWgqYjzYrH0oc/acg+OAXaxUjwqoQWaT+dHaI4D5qoTkMx7XlWATjI2L72IUTf6Luo92jPzyDFwb10CdeFHtRtEYD54Qbi/nD4oxQ8cSoLKC3wft2l3E/mK/1I4Mxwq15CioK4MhfzTISoeGZbjDXPKgloJOG3rn9v64vFGV6dosbLgaXEs+MPcCsPQYkwhOOyazuewRmIDOBp5QSsKPhqsT8Rs20t8LGTMkvjZniFWJs90l9QL9F1m3obq5nyuxrGt+7Rf5zoj4T+0XCOGtE+b7cRCLg43tFuTbaAQG8Z+qkPzpza+gggQ1MIIEMTCCBC0wggMVoAMCAQICFCnhUo39pSqH6x3kHUds4YpYaXOrOj8BBDBaUSLaLwIIGjAYSS+oEUludGVybWVkaWF0ZSBDQSAxMB4XDTIzMDUwMTE5MjgzOVoXDTMzMDQyOA0PUasVAEkMMIIBIi4nAgABBQD0QAEPADCCAQoCggEBAKMMyuuA66EOHnGb07P5Zc5wwiEGPDHBBn6lqErhIaN0VJ9XzlDWwyk8Q7CdPlSU7o36DXFs316eATB5bLuXXa+7WwV3cp9V5mZF9OLCz3sOWNYUanYprOMwKA3uvcqqrh8e70Dzw6sX8tfsDeH7aJoJg5kRWEKU+A3Umm+fO+hW8Km3GBqRQXxD49uxAfGtCznXZZjmFbAXqVZu+4R6wMxndfz2dYQxeMVtUY/QGdMWT4fvWzO5et3+X6hq/URUAPOkplv9O2U4T4JPucS9yZpW/FTxWC/L7vQI/bfsrSgIZpv4eJgy27FW3Q4xusbjVvUCL/t2KLvEi/Nr2qodOCECAwEAAaOB7TCB6jAdBgNVHQ4EFgQUy15QYHqrL6k7HiSrAkKN7IFgSBMwHwYDVR0jBBgwFoBSyQNQMAwGA1UdEwEB/wQCMAAwDgYDVR0PAQ4YBAMCB4AwFgEeACUBEBAMMAoGCIm0sAMJMD0GA1UdHwQ2MDQwMqAwoC6GLGh0dHA6Ly8xMjcuMC4wLjE6MTg4ODgvaV1WKDFfY3JsLmRlcjAzEUscAQEEJzAlMCMRWwwwAYYXWkoALhICkTnw/0hlzm2RRjA3tvJ2wELj9e7pMg5GtdWdrLDyI/U1qBxhZoHADbyku7W+R1iL8dFfc4PSmdo+owsygZakvahXjv49xJNX7wV3YMmIHC4lfurIlY2mSnPlu2zEOwEDkI0S9WkTxXmHrkXLSciQJDkwzye6MR5fW+APk4JmKDPc46Go/K1A0EgxY/ugahMYsYtZu++W+IOYbEoYNxoCrcJCHX4c3Ep3t/Wulz4X6DWWhaDkMMUDC2JVE8E/3xUbw0X3adZe9Xf8T+goOz7wLCAigXKj1hvRUmOGISIGelv0KsfluZesG1a1TGLp+W9JX0M9nOaFOvjJTDP96aqIjs8oXGk=" 2365 } 2366 }`, 2367 errors.New("remote error: tls: bad certificate"), 2368 errors.New("expect error"), 2369 "_custom_", 2370 }, 2371 { 2372 "Test load from default local store when \"\" set; connect will reject only if cache file found and loaded", 2373 ` 2374 port: -1 2375 http_port: 8222 2376 tls: { 2377 cert_file: "configs/certs/ocsp_peer/mini-ca/server1/TestServer1_bundle.pem" 2378 key_file: "configs/certs/ocsp_peer/mini-ca/server1/private/TestServer1_keypair.pem" 2379 ca_file: "configs/certs/ocsp_peer/mini-ca/root/root_cert.pem" 2380 timeout: 5 2381 verify: true 2382 # Turn on CA OCSP check but allow when CA is unreachable 2383 ocsp_peer: { 2384 verify: true 2385 ca_timeout: 0.5 2386 allow_when_ca_unreachable: true 2387 } 2388 } 2389 # preserve revoked true 2390 ocsp_cache: { 2391 type: local 2392 local_store: "" 2393 preserve_revoked: true 2394 } 2395 `, 2396 []nats.Option{ 2397 nats.ClientCert("./configs/certs/ocsp_peer/mini-ca/client1/UserA1_bundle.pem", "./configs/certs/ocsp_peer/mini-ca/client1/private/UserA1_keypair.pem"), 2398 nats.RootCAs("./configs/certs/ocsp_peer/mini-ca/root/root_cert.pem"), 2399 nats.ErrorHandler(noOpErrHandler), 2400 }, 2401 ` 2402 { 2403 "5xL/SuHl6JN0OmxrNMpzVMTA73JVYcRfGX8+HvJinEI=": { 2404 "subject": "CN=UserA1,O=Testnats,L=Tacoma,ST=WA,C=US", 2405 "cached_at": "2023-05-29T17:56:45Z", 2406 "resp_status": "revoked", 2407 "resp_expires": "2023-05-29T17:56:49Z", 2408 "resp": "/wYAAFMyc1R3TwBSBQBao1Qr1QzUMIIGUQoBAKCCBkowggZGBgkrBgEFBQcwAQEEggY3MIIGMzCB46FZMFcxCzAJBgNVBAYTAlVTEQ0gCAwCV0ExDzANAQ0wBwwGVGFjb21hMREwDwEROAoMCFRlc3RuYXRzMRcwFQET8HQDDA5PQ1NQIFJlc3BvbmRlchgPMjAyMzA1MjkxNzU2MDBaMHUwczBNMAkGBSsOAwIaBQAEFKgwn5fplwQy+DsulBg5SRpx0iaYBBS1kW5PZLcWhHb5tL6ZzmCVmBqOnQIUXKGv1Xy7Fu/Cx+ZT/JQa7SS7tBc2ZAAQNDVaoBE2dwD0QQE0OVowDQYJKoZIhvcNAQELBQADggEBAGAax/vkv3SBFNbxp2utc/N6Rje4E0ceC972sWgqYjzYrH0oc/acg+OAXaxUjwqoQWaT+dHaI4D5qoTkMx7XlWATjI2L72IUTf6Luo92jPzyDFwb10CdeFHtRtEYD54Qbi/nD4oxQ8cSoLKC3wft2l3E/mK/1I4Mxwq15CioK4MhfzTISoeGZbjDXPKgloJOG3rn9v64vFGV6dosbLgaXEs+MPcCsPQYkwhOOyazuewRmIDOBp5QSsKPhqsT8Rs20t8LGTMkvjZniFWJs90l9QL9F1m3obq5nyuxrGt+7Rf5zoj4T+0XCOGtE+b7cRCLg43tFuTbaAQG8Z+qkPzpza+gggQ1MIIEMTCCBC0wggMVoAMCAQICFCnhUo39pSqH6x3kHUds4YpYaXOrOj8BBDBaUSLaLwIIGjAYSS+oEUludGVybWVkaWF0ZSBDQSAxMB4XDTIzMDUwMTE5MjgzOVoXDTMzMDQyOA0PUasVAEkMMIIBIi4nAgABBQD0QAEPADCCAQoCggEBAKMMyuuA66EOHnGb07P5Zc5wwiEGPDHBBn6lqErhIaN0VJ9XzlDWwyk8Q7CdPlSU7o36DXFs316eATB5bLuXXa+7WwV3cp9V5mZF9OLCz3sOWNYUanYprOMwKA3uvcqqrh8e70Dzw6sX8tfsDeH7aJoJg5kRWEKU+A3Umm+fO+hW8Km3GBqRQXxD49uxAfGtCznXZZjmFbAXqVZu+4R6wMxndfz2dYQxeMVtUY/QGdMWT4fvWzO5et3+X6hq/URUAPOkplv9O2U4T4JPucS9yZpW/FTxWC/L7vQI/bfsrSgIZpv4eJgy27FW3Q4xusbjVvUCL/t2KLvEi/Nr2qodOCECAwEAAaOB7TCB6jAdBgNVHQ4EFgQUy15QYHqrL6k7HiSrAkKN7IFgSBMwHwYDVR0jBBgwFoBSyQNQMAwGA1UdEwEB/wQCMAAwDgYDVR0PAQ4YBAMCB4AwFgEeACUBEBAMMAoGCIm0sAMJMD0GA1UdHwQ2MDQwMqAwoC6GLGh0dHA6Ly8xMjcuMC4wLjE6MTg4ODgvaV1WKDFfY3JsLmRlcjAzEUscAQEEJzAlMCMRWwwwAYYXWkoALhICkTnw/0hlzm2RRjA3tvJ2wELj9e7pMg5GtdWdrLDyI/U1qBxhZoHADbyku7W+R1iL8dFfc4PSmdo+owsygZakvahXjv49xJNX7wV3YMmIHC4lfurIlY2mSnPlu2zEOwEDkI0S9WkTxXmHrkXLSciQJDkwzye6MR5fW+APk4JmKDPc46Go/K1A0EgxY/ugahMYsYtZu++W+IOYbEoYNxoCrcJCHX4c3Ep3t/Wulz4X6DWWhaDkMMUDC2JVE8E/3xUbw0X3adZe9Xf8T+goOz7wLCAigXKj1hvRUmOGISIGelv0KsfluZesG1a1TGLp+W9JX0M9nOaFOvjJTDP96aqIjs8oXGk=" 2409 } 2410 }`, 2411 errors.New("remote error: tls: bad certificate"), 2412 errors.New("expect error"), 2413 "_rc_", 2414 }, 2415 } { 2416 t.Run(test.name, func(t *testing.T) { 2417 deleteLocalStore(t, test.storeLocation) 2418 c := []byte(test.cachedResponse) 2419 err := writeCacheFile(test.storeLocation, c) 2420 if err != nil { 2421 t.Fatal(err) 2422 } 2423 content := test.config 2424 conf := createConfFile(t, []byte(content)) 2425 s, opts := RunServerWithConfig(conf) 2426 defer s.Shutdown() 2427 nc, err := nats.Connect(fmt.Sprintf("tls://localhost:%d", opts.Port), test.opts...) 2428 if test.err == nil && err != nil { 2429 t.Errorf("Expected to connect, got %v", err) 2430 } else if test.err != nil && err == nil { 2431 t.Errorf("Expected error on connect") 2432 } else if test.err != nil && err != nil { 2433 // Error on connect was expected 2434 if test.err.Error() != err.Error() { 2435 t.Errorf("Expected error %s, got: %s", test.err, err) 2436 } 2437 return 2438 } 2439 defer nc.Close() 2440 }) 2441 } 2442 } 2443 2444 // TestOCSPPeerIncrementalSaveLocalCache is test of timer-based response cache save as new entries added 2445 func TestOCSPPeerIncrementalSaveLocalCache(t *testing.T) { 2446 ctx, cancel := context.WithCancel(context.Background()) 2447 defer cancel() 2448 2449 rootCAResponder := newOCSPResponderRootCA(t) 2450 rootCAResponderURL := fmt.Sprintf("http://%s", rootCAResponder.Addr) 2451 defer rootCAResponder.Shutdown(ctx) 2452 setOCSPStatus(t, rootCAResponderURL, "configs/certs/ocsp_peer/mini-ca/intermediate1/intermediate1_cert.pem", ocsp.Good) 2453 setOCSPStatus(t, rootCAResponderURL, "configs/certs/ocsp_peer/mini-ca/intermediate2/intermediate2_cert.pem", ocsp.Good) 2454 2455 intermediateCA1Responder := newOCSPResponderIntermediateCA1(t) 2456 intermediateCA1ResponderURL := fmt.Sprintf("http://%s", intermediateCA1Responder.Addr) 2457 defer intermediateCA1Responder.Shutdown(ctx) 2458 setOCSPStatus(t, intermediateCA1ResponderURL, "configs/certs/ocsp_peer/mini-ca/client1/UserA1_cert.pem", ocsp.Good) 2459 2460 intermediateCA2Responder := newOCSPResponderIntermediateCA2(t) 2461 intermediateCA2ResponderURL := fmt.Sprintf("http://%s", intermediateCA2Responder.Addr) 2462 defer intermediateCA2Responder.Shutdown(ctx) 2463 setOCSPStatus(t, intermediateCA2ResponderURL, "configs/certs/ocsp_peer/mini-ca/client2/UserB1_cert.pem", ocsp.Good) 2464 2465 var fi os.FileInfo 2466 var err error 2467 2468 for _, test := range []struct { 2469 name string 2470 config string 2471 opts [][]nats.Option 2472 err error 2473 rerr error 2474 configure func() 2475 }{ 2476 { 2477 "Default cache, short form: mTLS OCSP peer check on inbound client connection, UserA1 client of intermediate CA 1", 2478 ` 2479 port: -1 2480 http_port: 8222 2481 tls: { 2482 cert_file: "configs/certs/ocsp_peer/mini-ca/server1/TestServer1_bundle.pem" 2483 key_file: "configs/certs/ocsp_peer/mini-ca/server1/private/TestServer1_keypair.pem" 2484 ca_file: "configs/certs/ocsp_peer/mini-ca/root/root_cert.pem" 2485 timeout: 5 2486 verify: true 2487 # Long form configuration 2488 ocsp_peer: { 2489 verify: true 2490 ca_timeout: 5 2491 allowed_clockskew: 30 2492 } 2493 } 2494 # Local cache with custom save_interval for testability 2495 ocsp_cache: { 2496 type: local 2497 # Save if dirty ever 1 second 2498 save_interval: 1 2499 } 2500 `, 2501 [][]nats.Option{ 2502 { 2503 nats.ClientCert("./configs/certs/ocsp_peer/mini-ca/client1/UserA1_bundle.pem", "./configs/certs/ocsp_peer/mini-ca/client1/private/UserA1_keypair.pem"), 2504 nats.RootCAs("./configs/certs/ocsp_peer/mini-ca/root/root_cert.pem"), 2505 nats.ErrorHandler(noOpErrHandler), 2506 }, 2507 { 2508 nats.ClientCert("./configs/certs/ocsp_peer/mini-ca/client2/UserB1_bundle.pem", "./configs/certs/ocsp_peer/mini-ca/client2/private/UserB1_keypair.pem"), 2509 nats.RootCAs("./configs/certs/ocsp_peer/mini-ca/root/root_cert.pem"), 2510 nats.ErrorHandler(noOpErrHandler), 2511 }, 2512 }, 2513 nil, 2514 nil, 2515 func() {}, 2516 }, 2517 } { 2518 t.Run(test.name, func(t *testing.T) { 2519 // Cleanup any previous test that saved a local cache 2520 deleteLocalStore(t, "") 2521 fi, err = statCacheFile("") 2522 if err != nil && fi != nil && fi.Size() != 0 { 2523 t.Fatalf("Expected no local cache file, got a FileInfo with size %d", fi.Size()) 2524 } 2525 test.configure() 2526 content := test.config 2527 conf := createConfFile(t, []byte(content)) 2528 s, opts := RunServerWithConfig(conf) 2529 defer s.Shutdown() 2530 2531 // Connect with UserA1 client and get a CA Response 2532 nc, err := nats.Connect(fmt.Sprintf("tls://localhost:%d", opts.Port), test.opts[0]...) 2533 if test.err == nil && err != nil { 2534 t.Errorf("Expected to connect, got %v", err) 2535 } else if test.err != nil && err == nil { 2536 t.Errorf("Expected error on connect") 2537 } else if test.err != nil && err != nil { 2538 // Error on connect was expected 2539 if test.err.Error() != err.Error() { 2540 t.Errorf("Expected error %s, got: %s", test.err, err) 2541 } 2542 return 2543 } 2544 nc.Close() 2545 time.Sleep(2 * time.Second) 2546 fi, err = statCacheFile("") 2547 if err == nil && fi != nil && fi.Size() > 0 { 2548 // good 2549 } else { 2550 if err != nil { 2551 t.Fatalf("Expected an extant local cache file, got error: %v", err) 2552 } 2553 if fi != nil { 2554 t.Fatalf("Expected non-zero size local cache file, got a FileInfo with size %d", fi.Size()) 2555 } 2556 } 2557 firstFi := fi 2558 // Connect with UserB1 client and get another CA Response 2559 nc, err = nats.Connect(fmt.Sprintf("tls://localhost:%d", opts.Port), test.opts[1]...) 2560 if test.err == nil && err != nil { 2561 t.Errorf("Expected to connect, got %v", err) 2562 } else if test.err != nil && err == nil { 2563 t.Errorf("Expected error on connect") 2564 } else if test.err != nil && err != nil { 2565 // Error on connect was expected 2566 if test.err.Error() != err.Error() { 2567 t.Errorf("Expected error %s, got: %s", test.err, err) 2568 } 2569 return 2570 } 2571 nc.Close() 2572 time.Sleep(2 * time.Second) 2573 fi, err = statCacheFile("") 2574 if err == nil && fi != nil && fi.Size() > firstFi.Size() { 2575 // good 2576 } else { 2577 if err != nil { 2578 t.Fatalf("Expected an extant local cache file, got error: %v", err) 2579 } 2580 if fi != nil { 2581 t.Fatalf("Expected non-zero size local cache file with more bytes, got a FileInfo with size %d", fi.Size()) 2582 } 2583 } 2584 }) 2585 } 2586 } 2587 2588 func statCacheFile(dir string) (os.FileInfo, error) { 2589 if dir == "" { 2590 dir = "_rc_" 2591 } 2592 return os.Stat(filepath.Join(dir, "cache.json")) 2593 } 2594 2595 // TestOCSPPeerUndelegatedCAResponseSigner 2596 func TestOCSPPeerUndelegatedCAResponseSigner(t *testing.T) { 2597 ctx, cancel := context.WithCancel(context.Background()) 2598 defer cancel() 2599 2600 rootCAResponder := newOCSPResponderRootCA(t) 2601 rootCAResponderURL := fmt.Sprintf("http://%s", rootCAResponder.Addr) 2602 defer rootCAResponder.Shutdown(ctx) 2603 setOCSPStatus(t, rootCAResponderURL, "configs/certs/ocsp_peer/mini-ca/intermediate1/intermediate1_cert.pem", ocsp.Good) 2604 2605 intermediateCA1Responder := newOCSPResponderIntermediateCA1Undelegated(t) 2606 intermediateCA1ResponderURL := fmt.Sprintf("http://%s", intermediateCA1Responder.Addr) 2607 defer intermediateCA1Responder.Shutdown(ctx) 2608 setOCSPStatus(t, intermediateCA1ResponderURL, "configs/certs/ocsp_peer/mini-ca/client1/UserA1_cert.pem", ocsp.Good) 2609 2610 for _, test := range []struct { 2611 name string 2612 config string 2613 opts []nats.Option 2614 err error 2615 rerr error 2616 configure func() 2617 }{ 2618 { 2619 "mTLS OCSP peer check on inbound client connection, responder is CA (undelegated)", 2620 ` 2621 port: -1 2622 # Cache configuration is default 2623 tls: { 2624 cert_file: "configs/certs/ocsp_peer/mini-ca/server1/TestServer1_bundle.pem" 2625 key_file: "configs/certs/ocsp_peer/mini-ca/server1/private/TestServer1_keypair.pem" 2626 ca_file: "configs/certs/ocsp_peer/mini-ca/root/root_cert.pem" 2627 timeout: 5 2628 verify: true 2629 # Turn on CA OCSP check so unvalidated clients can't connect 2630 ocsp_peer: true 2631 } 2632 `, 2633 []nats.Option{ 2634 nats.ClientCert("./configs/certs/ocsp_peer/mini-ca/client1/UserA1_bundle.pem", "./configs/certs/ocsp_peer/mini-ca/client1/private/UserA1_keypair.pem"), 2635 nats.RootCAs("./configs/certs/ocsp_peer/mini-ca/root/root_cert.pem"), 2636 nats.ErrorHandler(noOpErrHandler), 2637 }, 2638 nil, 2639 nil, 2640 func() {}, 2641 }, 2642 } { 2643 t.Run(test.name, func(t *testing.T) { 2644 deleteLocalStore(t, "") 2645 test.configure() 2646 content := test.config 2647 conf := createConfFile(t, []byte(content)) 2648 s, opts := RunServerWithConfig(conf) 2649 defer s.Shutdown() 2650 nc, err := nats.Connect(fmt.Sprintf("tls://localhost:%d", opts.Port), test.opts...) 2651 if test.err == nil && err != nil { 2652 t.Errorf("Expected to connect, got %v", err) 2653 } else if test.err != nil && err == nil { 2654 t.Errorf("Expected error on connect") 2655 } else if test.err != nil && err != nil { 2656 // Error on connect was expected 2657 if test.err.Error() != err.Error() { 2658 t.Errorf("Expected error %s, got: %s", test.err, err) 2659 } 2660 return 2661 } 2662 defer nc.Close() 2663 }) 2664 } 2665 } 2666 2667 // TestOCSPPeerDelegatedCAResponseSigner 2668 func TestOCSPPeerDelegatedCAResponseSigner(t *testing.T) { 2669 ctx, cancel := context.WithCancel(context.Background()) 2670 defer cancel() 2671 2672 rootCAResponder := newOCSPResponderRootCA(t) 2673 rootCAResponderURL := fmt.Sprintf("http://%s", rootCAResponder.Addr) 2674 defer rootCAResponder.Shutdown(ctx) 2675 setOCSPStatus(t, rootCAResponderURL, "configs/certs/ocsp_peer/mini-ca/intermediate1/intermediate1_cert.pem", ocsp.Good) 2676 2677 intermediateCA1Responder := newOCSPResponderIntermediateCA1(t) 2678 intermediateCA1ResponderURL := fmt.Sprintf("http://%s", intermediateCA1Responder.Addr) 2679 defer intermediateCA1Responder.Shutdown(ctx) 2680 setOCSPStatus(t, intermediateCA1ResponderURL, "configs/certs/ocsp_peer/mini-ca/client1/UserA1_cert.pem", ocsp.Good) 2681 2682 for _, test := range []struct { 2683 name string 2684 config string 2685 opts []nats.Option 2686 err error 2687 rerr error 2688 configure func() 2689 }{ 2690 { 2691 "mTLS OCSP peer check on inbound client connection, responder is CA (undelegated)", 2692 ` 2693 port: -1 2694 # Cache configuration is default 2695 tls: { 2696 cert_file: "configs/certs/ocsp_peer/mini-ca/server1/TestServer1_bundle.pem" 2697 key_file: "configs/certs/ocsp_peer/mini-ca/server1/private/TestServer1_keypair.pem" 2698 ca_file: "configs/certs/ocsp_peer/mini-ca/root/root_cert.pem" 2699 timeout: 5 2700 verify: true 2701 # Turn on CA OCSP check so unvalidated clients can't connect 2702 ocsp_peer: true 2703 } 2704 `, 2705 []nats.Option{ 2706 nats.ClientCert("./configs/certs/ocsp_peer/mini-ca/client1/UserA1_bundle.pem", "./configs/certs/ocsp_peer/mini-ca/client1/private/UserA1_keypair.pem"), 2707 nats.RootCAs("./configs/certs/ocsp_peer/mini-ca/root/root_cert.pem"), 2708 nats.ErrorHandler(noOpErrHandler), 2709 }, 2710 nil, 2711 nil, 2712 func() {}, 2713 }, 2714 } { 2715 t.Run(test.name, func(t *testing.T) { 2716 deleteLocalStore(t, "") 2717 test.configure() 2718 content := test.config 2719 conf := createConfFile(t, []byte(content)) 2720 s, opts := RunServerWithConfig(conf) 2721 defer s.Shutdown() 2722 nc, err := nats.Connect(fmt.Sprintf("tls://localhost:%d", opts.Port), test.opts...) 2723 if test.err == nil && err != nil { 2724 t.Errorf("Expected to connect, got %v", err) 2725 } else if test.err != nil && err == nil { 2726 t.Errorf("Expected error on connect") 2727 } else if test.err != nil && err != nil { 2728 // Error on connect was expected 2729 if test.err.Error() != err.Error() { 2730 t.Errorf("Expected error %s, got: %s", test.err, err) 2731 } 2732 return 2733 } 2734 defer nc.Close() 2735 }) 2736 } 2737 } 2738 2739 // TestOCSPPeerBadDelegatedCAResponseSigner 2740 func TestOCSPPeerBadDelegatedCAResponseSigner(t *testing.T) { 2741 ctx, cancel := context.WithCancel(context.Background()) 2742 defer cancel() 2743 2744 rootCAResponder := newOCSPResponderRootCA(t) 2745 rootCAResponderURL := fmt.Sprintf("http://%s", rootCAResponder.Addr) 2746 defer rootCAResponder.Shutdown(ctx) 2747 setOCSPStatus(t, rootCAResponderURL, "configs/certs/ocsp_peer/mini-ca/intermediate1/intermediate1_cert.pem", ocsp.Good) 2748 2749 intermediateCA1Responder := newOCSPResponderBadDelegateIntermediateCA1(t) 2750 intermediateCA1ResponderURL := fmt.Sprintf("http://%s", intermediateCA1Responder.Addr) 2751 defer intermediateCA1Responder.Shutdown(ctx) 2752 setOCSPStatus(t, intermediateCA1ResponderURL, "configs/certs/ocsp_peer/mini-ca/client1/UserA1_cert.pem", ocsp.Good) 2753 2754 for _, test := range []struct { 2755 name string 2756 config string 2757 opts []nats.Option 2758 err error 2759 rerr error 2760 configure func() 2761 }{ 2762 { 2763 "mTLS OCSP peer check on inbound client connection, responder is not a legal delegate", 2764 ` 2765 port: -1 2766 # Cache configuration is default 2767 tls: { 2768 cert_file: "configs/certs/ocsp_peer/mini-ca/server1/TestServer1_bundle.pem" 2769 key_file: "configs/certs/ocsp_peer/mini-ca/server1/private/TestServer1_keypair.pem" 2770 ca_file: "configs/certs/ocsp_peer/mini-ca/root/root_cert.pem" 2771 timeout: 5 2772 verify: true 2773 # Turn on CA OCSP check so unvalidated clients can't connect 2774 ocsp_peer: true 2775 } 2776 `, 2777 []nats.Option{ 2778 nats.ClientCert("./configs/certs/ocsp_peer/mini-ca/client1/UserA1_bundle.pem", "./configs/certs/ocsp_peer/mini-ca/client1/private/UserA1_keypair.pem"), 2779 nats.RootCAs("./configs/certs/ocsp_peer/mini-ca/root/root_cert.pem"), 2780 nats.ErrorHandler(noOpErrHandler), 2781 }, 2782 errors.New("remote error: tls: bad certificate"), 2783 errors.New("expect error"), 2784 func() {}, 2785 }, 2786 } { 2787 t.Run(test.name, func(t *testing.T) { 2788 deleteLocalStore(t, "") 2789 test.configure() 2790 content := test.config 2791 conf := createConfFile(t, []byte(content)) 2792 s, opts := RunServerWithConfig(conf) 2793 defer s.Shutdown() 2794 nc, err := nats.Connect(fmt.Sprintf("tls://localhost:%d", opts.Port), test.opts...) 2795 if test.err == nil && err != nil { 2796 t.Errorf("Expected to connect, got %v", err) 2797 } else if test.err != nil && err == nil { 2798 t.Errorf("Expected error on connect") 2799 } else if test.err != nil && err != nil { 2800 // Error on connect was expected 2801 if test.err.Error() != err.Error() { 2802 t.Errorf("Expected error %s, got: %s", test.err, err) 2803 } 2804 return 2805 } 2806 defer nc.Close() 2807 }) 2808 } 2809 } 2810 2811 // TestOCSPPeerNextUpdateUnset is test of scenario when responder does not set NextUpdate and cache TTL option is used 2812 func TestOCSPPeerNextUpdateUnset(t *testing.T) { 2813 ctx, cancel := context.WithCancel(context.Background()) 2814 defer cancel() 2815 2816 rootCAResponder := newOCSPResponderRootCA(t) 2817 rootCAResponderURL := fmt.Sprintf("http://%s", rootCAResponder.Addr) 2818 defer rootCAResponder.Shutdown(ctx) 2819 setOCSPStatus(t, rootCAResponderURL, "configs/certs/ocsp_peer/mini-ca/intermediate1/intermediate1_cert.pem", ocsp.Good) 2820 2821 respCertPEM := "configs/certs/ocsp_peer/mini-ca/ocsp1/ocsp1_bundle.pem" 2822 respKeyPEM := "configs/certs/ocsp_peer/mini-ca/ocsp1/private/ocsp1_keypair.pem" 2823 issuerCertPEM := "configs/certs/ocsp_peer/mini-ca/intermediate1/intermediate1_cert.pem" 2824 intermediateCA1Responder := newOCSPResponderBase(t, issuerCertPEM, respCertPEM, respKeyPEM, true, "127.0.0.1:18888", 0, "") 2825 intermediateCA1ResponderURL := fmt.Sprintf("http://%s", intermediateCA1Responder.Addr) 2826 defer intermediateCA1Responder.Shutdown(ctx) 2827 setOCSPStatus(t, intermediateCA1ResponderURL, "configs/certs/ocsp_peer/mini-ca/client1/UserA1_cert.pem", ocsp.Good) 2828 2829 for _, test := range []struct { 2830 name string 2831 config string 2832 opts []nats.Option 2833 err error 2834 rerr error 2835 expectedMisses int64 2836 configure func() 2837 }{ 2838 { 2839 "TTL set to 4 seconds with second client connection leveraging cache from first client connect", 2840 ` 2841 port: -1 2842 http_port: 8222 2843 tls: { 2844 cert_file: "configs/certs/ocsp_peer/mini-ca/server1/TestServer1_bundle.pem" 2845 key_file: "configs/certs/ocsp_peer/mini-ca/server1/private/TestServer1_keypair.pem" 2846 ca_file: "configs/certs/ocsp_peer/mini-ca/root/root_cert.pem" 2847 timeout: 5 2848 verify: true 2849 # Long form configuration 2850 ocsp_peer: { 2851 verify: true 2852 ca_timeout: 5 2853 allowed_clockskew: 0 2854 cache_ttl_when_next_update_unset: 4 2855 } 2856 } 2857 # Short form configuration, local as default 2858 ocsp_cache: true 2859 `, 2860 []nats.Option{ 2861 nats.ClientCert("./configs/certs/ocsp_peer/mini-ca/client1/UserA1_bundle.pem", "./configs/certs/ocsp_peer/mini-ca/client1/private/UserA1_keypair.pem"), 2862 nats.RootCAs("./configs/certs/ocsp_peer/mini-ca/root/root_cert.pem"), 2863 nats.ErrorHandler(noOpErrHandler), 2864 }, 2865 nil, 2866 nil, 2867 2, 2868 func() {}, 2869 }, 2870 { 2871 "TTL set to 1 seconds with second client connection not leveraging cache items from first client connect", 2872 ` 2873 port: -1 2874 http_port: 8222 2875 tls: { 2876 cert_file: "configs/certs/ocsp_peer/mini-ca/server1/TestServer1_bundle.pem" 2877 key_file: "configs/certs/ocsp_peer/mini-ca/server1/private/TestServer1_keypair.pem" 2878 ca_file: "configs/certs/ocsp_peer/mini-ca/root/root_cert.pem" 2879 timeout: 5 2880 verify: true 2881 # Long form configuration 2882 ocsp_peer: { 2883 verify: true 2884 ca_timeout: 5 2885 allowed_clockskew: 0 2886 cache_ttl_when_next_update_unset: 1 2887 } 2888 } 2889 # Short form configuration, local as default 2890 ocsp_cache: true 2891 `, 2892 []nats.Option{ 2893 nats.ClientCert("./configs/certs/ocsp_peer/mini-ca/client1/UserA1_bundle.pem", "./configs/certs/ocsp_peer/mini-ca/client1/private/UserA1_keypair.pem"), 2894 nats.RootCAs("./configs/certs/ocsp_peer/mini-ca/root/root_cert.pem"), 2895 nats.ErrorHandler(noOpErrHandler), 2896 }, 2897 nil, 2898 nil, 2899 3, 2900 func() {}, 2901 }, 2902 } { 2903 t.Run(test.name, func(t *testing.T) { 2904 // Cleanup any previous test that saved a local cache 2905 deleteLocalStore(t, "") 2906 test.configure() 2907 content := test.config 2908 conf := createConfFile(t, []byte(content)) 2909 s, opts := RunServerWithConfig(conf) 2910 defer s.Shutdown() 2911 nc, err := nats.Connect(fmt.Sprintf("tls://localhost:%d", opts.Port), test.opts...) 2912 if test.err == nil && err != nil { 2913 t.Errorf("Expected to connect, got %v", err) 2914 } else if test.err != nil && err == nil { 2915 t.Errorf("Expected error on connect") 2916 } else if test.err != nil && err != nil { 2917 // Error on connect was expected 2918 if test.err.Error() != err.Error() { 2919 t.Errorf("Expected error %s, got: %s", test.err, err) 2920 } 2921 return 2922 } 2923 nc.Close() 2924 2925 // Wait interval shorter than first test, and longer than second test 2926 time.Sleep(2 * time.Second) 2927 2928 nc, err = nats.Connect(fmt.Sprintf("tls://localhost:%d", opts.Port), test.opts...) 2929 if test.err == nil && err != nil { 2930 t.Errorf("Expected to connect, got %v", err) 2931 } else if test.err != nil && err == nil { 2932 t.Errorf("Expected error on connect") 2933 } else if test.err != nil && err != nil { 2934 // Error on connect was expected 2935 if test.err.Error() != err.Error() { 2936 t.Errorf("Expected error %s, got: %s", test.err, err) 2937 } 2938 return 2939 } 2940 defer nc.Close() 2941 2942 v := monitorGetVarzHelper(t, 8222) 2943 if v.OCSPResponseCache == nil { 2944 t.Fatalf("Expected OCSP statistics to be in varz") 2945 } 2946 if v.OCSPResponseCache.Misses != test.expectedMisses || v.OCSPResponseCache.Responses != 2 { 2947 t.Errorf("Expected cache misses to be %d and cache items to be 2, got %d and %d", test.expectedMisses, v.OCSPResponseCache.Misses, v.OCSPResponseCache.Responses) 2948 } 2949 }) 2950 } 2951 }