diff --git a/async-nats/tests/jetstream_tests.rs b/async-nats/tests/jetstream_tests.rs index 2d22918d9..72ad153c4 100644 --- a/async-nats/tests/jetstream_tests.rs +++ b/async-nats/tests/jetstream_tests.rs @@ -1154,7 +1154,6 @@ mod jetstream { .unwrap(); } - #[ignore] #[tokio::test] async fn pull_sequence() { let server = nats_server::run_server("tests/configs/jetstream.conf"); diff --git a/nats/Cargo.toml b/nats/Cargo.toml index 10d4670f5..2ef35c1e0 100644 --- a/nats/Cargo.toml +++ b/nats/Cargo.toml @@ -46,10 +46,10 @@ nuid = "0.3.1" once_cell = "1.8.0" parking_lot = "0.12.0" regex = { version = "1.5.5", default-features = false, features = ["std", "unicode-perl"] } -rustls = "0.19.1" -rustls-native-certs = "0.5.0" -rustls-pemfile = "0.2.1" -webpki = "0.21.0" +rustls = "0.21" +rustls-native-certs = "0.6" +rustls-pemfile = "1.0.2" +webpki = { package = "rustls-webpki", version = "0.100.0", features = ["alloc", "std"] } serde = { version = "1.0.126", features = ["derive"] } serde_json = "1.0.64" serde_nanos = "0.1.1" diff --git a/nats/src/auth_utils.rs b/nats/src/auth_utils.rs index fba180d13..7b96f5545 100644 --- a/nats/src/auth_utils.rs +++ b/nats/src/auth_utils.rs @@ -123,7 +123,7 @@ pub(crate) fn load_key(path: &Path) -> io::Result { return Ok(PrivateKey(key)) } // if public key is found, don't error, just skip it and hope to find client key next. - Some(rustls_pemfile::Item::X509Certificate(_)) => {} + Some(rustls_pemfile::Item::X509Certificate(_)) | Some(_) => {} None => break, } } diff --git a/nats/src/connector.rs b/nats/src/connector.rs index 8f6d018ec..f192caddf 100644 --- a/nats/src/connector.rs +++ b/nats/src/connector.rs @@ -14,6 +14,7 @@ use lazy_static::__Deref; use parking_lot::{Mutex, MutexGuard}; use std::collections::HashMap; +use std::convert::TryFrom; use std::io::prelude::*; use std::io::{self, BufReader, Error, ErrorKind}; use std::net::{Shutdown, SocketAddr, TcpStream, ToSocketAddrs}; @@ -23,11 +24,9 @@ use std::thread; use std::time::Duration; use url::{Host, Url}; -use webpki::DNSNameRef; - use crate::auth_utils; use crate::proto::{self, ClientOp, ServerOp}; -use crate::rustls::{ClientConfig, ClientSession, Session}; +use crate::rustls::{ClientConfig, ClientConnection}; use crate::secure_wipe::SecureString; use crate::{connect::ConnectInfo, inject_io_failure, AuthStyle, Options, ServerInfo}; @@ -47,53 +46,80 @@ pub(crate) struct Connector { tls_config: Arc, } -impl Connector { - /// Creates a new connector with the URLs and options. - pub(crate) fn new(urls: Vec, options: Arc) -> io::Result { - let mut tls_config = options.tls_client_config.clone(); - - // Include system root certificates. - // - // On Windows, some certificates cannot be loaded by rustls - // for whatever reason, so we simply skip them. - // See https://github.com/ctz/rustls-native-certs/issues/5 - let roots = match rustls_native_certs::load_native_certs() { - Ok(store) | Err((Some(store), _)) => store.roots, - Err((None, _)) => Vec::new(), - }; - for root in roots { - tls_config.root_store.roots.push(root); - } +fn configure_tls(options: &Arc) -> Result { + let mut root_store = rustls::RootCertStore::empty(); + + // load native system certs only if user did not specify them + if options.tls_client_config.is_some() || options.certificates.is_empty() { + let native_certs = rustls_native_certs::load_native_certs() + .map_err(|err| { + io::Error::new( + ErrorKind::Other, + format!("could not load platform certs: {err}"), + ) + })? + .into_iter() + .map(|cert| cert.0) + .collect::>>(); - // Include user-provided certificates. + root_store.add_parsable_certificates(&native_certs); + } + + if let Some(config) = &options.tls_client_config { + Ok(config.to_owned()) + } else { + // Include user-provided certificates for path in &options.certificates { - let contents = std::fs::read(path)?; - let mut cursor = std::io::Cursor::new(contents); - - tls_config - .root_store - .add_pem_file(&mut cursor) - .map_err(|_| { - io::Error::new(io::ErrorKind::InvalidInput, "invalid certificate file") - })?; + let mut pem = BufReader::new(std::fs::File::open(path)?); + let certs = rustls_pemfile::certs(&mut pem)?; + let trust_anchors = certs.iter().map(|cert| { + let trust_anchor = webpki::TrustAnchor::try_from_cert_der(&cert[..]) + .map_err(|err| { + io::Error::new( + ErrorKind::InvalidInput, + format!("could not load certs: {err}"), + ) + }) + .unwrap(); + rustls::OwnedTrustAnchor::from_subject_spki_name_constraints( + trust_anchor.subject, + trust_anchor.spki, + trust_anchor.name_constraints, + ) + }); + root_store.add_server_trust_anchors(trust_anchors); } + let builder = rustls::ClientConfig::builder() + .with_safe_defaults() + .with_root_certificates(root_store); + if let Some(cert) = &options.client_cert { if let Some(key) = &options.client_key { - tls_config - .set_single_client_cert( - auth_utils::load_certs(cert)?, - auth_utils::load_key(key)?, - ) - .map_err(|err| { - io::Error::new( - io::ErrorKind::InvalidInput, - format!("invalid client certificate and key pair: {err}"), - ) - })?; + let cert = auth_utils::load_certs(cert)?; + let key = auth_utils::load_key(key)?; + + return builder.with_single_cert(cert, key).map_err(|_| { + io::Error::new(ErrorKind::Other, "could not add certificate or key") + }); + } else { + return Err(io::Error::new( + ErrorKind::Other, + "found certificate, but no key", + )); } } + // if there are no client certs provided, connect with just TLS. + Ok(builder.with_no_client_auth()) + } +} + +impl Connector { + /// Creates a new connector with the URLs and options. + pub(crate) fn new(urls: Vec, options: Arc) -> io::Result { + let tls_config = configure_tls(&options)?; + let connector = Connector { attempts: urls.into_iter().map(|url| (url, 0)).collect(), options, @@ -252,15 +278,18 @@ impl Connector { inject_io_failure()?; // Connect using TLS. - let dns_name = DNSNameRef::try_from_ascii_str(&server_info.host) - .or_else(|_| DNSNameRef::try_from_ascii_str(server.host())) - .map_err(|_| { + let server_name = + rustls::client::ServerName::try_from(server.host()).map_err(|_| { io::Error::new( io::ErrorKind::InvalidInput, "cannot determine hostname for TLS connection", ) })?; - Some(ClientSession::new(&self.tls_config, dns_name)) + + Some( + ClientConnection::new(self.tls_config.clone(), server_name) + .map_err(|err| io::Error::new(io::ErrorKind::InvalidInput, err))?, + ) } else { None }; @@ -374,12 +403,12 @@ enum Flavor { struct TlsStream { tcp: TcpStream, - session: ClientSession, + session: ClientConnection, } impl NatsStream { /// Creates a NATS stream from a TCP stream and an optional TLS session. - fn new(tcp: TcpStream, session: Option) -> io::Result { + fn new(tcp: TcpStream, session: Option) -> io::Result { let flavor = match session { None => Flavor::Tcp(tcp), Some(session) => { @@ -418,7 +447,7 @@ impl Read for &NatsStream { fn read(&mut self, buf: &mut [u8]) -> io::Result { match &*self.flavor { Flavor::Tcp(tcp) => (tcp.deref()).read(buf), - Flavor::Tls(tls) => tls_op(tls, |session, eof| match session.read(buf) { + Flavor::Tls(tls) => tls_op(tls, |session, eof| match session.reader().read(buf) { Ok(0) if !eof => Err(io::ErrorKind::WouldBlock.into()), res => res, }), @@ -440,14 +469,14 @@ impl Write for &NatsStream { fn write(&mut self, buf: &[u8]) -> io::Result { match &*self.flavor { Flavor::Tcp(tcp) => (tcp.deref()).write(buf), - Flavor::Tls(tls) => tls_op(tls, |session, _| session.write(buf)), + Flavor::Tls(tls) => tls_op(tls, |session, _| session.writer().write(buf)), } } fn flush(&mut self) -> io::Result<()> { match &*self.flavor { Flavor::Tcp(tcp) => (tcp.deref()).flush(), - Flavor::Tls(tls) => tls_op(tls, |session, _| session.flush()), + Flavor::Tls(tls) => tls_op(tls, |session, _| session.writer().flush()), } } } @@ -457,7 +486,7 @@ impl Write for &NatsStream { /// However, note that the inner TCP stream is in non-blocking mode. fn tls_op( tls: &Mutex, - mut op: impl FnMut(&mut ClientSession, bool) -> io::Result, + mut op: impl FnMut(&mut ClientConnection, bool) -> io::Result, ) -> io::Result { loop { let mut tls = tls.lock(); @@ -468,9 +497,11 @@ fn tls_op( if session.wants_read() { match session.read_tls(tcp) { Ok(0) => eof = true, - Ok(_) => session - .process_new_packets() - .map_err(|err| Error::new(ErrorKind::Other, format!("TLS error: {err}")))?, + Ok(_) => { + session + .process_new_packets() + .map_err(|err| Error::new(ErrorKind::Other, format!("TLS error: {err}")))?; + } Err(err) if err.kind() == ErrorKind::WouldBlock => {} Err(err) => return Err(err), } diff --git a/nats/src/options.rs b/nats/src/options.rs index fc48e805b..7527c0c4b 100644 --- a/nats/src/options.rs +++ b/nats/src/options.rs @@ -38,7 +38,7 @@ pub struct Options { pub(crate) certificates: Vec, pub(crate) client_cert: Option, pub(crate) client_key: Option, - pub(crate) tls_client_config: crate::rustls::ClientConfig, + pub(crate) tls_client_config: Option, pub(crate) error_callback: ErrorCallback, pub(crate) disconnect_callback: Callback, @@ -91,7 +91,7 @@ impl Default for Options { reconnect_delay_callback: ReconnectDelayCallback(Box::new(backoff)), close_callback: Callback(None), lame_duck_callback: Callback(None), - tls_client_config: crate::rustls::ClientConfig::default(), + tls_client_config: None, } } } @@ -342,19 +342,30 @@ impl Options { /// # Example /// ```no_run /// # fn main() -> std::io::Result<()> { - /// let mut tls_client_config = nats::rustls::ClientConfig::default(); - /// tls_client_config.set_single_client_cert( - /// vec![nats::rustls::Certificate(b"MY_CERT".to_vec())], - /// nats::rustls::PrivateKey(b"MY_KEY".to_vec()), + /// let mut root_store = nats::rustls::RootCertStore::empty(); + /// + /// root_store.add_parsable_certificates( + /// rustls_native_certs::load_native_certs()? + /// .into_iter() + /// .map(|cert| cert.0) + /// .collect::>>() + /// .as_ref(), /// ); + /// + /// let tls_client_config = nats::rustls::ClientConfig::builder() + /// .with_safe_defaults() + /// .with_root_certificates(root_store) + /// .with_no_client_auth(); + /// /// let nc = nats::Options::new() /// .tls_client_config(tls_client_config) /// .connect("nats://localhost:4443")?; + /// /// # Ok(()) /// # } /// ``` pub fn tls_client_config(mut self, tls_client_config: crate::rustls::ClientConfig) -> Options { - self.tls_client_config = tls_client_config; + self.tls_client_config = Some(tls_client_config); self } diff --git a/nats/tests/auth_tls.rs b/nats/tests/auth_tls.rs index 881192c16..2ba8c2ddf 100644 --- a/nats/tests/auth_tls.rs +++ b/nats/tests/auth_tls.rs @@ -11,23 +11,28 @@ // See the License for the specific language governing permissions and // limitations under the License. -use std::io; use std::path::PathBuf; #[test] -fn basic_tls() -> io::Result<()> { +fn basic_tls() { let server = nats_server::run_server("tests/configs/tls.conf"); + + // Should fail without certs. assert!(nats::connect(server.client_url()).is_err()); let path = PathBuf::from(env!("CARGO_MANIFEST_DIR")); + // Should fail with IP (cert doesn't have proper SAN entry) + assert!(nats::connect(format!("tls://127.0.0.1:{}", server.client_port())).is_err()); + nats::Options::with_user_pass("derek", "porkchop") .add_root_certificate(path.join("tests/configs/certs/rootCA.pem")) .client_cert( path.join("tests/configs/certs/client-cert.pem"), path.join("tests/configs/certs/client-key.pem"), ) - .connect(server.client_url())?; + .connect(server.client_url()) + .unwrap(); // test scenario where rootCA, client certificate and client key are all in one .pem file nats::Options::with_user_pass("derek", "porkchop") @@ -36,7 +41,19 @@ fn basic_tls() -> io::Result<()> { path.join("tests/configs/certs/client-all.pem"), path.join("tests/configs/certs/client-all.pem"), ) - .connect(server.client_url())?; + .connect(server.client_url()) + .unwrap(); +} + +#[test] +fn ip_basic_tls() { + let server = nats_server::run_server("tests/configs/ip-tls.conf"); + + let path = PathBuf::from(env!("CARGO_MANIFEST_DIR")); - Ok(()) + nats::Options::with_user_pass("derek", "porkchop") + .add_root_certificate(path.join("tests/configs/certs/ip-ca.pem")) + .tls_required(true) + .connect(format!("tls://127.0.0.1:{}", server.client_port())) + .unwrap(); } diff --git a/nats/tests/configs/certs/ip-ca.pem b/nats/tests/configs/certs/ip-ca.pem new file mode 100644 index 000000000..911c486c1 --- /dev/null +++ b/nats/tests/configs/certs/ip-ca.pem @@ -0,0 +1,27 @@ +-----BEGIN CERTIFICATE----- +MIIEkDCCA3igAwIBAgIUSZwW7btc9EUbrMWtjHpbM0C2bSEwDQYJKoZIhvcNAQEL +BQAwcTELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExEDAOBgNVBAoM +B1N5bmFkaWExEDAOBgNVBAsMB25hdHMuaW8xKTAnBgNVBAMMIENlcnRpZmljYXRl +IEF1dGhvcml0eSAyMDIyLTA4LTI3MB4XDTIyMDgyNzIwMjMwMloXDTMyMDgyNDIw +MjMwMlowcTELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExEDAOBgNV +BAoMB1N5bmFkaWExEDAOBgNVBAsMB25hdHMuaW8xKTAnBgNVBAMMIENlcnRpZmlj +YXRlIEF1dGhvcml0eSAyMDIyLTA4LTI3MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEAqilVqyY8rmCpTwAsLF7DEtWEq37KbljBWVjmlp2Wo6TgMd3b537t +6iO8+SbI8KH75i63RcxV3Uzt1/L9Yb6enDXF52A/U5ugmDhaa+Vsoo2HBTbCczmp +qndp7znllQqn7wNLv6aGSvaeIUeYS5Dmlh3kt7Vqbn4YRANkOUTDYGSpMv7jYKSu +1ee05Rco3H674zdwToYto8L8V7nVMrky42qZnGrJTaze+Cm9tmaIyHCwUq362CxS +dkmaEuWx11MOIFZvL80n7ci6pveDxe5MIfwMC3/oGn7mbsSqidPMcTtjw6ey5NEu +Z0UrC/2lL1FtF4gnVMKUSaEhU2oKjj0ZAQIDAQABo4IBHjCCARowHQYDVR0OBBYE +FP7Pfz4u7sSt6ltviEVsx4hIFIs6MIGuBgNVHSMEgaYwgaOAFP7Pfz4u7sSt6ltv +iEVsx4hIFIs6oXWkczBxMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5p +YTEQMA4GA1UECgwHU3luYWRpYTEQMA4GA1UECwwHbmF0cy5pbzEpMCcGA1UEAwwg +Q2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMjItMDgtMjeCFEmcFu27XPRFG6zFrYx6 +WzNAtm0hMAwGA1UdEwQFMAMBAf8wOgYJYIZIAYb4QgENBC0WK25hdHMuaW8gbmF0 +cy1zZXJ2ZXIgdGVzdC1zdWl0ZSB0cmFuc2llbnQgQ0EwDQYJKoZIhvcNAQELBQAD +ggEBAHDCHLQklYZlnzHDaSwxgGSiPUrCf2zhk2DNIYSDyBgdzrIapmaVYQRrCBtA +j/4jVFesgw5WDoe4TKsyha0QeVwJDIN8qg2pvpbmD8nOtLApfl0P966vcucxDwqO +dQWrIgNsaUdHdwdo0OfvAlTfG0v/y2X0kbL7h/el5W9kWpxM/rfbX4IHseZL2sLq +FH69SN3FhMbdIm1ldrcLBQVz8vJAGI+6B9hSSFQWljssE0JfAX+8VW/foJgMSx7A +vBTq58rLkAko56Jlzqh/4QT+ckayg9I73v1Q5/44jP1mHw35s5ZrzpDQt2sVv4l5 +lwRPJFXMwe64flUs9sM+/vqJaIY= +-----END CERTIFICATE----- diff --git a/nats/tests/configs/certs/ip-cert.pem b/nats/tests/configs/certs/ip-cert.pem new file mode 100644 index 000000000..80a9d8fe0 --- /dev/null +++ b/nats/tests/configs/certs/ip-cert.pem @@ -0,0 +1,99 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 1d:d9:1f:06:dd:fd:90:26:4e:27:ea:2e:01:4b:31:e6:d2:49:31:1f + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=US, ST=California, O=Synadia, OU=nats.io, CN=Certificate Authority 2022-08-27 + Validity + Not Before: Aug 27 20:23:02 2022 GMT + Not After : Aug 24 20:23:02 2032 GMT + Subject: C=US, ST=California, O=Synadia, OU=nats.io, CN=localhost + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + RSA Public-Key: (2048 bit) + Modulus: + 00:e6:fb:47:65:cd:c9:a2:2d:af:8b:cd:d5:6a:79: + 54:3c:07:5f:eb:5a:71:2b:2b:e5:6f:be:31:fb:16: + 65:68:76:0e:59:e7:e4:57:ca:88:e9:77:d6:41:ad: + 57:7a:42:b2:d2:54:c4:0f:7c:5b:c1:bc:61:97:e3: + 22:3a:3e:1e:4a:5d:47:9f:6b:7d:6f:34:e3:8c:86: + 9d:85:19:29:9a:11:58:44:4c:a1:90:d3:14:61:e1: + 57:da:01:ea:ce:3f:90:ae:9e:5d:13:6d:2c:89:ca: + 39:15:6b:b6:9e:32:d7:2a:4c:48:85:2f:b0:1e:d8: + 4b:62:32:14:eb:32:b6:29:04:34:3c:af:39:b6:8b: + 52:32:4d:bf:43:5f:9b:fb:0d:43:a6:ad:2c:a7:41: + 29:55:c9:70:b3:b5:15:46:34:bf:e4:1e:52:2d:a4: + 49:2e:d5:21:ed:fc:00:f7:a2:0b:bc:12:0a:90:64: + 50:7c:c5:14:70:f5:fb:9b:62:08:78:43:49:31:f3: + 47:b8:93:d4:2d:4c:a9:dc:17:70:76:34:66:ff:65: + c1:39:67:e9:a6:1c:80:6a:f0:9d:b3:28:c8:a3:3a: + b7:5d:de:6e:53:6d:09:b3:0d:b1:13:10:e8:ec:e0: + bd:5e:a1:94:4b:70:bf:dc:bd:8b:b9:82:65:dd:af: + 81:7b + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: + CA:FALSE + Netscape Comment: + nats.io nats-server test-suite certificate + X509v3 Subject Key Identifier: + 2B:8C:A3:8B:DB:DB:5C:CE:18:DB:F6:A8:31:4E:C2:3E:EE:D3:40:7E + X509v3 Authority Key Identifier: + keyid:FE:CF:7F:3E:2E:EE:C4:AD:EA:5B:6F:88:45:6C:C7:88:48:14:8B:3A + DirName:/C=US/ST=California/O=Synadia/OU=nats.io/CN=Certificate Authority 2022-08-27 + serial:49:9C:16:ED:BB:5C:F4:45:1B:AC:C5:AD:8C:7A:5B:33:40:B6:6D:21 + + X509v3 Subject Alternative Name: + DNS:localhost, IP Address:127.0.0.1, IP Address:0:0:0:0:0:0:0:1 + Netscape Cert Type: + SSL Client, SSL Server + X509v3 Key Usage: + Digital Signature, Key Encipherment + X509v3 Extended Key Usage: + TLS Web Server Authentication, Netscape Server Gated Crypto, Microsoft Server Gated Crypto, TLS Web Client Authentication + Signature Algorithm: sha256WithRSAEncryption + 54:49:34:2b:38:d1:aa:3b:43:60:4c:3f:6a:f8:74:ca:49:53: + a1:af:12:d3:a8:17:90:7b:9d:a3:69:13:6e:da:2c:b7:61:31: + ac:eb:00:93:92:fc:0c:10:d4:18:a0:16:61:94:4b:42:cb:eb: + 7a:f6:80:c6:45:c0:9c:09:aa:a9:48:e8:36:e3:c5:be:36:e0: + e9:78:2a:bb:ab:64:9b:20:eb:e6:0f:63:2b:59:c3:58:0b:3a: + 84:15:04:c1:7e:12:03:1b:09:25:8d:4c:03:e8:18:26:c0:6c: + b7:90:b1:fd:bc:f1:cf:d0:d5:4a:03:15:71:0c:7d:c1:76:87: + 92:f1:3e:bc:75:51:5a:c4:36:a4:ff:91:98:df:33:5d:a7:38: + de:50:29:fd:0f:c8:55:e6:8f:24:c2:2e:98:ab:d9:5d:65:2f: + 50:cc:25:f6:84:f2:21:2e:5e:76:d0:86:1e:69:8b:cb:8a:3a: + 2d:79:21:5e:e7:f7:2d:06:18:a1:13:cb:01:c3:46:91:2a:de: + b4:82:d7:c3:62:6f:08:a1:d5:90:19:30:9d:64:8e:e4:f8:ba: + 4f:2f:ba:13:b4:a3:9f:d1:d5:77:64:8a:3e:eb:53:c5:47:ac: + ab:3e:0e:7a:9b:a6:f4:48:25:66:eb:c7:4c:f9:50:24:eb:71: + e0:75:ae:e6 +-----BEGIN CERTIFICATE----- +MIIE+TCCA+GgAwIBAgIUHdkfBt39kCZOJ+ouAUsx5tJJMR8wDQYJKoZIhvcNAQEL +BQAwcTELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExEDAOBgNVBAoM +B1N5bmFkaWExEDAOBgNVBAsMB25hdHMuaW8xKTAnBgNVBAMMIENlcnRpZmljYXRl +IEF1dGhvcml0eSAyMDIyLTA4LTI3MB4XDTIyMDgyNzIwMjMwMloXDTMyMDgyNDIw +MjMwMlowWjELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExEDAOBgNV +BAoMB1N5bmFkaWExEDAOBgNVBAsMB25hdHMuaW8xEjAQBgNVBAMMCWxvY2FsaG9z +dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOb7R2XNyaItr4vN1Wp5 +VDwHX+tacSsr5W++MfsWZWh2Dlnn5FfKiOl31kGtV3pCstJUxA98W8G8YZfjIjo+ +HkpdR59rfW8044yGnYUZKZoRWERMoZDTFGHhV9oB6s4/kK6eXRNtLInKORVrtp4y +1ypMSIUvsB7YS2IyFOsytikENDyvObaLUjJNv0Nfm/sNQ6atLKdBKVXJcLO1FUY0 +v+QeUi2kSS7VIe38APeiC7wSCpBkUHzFFHD1+5tiCHhDSTHzR7iT1C1MqdwXcHY0 +Zv9lwTln6aYcgGrwnbMoyKM6t13eblNtCbMNsRMQ6OzgvV6hlEtwv9y9i7mCZd2v +gXsCAwEAAaOCAZ4wggGaMAkGA1UdEwQCMAAwOQYJYIZIAYb4QgENBCwWKm5hdHMu +aW8gbmF0cy1zZXJ2ZXIgdGVzdC1zdWl0ZSBjZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQU +K4yji9vbXM4Y2/aoMU7CPu7TQH4wga4GA1UdIwSBpjCBo4AU/s9/Pi7uxK3qW2+I +RWzHiEgUizqhdaRzMHExCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlh +MRAwDgYDVQQKDAdTeW5hZGlhMRAwDgYDVQQLDAduYXRzLmlvMSkwJwYDVQQDDCBD +ZXJ0aWZpY2F0ZSBBdXRob3JpdHkgMjAyMi0wOC0yN4IUSZwW7btc9EUbrMWtjHpb +M0C2bSEwLAYDVR0RBCUwI4IJbG9jYWxob3N0hwR/AAABhxAAAAAAAAAAAAAAAAAA +AAABMBEGCWCGSAGG+EIBAQQEAwIGwDALBgNVHQ8EBAMCBaAwNAYDVR0lBC0wKwYI +KwYBBQUHAwEGCWCGSAGG+EIEAQYKKwYBBAGCNwoDAwYIKwYBBQUHAwIwDQYJKoZI +hvcNAQELBQADggEBAFRJNCs40ao7Q2BMP2r4dMpJU6GvEtOoF5B7naNpE27aLLdh +MazrAJOS/AwQ1BigFmGUS0LL63r2gMZFwJwJqqlI6Dbjxb424Ol4KrurZJsg6+YP +YytZw1gLOoQVBMF+EgMbCSWNTAPoGCbAbLeQsf288c/Q1UoDFXEMfcF2h5LxPrx1 +UVrENqT/kZjfM12nON5QKf0PyFXmjyTCLpir2V1lL1DMJfaE8iEuXnbQhh5pi8uK +Oi15IV7n9y0GGKETywHDRpEq3rSC18Nibwih1ZAZMJ1kjuT4uk8vuhO0o5/R1Xdk +ij7rU8VHrKs+DnqbpvRIJWbrx0z5UCTrceB1ruY= +-----END CERTIFICATE----- diff --git a/nats/tests/configs/certs/ip-key.pem b/nats/tests/configs/certs/ip-key.pem new file mode 100644 index 000000000..f2c2c6c2f --- /dev/null +++ b/nats/tests/configs/certs/ip-key.pem @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEuwIBADANBgkqhkiG9w0BAQEFAASCBKUwggShAgEAAoIBAQDm+0dlzcmiLa+L +zdVqeVQ8B1/rWnErK+VvvjH7FmVodg5Z5+RXyojpd9ZBrVd6QrLSVMQPfFvBvGGX +4yI6Ph5KXUefa31vNOOMhp2FGSmaEVhETKGQ0xRh4VfaAerOP5Cunl0TbSyJyjkV +a7aeMtcqTEiFL7Ae2EtiMhTrMrYpBDQ8rzm2i1IyTb9DX5v7DUOmrSynQSlVyXCz +tRVGNL/kHlItpEku1SHt/AD3ogu8EgqQZFB8xRRw9fubYgh4Q0kx80e4k9QtTKnc +F3B2NGb/ZcE5Z+mmHIBq8J2zKMijOrdd3m5TbQmzDbETEOjs4L1eoZRLcL/cvYu5 +gmXdr4F7AgMBAAECggEBAK4sr3MiEbjcsHJAvXyzjwRRH1Bu+8VtLW7swe2vvrpd +w4aiKXrV/BXpSsRtvPgxkXyvdMSkpuBZeFI7cVTwAJFc86RQPt77x9bwr5ltFwTZ +rXCbRH3b3ZPNhByds3zhS+2Q92itu5cPyanQdn2mor9/lHPyOOGZgobCcynELL6R +wRElkeDyf5ODuWEd7ADC5IFyZuwb3azNVexIK+0yqnMmv+QzEW3hsycFmFGAeB7v +MIMjb2BhLrRr6Y5Nh+k58yM5DCf9h/OJhDpeXwLkxyK4BFg+aZffEbUX0wHDMR7f +/nMv1g6cKvDWiLU8xLzez4t2qNIBNdxw5ZSLyQRRolECgYEA+ySTKrBAqI0Uwn8H +sUFH95WhWUXryeRyGyQsnWAjZGF1+d67sSY2un2W6gfZrxRgiNLWEFq9AaUs0MuH +6syF4Xwx/aZgU/gvsGtkgzuKw1bgvekT9pS/+opmHRCZyQAFEHj0IEpzyB6rW1u/ +LdlR3ShEENnmXilFv/uF/uXP5tMCgYEA63LiT0w46aGPA/E+aLRWU10c1eZ7KdhR +c3En6zfgIxgFs8J38oLdkOR0CF6T53DSuvGR/OprVKdlnUhhDxBgT1oQjK2GlhPx +JV5uMvarJDJxAwsF+7T4H2QtZ00BtEfpyp790+TlypSG1jo/BnSMmX2uEbV722lY +hzINLY49obkCgYBEpN2YyG4T4+PtuXznxRkfogVk+kiVeVx68KtFJLbnw//UGT4i +EHjbBmLOevDT+vTb0QzzkWmh3nzeYRM4aUiatjCPzP79VJPsW54whIDMHZ32KpPr +TQMgPt3kSdpO5zN7KiRIAzGcXE2n/e7GYGUQ1uWr2XMu/4byD5SzdCscQwJ/Ymii +LoKtRvk/zWYHr7uwWSeR5dVvpQ3E/XtONAImrIRd3cRqXfJUqTrTRKxDJXkCmyBc +5FkWg0t0LUkTSDiQCJqcUDA3EINFR1kwthxja72pfpwc5Be/nV9BmuuUysVD8myB +qw8A/KsXsHKn5QrRuVXOa5hvLEXbuqYw29mX6QKBgDGDzIzpR9uPtBCqzWJmc+IJ +z4m/1NFlEz0N0QNwZ/TlhyT60ytJNcmW8qkgOSTHG7RDueEIzjQ8LKJYH7kXjfcF +6AJczUG5PQo9cdJKo9JP3e1037P/58JpLcLe8xxQ4ce03zZpzhsxR2G/tz8DstJs +b8jpnLyqfGrcV2feUtIZ +-----END PRIVATE KEY----- diff --git a/nats/tests/configs/ip-tls.conf b/nats/tests/configs/ip-tls.conf new file mode 100644 index 000000000..ba85c64a6 --- /dev/null +++ b/nats/tests/configs/ip-tls.conf @@ -0,0 +1,17 @@ +# Simple TLS config file + +port: 4443 +net: localhost # net interface + +tls { + cert_file: "./tests/configs/certs/ip-cert.pem" + key_file: "./tests/configs/certs/ip-key.pem" + ca_file: "./tests/configs/certs/ip-ca.pem" + timeout: 2 +} + +authorization { + user: derek + password: porkchop + timeout: 1 +}