allow expired certificates for electrum servers so long as they have been previously used or explicitly approved

This commit is contained in:
Craig Raw 2022-12-16 12:06:05 +02:00
parent 1fa52f043c
commit 56784b684a
3 changed files with 37 additions and 3 deletions

View file

@ -290,8 +290,7 @@ public class AppServices {
connectionService.setRestartOnFailure(false); connectionService.setRestartOnFailure(false);
} }
if(failEvent.getSource().getException() instanceof TlsServerException && failEvent.getSource().getException().getCause() != null) { if(failEvent.getSource().getException() instanceof TlsServerException tlsServerException && failEvent.getSource().getException().getCause() != null) {
TlsServerException tlsServerException = (TlsServerException)failEvent.getSource().getException();
connectionService.setRestartOnFailure(false); connectionService.setRestartOnFailure(false);
if(tlsServerException.getCause().getMessage().contains("PKIX path building failed")) { if(tlsServerException.getCause().getMessage().contains("PKIX path building failed")) {
File crtFile = Config.get().getElectrumServerCert(); File crtFile = Config.get().getElectrumServerCert();
@ -315,6 +314,15 @@ public class AppServices {
} }
} }
} }
} else if(tlsServerException.getCause().getCause() instanceof UnknownCertificateExpiredException expiredException) {
Optional<ButtonType> optButton = AppServices.showErrorDialog("SSL Handshake Failed", "The certificate provided by the server at " + tlsServerException.getServer().getHost() + " has expired. "
+ tlsServerException.getMessage() + "." +
"\n\nDo you still want to proceed?", ButtonType.NO, ButtonType.YES);
if(optButton.isPresent() && optButton.get() == ButtonType.YES) {
Storage.saveCertificate(tlsServerException.getServer().getHost(), expiredException.getCertificate());
Platform.runLater(() -> restartService(connectionService));
return;
}
} }
} }

View file

@ -57,7 +57,13 @@ public class TcpOverTlsTransport extends TcpTransport {
throw new CertificateException("No server certificate provided"); throw new CertificateException("No server certificate provided");
} }
certs[0].checkValidity(); try {
certs[0].checkValidity();
} catch(CertificateExpiredException e) {
if(Storage.getCertificateFile(server.getHost()) == null) {
throw new UnknownCertificateExpiredException(e.getMessage(), certs[0]);
}
}
} }
} }
}; };
@ -68,6 +74,9 @@ public class TcpOverTlsTransport extends TcpTransport {
try { try {
X509Certificate x509Certificate = (X509Certificate)certificate; X509Certificate x509Certificate = (X509Certificate)certificate;
x509Certificate.checkValidity(); x509Certificate.checkValidity();
} catch(CertificateExpiredException e) {
//Allow expired certificates so long as they have been previously used or explicitly approved
//These will usually be self-signed certificates that users may not have the expertise to renew
} catch(CertificateException e) { } catch(CertificateException e) {
crtFile.delete(); crtFile.delete();
return getTrustManagers(null); return getTrustManagers(null);

View file

@ -0,0 +1,17 @@
package com.sparrowwallet.sparrow.net;
import java.security.cert.Certificate;
import java.security.cert.CertificateExpiredException;
public class UnknownCertificateExpiredException extends CertificateExpiredException {
private final Certificate certificate;
public UnknownCertificateExpiredException(String message, Certificate certificate) {
super(message);
this.certificate = certificate;
}
public Certificate getCertificate() {
return certificate;
}
}