Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-proton-vpn-local-agent for 
openSUSE:Factory checked in at 2026-07-31 15:29:23
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-proton-vpn-local-agent (Old)
 and      /work/SRC/openSUSE:Factory/.python-proton-vpn-local-agent.new.2004 
(New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-proton-vpn-local-agent"

Fri Jul 31 15:29:23 2026 rev:6 rq:1368436 version:1.6.3

Changes:
--------
--- 
/work/SRC/openSUSE:Factory/python-proton-vpn-local-agent/python-proton-vpn-local-agent.changes
      2025-12-24 13:18:18.479407813 +0100
+++ 
/work/SRC/openSUSE:Factory/.python-proton-vpn-local-agent.new.2004/python-proton-vpn-local-agent.changes
    2026-07-31 16:10:06.410272256 +0200
@@ -1,0 +2,10 @@
+Thu Jul 30 04:11:04 UTC 2026 - Richard Rahl <[email protected]>
+
+- Update to version 1.6.3:
+  + fix: add error handling for certificate not yet valid
+- Update to version 1.6.2:
+  + chore: Update Root CA and add legacy intermediate CA
+- Update to version 1.6.1:
+  + Fix lint
+
+-------------------------------------------------------------------

Old:
----
  1.6.0.tar.gz

New:
----
  1.6.3.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-proton-vpn-local-agent.spec ++++++
--- /var/tmp/diff_new_pack.n1UEo8/_old  2026-07-31 16:10:07.258301756 +0200
+++ /var/tmp/diff_new_pack.n1UEo8/_new  2026-07-31 16:10:07.258301756 +0200
@@ -1,7 +1,7 @@
 #
 # spec file for package python-proton-vpn-local-agent
 #
-# Copyright (c) 2025 SUSE LLC
+# Copyright (c) 2026 SUSE LLC and contributors
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -19,7 +19,7 @@
 %{?sle15_python_module_pythons}
 %define         _name python-proton-vpn-local-agent
 Name:           python-proton-vpn-local-agent
-Version:        1.6.0
+Version:        1.6.3
 Release:        0
 Summary:        Proton VPN local agent written in Rust
 License:        GPL-3.0-only
@@ -55,7 +55,7 @@
 popd
 
 %install
-%if 0%{?suse_version} == 1600
+%if 0%{?suse_version} >= 1600 && 0%{?suse_version} < 1650
 pushd %{_name}
 %endif
 for p in $(echo "%{pythons}" | sed s/python31/python3.1/g); do

++++++ 1.6.0.tar.gz -> 1.6.3.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/local-agent-rs-1.6.0/local_agent_rs/Cargo.lock 
new/local-agent-rs-1.6.3/local_agent_rs/Cargo.lock
--- old/local-agent-rs-1.6.0/local_agent_rs/Cargo.lock  2025-09-30 
10:14:00.000000000 +0200
+++ new/local-agent-rs-1.6.3/local_agent_rs/Cargo.lock  2026-05-26 
13:02:36.000000000 +0200
@@ -424,9 +424,9 @@
 
 [[package]]
 name = "deranged"
-version = "0.3.11"
+version = "0.5.8"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4"
+checksum = "7cd812cc2bc1d69d4764bd80df88b4317eaef9e773c75226407d9bc0876b211c"
 dependencies = [
  "powerfmt",
 ]
@@ -670,7 +670,8 @@
  "socket2",
  "static_assertions",
  "test-log",
- "thiserror 1.0.63",
+ "thiserror 2.0.12",
+ "time",
  "tokio",
  "tokio-rustls",
  "uniffi",
@@ -775,9 +776,9 @@
 
 [[package]]
 name = "num-conv"
-version = "0.1.0"
+version = "0.2.2"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9"
+checksum = "521739c6d2bac4aa25192232afe6841231376b2b26d4d9fae5ecf8ca5772e441"
 
 [[package]]
 name = "num-integer"
@@ -1102,18 +1103,28 @@
 
 [[package]]
 name = "serde"
-version = "1.0.204"
+version = "1.0.228"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e"
+dependencies = [
+ "serde_core",
+ "serde_derive",
+]
+
+[[package]]
+name = "serde_core"
+version = "1.0.228"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "bc76f558e0cbb2a839d37354c575f1dc3fdc6546b5be373ba43d95f231bf7c12"
+checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad"
 dependencies = [
  "serde_derive",
 ]
 
 [[package]]
 name = "serde_derive"
-version = "1.0.204"
+version = "1.0.228"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222"
+checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -1325,30 +1336,30 @@
 
 [[package]]
 name = "time"
-version = "0.3.36"
+version = "0.3.47"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885"
+checksum = "743bd48c283afc0388f9b8827b976905fb217ad9e647fae3a379a9283c4def2c"
 dependencies = [
  "deranged",
  "itoa",
  "num-conv",
  "powerfmt",
- "serde",
+ "serde_core",
  "time-core",
  "time-macros",
 ]
 
 [[package]]
 name = "time-core"
-version = "0.1.2"
+version = "0.1.8"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3"
+checksum = "7694e1cfe791f8d31026952abf09c69ca6f6fa4e1a1229e18988f06a04a12dca"
 
 [[package]]
 name = "time-macros"
-version = "0.2.18"
+version = "0.2.27"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf"
+checksum = "2e70e4c5a0e0a8a4823ad65dfe1a6930e4f4d756dcd9dd7939022b5e8c501215"
 dependencies = [
  "num-conv",
  "time-core",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/local-agent-rs-1.6.0/local_agent_rs/Cargo.toml 
new/local-agent-rs-1.6.3/local_agent_rs/Cargo.toml
--- old/local-agent-rs-1.6.0/local_agent_rs/Cargo.toml  2025-09-30 
10:14:00.000000000 +0200
+++ new/local-agent-rs-1.6.3/local_agent_rs/Cargo.toml  2026-05-26 
13:02:36.000000000 +0200
@@ -25,6 +25,9 @@
 uniffi = { version = "0.29.3", features = ["cli"], optional = true }
 x509-parser = "0.16.0"
 
+[dev-dependencies]
+time = { version = "0.3.47", features = ["macros"] }
+
 [build-dependencies]
 uniffi = { version = "0.29.3", features = ["build"], optional = true }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/local-agent-rs-1.6.0/local_agent_rs/src/agent_connector.rs 
new/local-agent-rs-1.6.3/local_agent_rs/src/agent_connector.rs
--- old/local-agent-rs-1.6.0/local_agent_rs/src/agent_connector.rs      
2025-09-30 10:14:00.000000000 +0200
+++ new/local-agent-rs-1.6.3/local_agent_rs/src/agent_connector.rs      
2026-05-26 13:02:36.000000000 +0200
@@ -11,6 +11,7 @@
 use tokio::net::TcpStream;
 use tokio_rustls::rustls::{ClientConfig, RootCertStore};
 use tokio_rustls::TlsConnector;
+use x509_parser::time::ASN1Time;
 // 
-----------------------------------------------------------------------------
 
 /// The address of the local agent server, this ip is always the same
@@ -19,38 +20,71 @@
 /// The root certificate of the local agent server, this may expire in the 
future
 /// we have a test in the gtk python application unit tests which will fail
 /// when this expires.
-const PROTON_VPN_ROOT_CA: &str = r#"-----BEGIN CERTIFICATE-----
-MIIFozCCA4ugAwIBAgIBATANBgkqhkiG9w0BAQ0FADBAMQswCQYDVQQGEwJDSDEV
-MBMGA1UEChMMUHJvdG9uVlBOIEFHMRowGAYDVQQDExFQcm90b25WUE4gUm9vdCBD
-QTAeFw0xNzAyMTUxNDM4MDBaFw0yNzAyMTUxNDM4MDBaMEAxCzAJBgNVBAYTAkNI
-MRUwEwYDVQQKEwxQcm90b25WUE4gQUcxGjAYBgNVBAMTEVByb3RvblZQTiBSb290
-IENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAt+BsSsZg7+AuqTq7
-vDbPzfygtl9f8fLJqO4amsyOXlI7pquL5IsEZhpWyJIIvYybqS4s1/T7BbvHPLVE
-wlrq8A5DBIXcfuXrBbKoYkmpICGc2u1KYVGOZ9A+PH9z4Tr6OXFfXRnsbZToie8t
-2Xjv/dZDdUDAqeW89I/mXg3k5x08m2nfGCQDm4gCanN1r5MT7ge56z0MkY3FFGCO
-qRwspIEUzu1ZqGSTkG1eQiOYIrdOF5cc7n2APyvBIcfvp/W3cpTOEmEBJ7/14RnX
-nHo0fcx61Inx/6ZxzKkW8BMdGGQF3tF6u2M0FjVN0lLH9S0ul1TgoOS56yEJ34hr
-JSRTqHuar3t/xdCbKFZjyXFZFNsXVvgJu34CNLrHHTGJj9jiUfFnxWQYMo9UNUd4
-a3PPG1HnbG7LAjlvj5JlJ5aqO5gshdnqb9uIQeR2CdzcCJgklwRGCyDT1pm7eoiv
-WV19YBd81vKulLzgPavu3kRRe83yl29It2hwQ9FMs5w6ZV/X6ciTKo3etkX9nBD9
-ZzJPsGQsBUy7CzO1jK4W01+u3ItmQS+1s4xtcFxdFY8o/q1zoqBlxpe5MQIWN6Qa
-lryiET74gMHE/S5WrPlsq/gehxsdgc6GDUXG4dk8vn6OUMa6wb5wRO3VXGEc67IY
-m4mDFTYiPvLaFOxtndlUWuCruKcCAwEAAaOBpzCBpDAMBgNVHRMEBTADAQH/MB0G
-A1UdDgQWBBSDkIaYhLVZTwyLNTetNB2qV0gkVDBoBgNVHSMEYTBfgBSDkIaYhLVZ
-TwyLNTetNB2qV0gkVKFEpEIwQDELMAkGA1UEBhMCQ0gxFTATBgNVBAoTDFByb3Rv
-blZQTiBBRzEaMBgGA1UEAxMRUHJvdG9uVlBOIFJvb3QgQ0GCAQEwCwYDVR0PBAQD
-AgEGMA0GCSqGSIb3DQEBDQUAA4ICAQCYr7LpvnfZXBCxVIVc2ea1fjxQ6vkTj0zM
-htFs3qfeXpMRf+g1NAh4vv1UIwLsczilMt87SjpJ25pZPyS3O+/VlI9ceZMvtGXd
-MGfXhTDp//zRoL1cbzSHee9tQlmEm1tKFxB0wfWd/inGRjZxpJCTQh8oc7CTziHZ
-ufS+Jkfpc4Rasr31fl7mHhJahF1j/ka/OOWmFbiHBNjzmNWPQInJm+0ygFqij5qs
-51OEvubR8yh5Mdq4TNuWhFuTxpqoJ87VKaSOx/Aefca44Etwcj4gHb7LThidw/ky
-zysZiWjyrbfX/31RX7QanKiMk2RDtgZaWi/lMfsl5O+6E2lJ1vo4xv9pW8225B5X
-eAeXHCfjV/vrrCFqeCprNF6a3Tn/LX6VNy3jbeC+167QagBOaoDA01XPOx7Odhsb
-Gd7cJ5VkgyycZgLnT9zrChgwjx59JQosFEG1DsaAgHfpEl/N3YPJh68N7fwN41Cj
-zsk39v6iZdfuet/sP7oiP5/gLmA/CIPNhdIYxaojbLjFPkftVjVPn49RqwqzJJPR
-N8BOyb94yhQ7KO4F3IcLT/y/dsWitY0ZH4lCnAVV/v2YjWAWS3OWyC8BFx/Jmc3W
-DK/yPwECUcPgHIeXiRjHnJt0Zcm23O2Q3RphpU+1SO3XixsXpOVOYP6rJIXW9bMZ
-A1gTTlpi7A==
+const PROTON_VPN_ROOT_FOLLOWED_BY_INTERMEDIATE_LEGACY_CA: &str = r#"
+-----BEGIN CERTIFICATE-----
+MIIFnTCCA4WgAwIBAgIUCI574SM3Lyh47GyNl0WAOYrqb5QwDQYJKoZIhvcNAQEL
+BQAwXjELMAkGA1UEBhMCQ0gxHzAdBgNVBAoMFlByb3RvbiBUZWNobm9sb2dpZXMg
+QUcxEjAQBgNVBAsMCVByb3RvblZQTjEaMBgGA1UEAwwRUHJvdG9uVlBOIFJvb3Qg
+Q0EwHhcNMTkxMDE3MDgwNjQxWhcNMzkxMDEyMDgwNjQxWjBeMQswCQYDVQQGEwJD
+SDEfMB0GA1UECgwWUHJvdG9uIFRlY2hub2xvZ2llcyBBRzESMBAGA1UECwwJUHJv
+dG9uVlBOMRowGAYDVQQDDBFQcm90b25WUE4gUm9vdCBDQTCCAiIwDQYJKoZIhvcN
+AQEBBQADggIPADCCAgoCggIBAMkUT7zMUS5C+NjQ7YoGpVFlfbN9HFgG4JiKfHB8
+QxnPPRgyTi0zVOAj1ImsRilauY8Ddm5dQtd8qcApoz6oCx5cFiiSQG2uyhS/59Zl
+5wqIkw1o+CgwZgeWkq04lcrxhhfPgJZRFjrYVezy/Z2Ssd18s3/FFNQ+2iV1KC2K
+z8eSPr50u+l9vEKsKiNGkJTdlWjoDKZM2C15i/h8Smi+PdJlx7WMTtYoVC1Fzq0r
+aCPDQl18kspu11b6d8ECPWghKcDIIKuA0r0nGqF1GvH1AmbC/xUaNrKgz9AfioZL
+MP/l22tVG3KKM1ku0eYHX7NzNHgkM2JKnBBannImQQBGTAcvvUlnfF3AHx4vzx7H
+ahpBz8ebThx2uv+vzu8lCVEcKjQObGwLbAONJN2enug8hwSSZQv7tz7onDQWlYh0
+El5fnkrEQGbukNnSyOqTwfobvBllIPzBqdO38eZFA0YTlH9plYjIjPjGl931lFAA
+3G9t0x7nxAauLXN5QVp1yoF1tzXc5kN0SFAasM9VtVEOSMaGHLKhF+IMyVX8h5Iu
+IRC8u5O672r7cHS+Dtx87LjxypqNhmbf1TWyLJSoh0qYhMr+BbO7+N6zKRIZPI5b
+MXc8Be2pQwbSA4ZrDvSjFC9yDXmSuZTyVo6Bqi/KCUZeaXKof68oNxVYeGowNeQd
+g/znAgMBAAGjUzBRMB0GA1UdDgQWBBR44WtTuEKCaPPUltYEHZoyhJo+4TAfBgNV
+HSMEGDAWgBR44WtTuEKCaPPUltYEHZoyhJo+4TAPBgNVHRMBAf8EBTADAQH/MA0G
+CSqGSIb3DQEBCwUAA4ICAQBBmzCQlHxOJ6izys3TVpaze+rUkA9GejgsB2DZXIcm
+4Lj/SNzQsPlZRu4S0IZV253dbE1DoWlHanw5lnXwx8iU82X7jdm/5uZOwj2NqSqT
+bTn0WLAC6khEKKe5bPTf18UOcwN82Le3AnkwcNAaBO5/TzFQVgnVedXr2g6rmpp9
+gdedeEl9acB7xqfYfkrmijqYMm+xeG2rXaanch3HjweMDuZdT/Ub5G6oir0Kowft
+lA1ytjXRg+X+yWymTpF/zGLYfSodWWjMKhpzZtRJZ+9B0pWXUyY7SuCj5T5SMIAu
+x3NQQ46wSbHRolIlwh7zD7kBgkyLe7ByLvGFKa2Vw4PuWjqYwrRbFjb2+EKAwPu6
+VTWz/QQTU8oJewGFipw94Bi61zuaPvF1qZCHgYhVojRy6KcqncX2Hx9hjfVxspBZ
+DrVH6uofCmd99GmVu+qizybWQTrPaubfc/a2jJIbXc2bRQjYj/qmjE3hTlmO3k7V
+EP6i8CLhEl+dX75aZw9StkqjdpIApYwX6XNDqVuGzfeTXXclk4N4aDPwPFM/Yo/e
+KnvlNlKbljWdMYkfx8r37aOHpchH34cv0Jb5Im+1H07ywnshXNfUhRazOpubJRHn
+bjDuBwWS1/Vwp5AJ+QHsPXhJdl3qHc1szJZVJb3VyAWvG/bWApKfFuZX18tiI4N0
+EA==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFjDCCA3SgAwIBAgIBBDANBgkqhkiG9w0BAQsFADBeMQswCQYDVQQGEwJDSDEf
+MB0GA1UECgwWUHJvdG9uIFRlY2hub2xvZ2llcyBBRzESMBAGA1UECwwJUHJvdG9u
+VlBOMRowGAYDVQQDDBFQcm90b25WUE4gUm9vdCBDQTAeFw0yMjAxMTQxNjQ4MTBa
+Fw0zMjAxMTIxNjQ4NDBaMEoxCzAJBgNVBAYTAkNIMRUwEwYDVQQKEwxQcm90b25W
+UE4gQUcxJDAiBgNVBAMTG1Byb3RvblZQTiBJbnRlcm1lZGlhdGUgQ0EgMTCCAiIw
+DQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANv3uwQMFjYOx74taxadhczLbjCT
+uT73jMz09EqFNv7O7UesXfYJ6kQgYV9YyE86znP4xbsswNUZYh+XdZUpOoP6Zu3t
+R/iiYiuzi6jVYrJ66G89nPqS2mm5dn8Fbb8CRWkJygm8AdlYkDwYNldhDUrERlQd
+CRDGsYYg/98dded+5pXnSG8Y/+iuLM6/YYhkUVQeCfq1L6XguSwu8CuvJjIjjE1P
+ptUHa3Hc3tGziVydltKynxWlqb1dJqinGKiBZvYnoiV4motpFYwhc3Wd09JLPzeo
+bhD2IAZ2evSatikMWDingEv1EJXpI+V/E2AK3xHKSkhw+YZx99tNxCiOu3U5BFAr
+eZR3j2YnZzX1nEv9p02IGaWzzYJPNED0zSO2w07uthSmKcxA39VTvs91lptbcV7V
+TxoJY0SErHIeVS3Scrnr7WvoOTuu3M3SCRqe6oI9oJZMOdfNsceBdvG+qlpOFICo
+BjO53W4BK8KahzTd/PWlBRiVJ3UVv8xXwUDA+o9834DXVAobaAHXQtM9jNobqT98
+FXhZktjOQEA2UORL581ZPxfKeHLRcgWJ5dmPsDBGy/L6/qW/yrm6DUDAdN5+q41+
+gSNEjNBjLBJQFUmDk3l6Qxiu0uEDQ98oFvGHk5US2Kbj0OAq1RpiDjHci/536yua
+9rTC+cxekTM2asdXAgMBAAGjaTBnMA4GA1UdDwEB/wQEAwIBBjASBgNVHRMBAf8E
+CDAGAQH/AgEAMB8GA1UdIwQYMBaAFHjha1O4QoJo89SW1gQdmjKEmj7hMCAGA1Ud
+JQEB/wQWMBQGCCsGAQUFBwMCBggrBgEFBQcDATANBgkqhkiG9w0BAQsFAAOCAgEA
+fFMtLGksBmCWBbLu5SJW+6/8EtOoGD+QbCRc7kCpsKZOqgwKuVeEQHsTCJgeSyWM
+XXnD5mqtEKcgaJ8bjgE2YkPPajiqnqAYPxJ4xCUXELY+Tm6LMifAuxtGIC9M04Cy
+IIe44OtblEQDP+JB++TLKbwnj/+TAC7537eGxZa3Jesc4YUD2qUTp2Zqqo2Tzqib
+iyuGCeVfc+OiG0xcZls9lvYOIAcEIqxvWEwgSCJUul1567b3/mKe5S2SkpY6du29
+I3k3qhvSvrA1WtBlqAAeggLiQ5DE47LIMdJU+roYmk4TAJmibI2nKoonf1+OBF/S
+Zg04xEd18dtAoX1CjgTHlIeNQzeGV6O0/jhn3BfNWB2a2A8u5mVxDyOG3ZJEjdKC
+eiv6r/iEGI7BwOe3WSdvcmNpsa+UehbupN9azRyhEykXmG+LGF5DEylLxK128tdD
+0rl3p1qEWcRYIdzE8iS7rp0y0wD0pz0ye80OyGXJYc3Y8WSxPVQL/t35x7gaKnIW
+8S0Goqe7Or/F3bxYXh+kk1ARZyF0bmH/yOlkstV7ETsL7OB8aDEvlc/BG80bU68m
+cQDquPP1RszuksYu6pGZPtwra23Wuo8alsxVg4aJhhIKP/iocJdWKnodMMAIF23N
++WPATcqIu3YrtUFWnNHGAa/z3xBx3VwPMGIOcmfVl4E=
 -----END CERTIFICATE-----
 "#;
 
@@ -72,9 +106,11 @@
     pub timeout_in_seconds: u64,
 }
 
-/// Builds the root certificate store, fom the constant PROTON_VPN_ROOT_CA.
+/// Builds the root certificate store, from the constant 
PROTON_VPN_ROOT_FOLLOWED_BY_INTERMEDIATE_LEGACY_CA.
 fn build_root_cert_store() -> Result<RootCertStore> {
-    let mut cursor = std::io::Cursor::new(PROTON_VPN_ROOT_CA);
+    let mut cursor = std::io::Cursor::new(
+        PROTON_VPN_ROOT_FOLLOWED_BY_INTERMEDIATE_LEGACY_CA
+    );
     let ca = rustls_pemfile::certs(&mut cursor);
     let mut root_cert_store = RootCertStore::empty();
     for i in ca {
@@ -99,8 +135,10 @@
 }
 
 fn ensure_certificates_are_current(
-    certificates: &[CertificateDer<'_>]
+    certificates: &[CertificateDer<'_>],
+    now: Option<ASN1Time>,  // Optional time for testing
 ) -> Result<()> {
+    let now = now.unwrap_or_else(ASN1Time::now);
 
     for cert_d in certificates {
 
@@ -109,11 +147,20 @@
         )?;
 
         let validity = &cert.tbs_certificate.validity;
-        if !validity.is_valid() {
+
+        // Check if current time is before the certificate's start time
+        if now < validity.not_before {
+            return Err(Error::NotYetValidCertificate(format!(
+                "Now {:?}, Start: {}, End: {}",
+                now, &validity.not_before, &validity.not_after
+            )));
+        }
+
+        // Check if current time is after the certificate's end time
+        if now > validity.not_after {
             return Err(Error::ExpiredCertificate(format!(
                 "Now {:?}, Start: {}, End: {}",
-                std::time::SystemTime::now(),
-                &validity.not_before, &validity.not_after
+                now, &validity.not_before, &validity.not_after
             )));
         }
     }
@@ -147,7 +194,7 @@
 
         // This does a time validation of the certificates
         // and will return an error if any of them are expired.
-        ensure_certificates_are_current(&certs)?;
+        ensure_certificates_are_current(&certs, None)?;
 
         // Key is in pks8 format
         let key = rustls_pemfile::private_key(&mut 
std::io::Cursor::new(&params.key))?
@@ -206,9 +253,10 @@
 #[cfg(test)]
 mod tests {
     use super::*;
+    use time::macros::datetime;
 
     #[test]
-    fn test_proton_vpn_root_certificate_is_not_close_to_expiration() {
+    fn 
test_proton_vpn_root_and_intermediate_legacy_certificates_are_not_close_to_expiration()
 {
         // Ensure that the certificate still has 90 days before it expires.
         let ninety_days = 90_f64;
 
@@ -217,7 +265,9 @@
 
         // We need an in-memory reader for the certificate as we are reading
         // an in-memory hard coded certificate.
-        let mut reader = std::io::Cursor::new(PROTON_VPN_ROOT_CA);
+        let mut reader = std::io::Cursor::new(
+            PROTON_VPN_ROOT_FOLLOWED_BY_INTERMEDIATE_LEGACY_CA
+        );
 
         // Find the certificate in the pem file
         for cert_der in rustls_pemfile::certs(&mut reader) {
@@ -241,4 +291,49 @@
             assert!(expires_in > seconds);
         }
     }
+
+    // Testing certificate validity errors with the embedded root/intermediate 
certificates
+
+    // Root CA: Valid 2019-01-17 - 2039-01-12
+    // Intermediate: Valid 2022-01-14 - 2032-01-12
+
+    fn parse_embedded_certificates() -> Vec<CertificateDer<'static>> {
+        let mut cursor = std::io::Cursor::new(
+            PROTON_VPN_ROOT_FOLLOWED_BY_INTERMEDIATE_LEGACY_CA
+        );
+        rustls_pemfile::certs(&mut cursor)
+            .filter_map(|x| x.ok())
+            .collect()
+    }
+
+    #[test]
+    fn test_valid_certificate_with_current_time() {
+        let certs = parse_embedded_certificates();
+        
+        // Use current time
+        let result = ensure_certificates_are_current(&certs, None);
+        assert!(result.is_ok(), "Embedded certificates should be currently 
valid");
+    }
+
+    #[test]
+    fn test_expired_certificate_error() {
+        let certs = parse_embedded_certificates();
+        // Time after both certificates end
+        let expired_time = ASN1Time::new(datetime!(2040-01-15 00:00:00 UTC));
+        let result = ensure_certificates_are_current(&certs, 
Some(expired_time));
+        assert!(matches!(result, Err(Error::ExpiredCertificate(_))), 
+                "Should return ExpiredCertificate error when time is past 
certificate end date");
+    }
+
+    #[test]
+    fn test_not_yet_valid_certificate_error() {
+        let certs = parse_embedded_certificates();
+        
+        // Time before the root cert starts (with buffer)
+        let not_yet_valid_time = ASN1Time::new(datetime!(2019-01-01 00:00:00 
UTC));
+        
+        let result = ensure_certificates_are_current(&certs, 
Some(not_yet_valid_time));
+        assert!(matches!(result, Err(Error::NotYetValidCertificate(_))), 
+                "Should return NotYetValidCertificate error when time is 
before certificate start date");
+    }
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/local-agent-rs-1.6.0/local_agent_rs/src/error.rs 
new/local-agent-rs-1.6.3/local_agent_rs/src/error.rs
--- old/local-agent-rs-1.6.0/local_agent_rs/src/error.rs        2025-09-30 
10:14:00.000000000 +0200
+++ new/local-agent-rs-1.6.3/local_agent_rs/src/error.rs        2026-05-26 
13:02:36.000000000 +0200
@@ -41,6 +41,8 @@
     BincodeError(#[from] bincode::Error),
     #[error("Expired certificate: {0}")]
     ExpiredCertificate(String),
+    #[error("Certificate not yet valid: {0}")]
+    NotYetValidCertificate(String),
     #[error("Unable to parse certificate")]
     UnableToParseCertificate,
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/local-agent-rs-1.6.0/local_agent_rs/src/port_forwarding.rs 
new/local-agent-rs-1.6.3/local_agent_rs/src/port_forwarding.rs
--- old/local-agent-rs-1.6.0/local_agent_rs/src/port_forwarding.rs      
2025-09-30 10:14:00.000000000 +0200
+++ new/local-agent-rs-1.6.3/local_agent_rs/src/port_forwarding.rs      
2026-05-26 13:02:36.000000000 +0200
@@ -158,8 +158,7 @@
         if bytes_read != BYTE_SIZE {
             return Err(Error::PortForwarding(format!(
                 "Protocol error incorrect number of bytes returned in \
-                         nat-pmp response {}",
-                bytes_read
+                         nat-pmp response {bytes_read}"
             )));
         }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/local-agent-rs-1.6.0/local_agent_rs/src/reason_code.rs 
new/local-agent-rs-1.6.3/local_agent_rs/src/reason_code.rs
--- old/local-agent-rs-1.6.0/local_agent_rs/src/reason_code.rs  2025-09-30 
10:14:00.000000000 +0200
+++ new/local-agent-rs-1.6.3/local_agent_rs/src/reason_code.rs  2026-05-26 
13:02:36.000000000 +0200
@@ -1,9 +1,9 @@
 // 
-----------------------------------------------------------------------------
 // Copyright (c) 2024 Proton AG
 // 
-----------------------------------------------------------------------------
-/// Represents the reason for a status message.
+//! Represents the reason for a status message.
+//! The reason code is used to indicate why a connection is jailed.
 
-/// The reason code is used to indicate why a connection is jailed.
 pub const REASON_CODE_UNKNOWN: i32 = 0;
 pub const REASON_CODE_GUEST_SESSION: i32 = 86100;
 pub const REASON_CODE_RESTRICTED_SERVER: i32 = 86104;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/local-agent-rs-1.6.0/python-proton-vpn-local-agent/Cargo.lock 
new/local-agent-rs-1.6.3/python-proton-vpn-local-agent/Cargo.lock
--- old/local-agent-rs-1.6.0/python-proton-vpn-local-agent/Cargo.lock   
2025-09-30 10:14:00.000000000 +0200
+++ new/local-agent-rs-1.6.3/python-proton-vpn-local-agent/Cargo.lock   
2026-05-26 13:02:36.000000000 +0200
@@ -702,9 +702,9 @@
 
 [[package]]
 name = "num-conv"
-version = "0.1.0"
+version = "0.2.2"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9"
+checksum = "521739c6d2bac4aa25192232afe6841231376b2b26d4d9fae5ecf8ca5772e441"
 
 [[package]]
 name = "num-integer"
@@ -916,7 +916,7 @@
 
 [[package]]
 name = "python-proton-vpn-local-agent"
-version = "1.6.0"
+version = "1.6.3"
 dependencies = [
  "local-agent-rs",
  "log",
@@ -1094,18 +1094,28 @@
 
 [[package]]
 name = "serde"
-version = "1.0.204"
+version = "1.0.228"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "bc76f558e0cbb2a839d37354c575f1dc3fdc6546b5be373ba43d95f231bf7c12"
+checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e"
+dependencies = [
+ "serde_core",
+ "serde_derive",
+]
+
+[[package]]
+name = "serde_core"
+version = "1.0.228"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad"
 dependencies = [
  "serde_derive",
 ]
 
 [[package]]
 name = "serde_derive"
-version = "1.0.204"
+version = "1.0.228"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222"
+checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -1273,29 +1283,30 @@
 
 [[package]]
 name = "time"
-version = "0.3.43"
+version = "0.3.47"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "83bde6f1ec10e72d583d91623c939f623002284ef622b87de38cfd546cbf2031"
+checksum = "743bd48c283afc0388f9b8827b976905fb217ad9e647fae3a379a9283c4def2c"
 dependencies = [
  "deranged",
+ "itoa",
  "num-conv",
  "powerfmt",
- "serde",
+ "serde_core",
  "time-core",
  "time-macros",
 ]
 
 [[package]]
 name = "time-core"
-version = "0.1.6"
+version = "0.1.8"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "40868e7c1d2f0b8d73e4a8c7f0ff63af4f6d19be117e90bd73eb1d62cf831c6b"
+checksum = "7694e1cfe791f8d31026952abf09c69ca6f6fa4e1a1229e18988f06a04a12dca"
 
 [[package]]
 name = "time-macros"
-version = "0.2.24"
+version = "0.2.27"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "30cfb0125f12d9c277f35663a0a33f8c30190f4e4574868a330595412d34ebf3"
+checksum = "2e70e4c5a0e0a8a4823ad65dfe1a6930e4f4d756dcd9dd7939022b5e8c501215"
 dependencies = [
  "num-conv",
  "time-core",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/local-agent-rs-1.6.0/python-proton-vpn-local-agent/Cargo.toml 
new/local-agent-rs-1.6.3/python-proton-vpn-local-agent/Cargo.toml
--- old/local-agent-rs-1.6.0/python-proton-vpn-local-agent/Cargo.toml   
2025-09-30 10:14:00.000000000 +0200
+++ new/local-agent-rs-1.6.3/python-proton-vpn-local-agent/Cargo.toml   
2026-05-26 13:02:36.000000000 +0200
@@ -1,6 +1,6 @@
 [package]
 name = "python-proton-vpn-local-agent"
-version = "1.6.0"
+version = "1.6.3"
 edition = "2021"
 
 # See more keys and their definitions at 
https://doc.rust-lang.org/cargo/reference/manifest.html
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/local-agent-rs-1.6.0/python-proton-vpn-local-agent/src/connection_details.rs
 
new/local-agent-rs-1.6.3/python-proton-vpn-local-agent/src/connection_details.rs
--- 
old/local-agent-rs-1.6.0/python-proton-vpn-local-agent/src/connection_details.rs
    2025-09-30 10:14:00.000000000 +0200
+++ 
new/local-agent-rs-1.6.3/python-proton-vpn-local-agent/src/connection_details.rs
    2026-05-26 13:02:36.000000000 +0200
@@ -36,7 +36,7 @@
     /// This method is used to convert the object to a string for easier
     /// debugging in Python.
     fn __str__(&self) -> PyResult<String> {
-        Ok(format!("{:?}", self))
+        Ok(format!("{self:?}"))
     }
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/local-agent-rs-1.6.0/python-proton-vpn-local-agent/src/error.rs 
new/local-agent-rs-1.6.3/python-proton-vpn-local-agent/src/error.rs
--- old/local-agent-rs-1.6.0/python-proton-vpn-local-agent/src/error.rs 
2025-09-30 10:14:00.000000000 +0200
+++ new/local-agent-rs-1.6.3/python-proton-vpn-local-agent/src/error.rs 
2026-05-26 13:02:36.000000000 +0200
@@ -4,7 +4,7 @@
 use local_agent_rs as la;
 
 use crate::{
-    APIError, ExpiredCertificateError, LocalAgentError, PolicyAPIError,
+    APIError, ExpiredCertificateError, NotYetValidCertificateError, 
LocalAgentError, PolicyAPIError,
     SyntaxAPIError,
 };
 use pyo3::exceptions::PyTimeoutError;
@@ -45,6 +45,8 @@
         match err {
             Error::LocalAgent(la::Error::ExpiredCertificate(e)) =>
                 ExpiredCertificateError::new_err(e.to_string()),
+            Error::LocalAgent(la::Error::NotYetValidCertificate(e)) =>
+                NotYetValidCertificateError::new_err(e.to_string()),
             Error::LocalAgent(la::Error::Tokio(e))
                 if e.kind() == ErrorKind::TimedOut
                     || e.kind() == ErrorKind::BrokenPipe =>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/local-agent-rs-1.6.0/python-proton-vpn-local-agent/src/exception.rs 
new/local-agent-rs-1.6.3/python-proton-vpn-local-agent/src/exception.rs
--- old/local-agent-rs-1.6.0/python-proton-vpn-local-agent/src/exception.rs     
2025-09-30 10:14:00.000000000 +0200
+++ new/local-agent-rs-1.6.3/python-proton-vpn-local-agent/src/exception.rs     
2026-05-26 13:02:36.000000000 +0200
@@ -14,6 +14,13 @@
 
 create_exception!(
     local_agent,
+    NotYetValidCertificateError,
+    LocalAgentError,
+    "Raised when the passed certificate is not yet valid during read from 
socket."
+);
+
+create_exception!(
+    local_agent,
     ExpiredCertificateError,
     LocalAgentError,
     "Raised when the passed certificate is expired during read from socket."
@@ -46,6 +53,10 @@
         "ExpiredCertificateError",
         m.py().get_type::<ExpiredCertificateError>(),
     )?;
+    m.add(
+        "NotYetValidCertificateError",
+        m.py().get_type::<NotYetValidCertificateError>(),
+    )?;
     m.add("APIError", m.py().get_type::<APIError>())?;
     m.add("SyntaxAPIError", m.py().get_type::<SyntaxAPIError>())?;
     m.add("PolicyAPIError", m.py().get_type::<PolicyAPIError>())?;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/local-agent-rs-1.6.0/python-proton-vpn-local-agent/src/logger.rs 
new/local-agent-rs-1.6.3/python-proton-vpn-local-agent/src/logger.rs
--- old/local-agent-rs-1.6.0/python-proton-vpn-local-agent/src/logger.rs        
2025-09-30 10:14:00.000000000 +0200
+++ new/local-agent-rs-1.6.3/python-proton-vpn-local-agent/src/logger.rs        
2026-05-26 13:02:36.000000000 +0200
@@ -122,7 +122,7 @@
                         let filename = filename.to_string();
                         rust_info.set_item(
                             "name",
-                            format!("{LOG_NAME}/{}", filename),
+                            format!("{LOG_NAME}/{filename}"),
                         )?;
                     }
                 }
@@ -153,7 +153,7 @@
 
         match result {
             Ok(_) => (),
-            Err(error) => eprintln!("Failure in logger: {}", error),
+            Err(error) => eprintln!("Failure in logger: {error}"),
         }
     }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/local-agent-rs-1.6.0/python-proton-vpn-local-agent/src/reason.rs 
new/local-agent-rs-1.6.3/python-proton-vpn-local-agent/src/reason.rs
--- old/local-agent-rs-1.6.0/python-proton-vpn-local-agent/src/reason.rs        
2025-09-30 10:14:00.000000000 +0200
+++ new/local-agent-rs-1.6.3/python-proton-vpn-local-agent/src/reason.rs        
2026-05-26 13:02:36.000000000 +0200
@@ -101,7 +101,7 @@
     /// This method is used to convert the object to a string for easier
     /// debugging in Python.
     fn __str__(&self) -> PyResult<String> {
-        Ok(format!("{:?}", self))
+        Ok(format!("{self:?}"))
     }
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/local-agent-rs-1.6.0/python-proton-vpn-local-agent/src/state.rs 
new/local-agent-rs-1.6.3/python-proton-vpn-local-agent/src/state.rs
--- old/local-agent-rs-1.6.0/python-proton-vpn-local-agent/src/state.rs 
2025-09-30 10:14:00.000000000 +0200
+++ new/local-agent-rs-1.6.3/python-proton-vpn-local-agent/src/state.rs 
2026-05-26 13:02:36.000000000 +0200
@@ -17,7 +17,7 @@
     // This method is used to convert the object to a string for easier
     /// debugging in Python.
     fn __str__(&self) -> PyResult<String> {
-        Ok(format!("{:?}", self))
+        Ok(format!("{self:?}"))
     }
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/local-agent-rs-1.6.0/python-proton-vpn-local-agent/src/status.rs 
new/local-agent-rs-1.6.3/python-proton-vpn-local-agent/src/status.rs
--- old/local-agent-rs-1.6.0/python-proton-vpn-local-agent/src/status.rs        
2025-09-30 10:14:00.000000000 +0200
+++ new/local-agent-rs-1.6.3/python-proton-vpn-local-agent/src/status.rs        
2026-05-26 13:02:36.000000000 +0200
@@ -26,7 +26,7 @@
     /// This method is used to convert the Status object to a string for easier
     /// debugging in Python.
     fn __str__(&self) -> PyResult<String> {
-        Ok(format!("{:?}", self))
+        Ok(format!("{self:?}"))
     }
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/local-agent-rs-1.6.0/python-proton-vpn-local-agent/versions.yml 
new/local-agent-rs-1.6.3/python-proton-vpn-local-agent/versions.yml
--- old/local-agent-rs-1.6.0/python-proton-vpn-local-agent/versions.yml 
2025-09-30 10:14:00.000000000 +0200
+++ new/local-agent-rs-1.6.3/python-proton-vpn-local-agent/versions.yml 
2026-05-26 13:02:36.000000000 +0200
@@ -1,3 +1,30 @@
+version: 1.6.3
+time: 2026/05/14 13:55
+author: Elena Švilpė
+email: [email protected]
+urgency: low
+stability: unstable
+description:
+- "fix: add error when certificate is not yet valid"
+---
+version: 1.6.2
+time: 2026/04/13 15:27
+author: Richard Paterson
+email: [email protected]
+urgency: low
+stability: unstable
+description:
+- "chore: Update Root CA and add legacy intermediate CA"
+---
+version: 1.6.1
+time: 2026/03/12 13:07
+author: Luke Titley
+email: [email protected]
+urgency: low
+stability: unstable
+description:
+- "fix: Linting errors"
+---
 version: 1.6.0
 time: 2025/09/29 14:38
 author: Luke Titley

++++++ vendor.tar.zst ++++++
/work/SRC/openSUSE:Factory/python-proton-vpn-local-agent/vendor.tar.zst 
/work/SRC/openSUSE:Factory/.python-proton-vpn-local-agent.new.2004/vendor.tar.zst
 differ: char 7, line 1

Reply via email to