mirror of
https://github.com/Qortal/altcoinj.git
synced 2025-02-12 02:05:53 +00:00
Payment protocol: misc enhancements.
Stop using the JDK store and use our own, to make the StartSSL fix effective. Include the certs in the exception thrown if the chain doesn't verify. Support loading from a file in the PaymentProtocol tool. Print the certs out in the PaymentProtocol tool if there's an error.
This commit is contained in:
parent
feecc8f486
commit
0ed260bae2
@ -16,6 +16,9 @@
|
||||
|
||||
package com.google.bitcoin.protocols.payments;
|
||||
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.List;
|
||||
|
||||
public class PaymentRequestException extends Exception {
|
||||
public PaymentRequestException(String msg) {
|
||||
super(msg);
|
||||
@ -86,6 +89,8 @@ public class PaymentRequestException extends Exception {
|
||||
}
|
||||
|
||||
public static class PkiVerificationException extends PaymentRequestException {
|
||||
public List<X509Certificate> certificates;
|
||||
|
||||
public PkiVerificationException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
@ -93,5 +98,10 @@ public class PaymentRequestException extends Exception {
|
||||
public PkiVerificationException(Exception e) {
|
||||
super(e);
|
||||
}
|
||||
|
||||
public PkiVerificationException(Exception e, List<X509Certificate> certificates) {
|
||||
super(e);
|
||||
this.certificates = certificates;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -441,6 +441,7 @@ public class PaymentSession {
|
||||
* Returns null if no PKI method was specified in the {@link Protos.PaymentRequest}.
|
||||
*/
|
||||
public @Nullable PkiVerificationData verifyPki() throws PaymentRequestException {
|
||||
List<X509Certificate> certs = null;
|
||||
try {
|
||||
if (pkiVerificationData != null)
|
||||
return pkiVerificationData;
|
||||
@ -464,7 +465,7 @@ public class PaymentSession {
|
||||
// The ordering of certificates is defined by the payment protocol spec to be the same as what the Java
|
||||
// crypto API requires - convenient!
|
||||
CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
|
||||
List<X509Certificate> certs = Lists.newArrayList();
|
||||
certs = Lists.newArrayList();
|
||||
for (ByteString bytes : protoCerts.getCertificateList())
|
||||
certs.add((X509Certificate) certificateFactory.generateCertificate(bytes.newInput()));
|
||||
CertPath path = certificateFactory.generateCertPath(certs);
|
||||
@ -536,7 +537,7 @@ public class PaymentSession {
|
||||
} catch (CertPathValidatorException e) {
|
||||
// The certificate chain isn't known or trusted, probably, the server is using an SSL root we don't
|
||||
// know about and the user needs to upgrade to a new version of the software (or import a root cert).
|
||||
throw new PaymentRequestException.PkiVerificationException(e);
|
||||
throw new PaymentRequestException.PkiVerificationException(e, certs);
|
||||
} catch (InvalidKeyException e) {
|
||||
// Shouldn't happen if the certs verified correctly.
|
||||
throw new PaymentRequestException.PkiVerificationException(e);
|
||||
@ -586,8 +587,7 @@ public class PaymentSession {
|
||||
path = System.getProperty("javax.net.ssl.trustStore");
|
||||
}
|
||||
if (path == null) {
|
||||
// Try this default system location for Linux/Windows/OSX.
|
||||
path = System.getProperty("java.home") + "/lib/security/cacerts".replace('/', File.separatorChar);
|
||||
return loadFallbackStore(defaultPassword);
|
||||
}
|
||||
try {
|
||||
KeyStore keyStore = KeyStore.getInstance(keyStoreType);
|
||||
@ -597,13 +597,17 @@ public class PaymentSession {
|
||||
} catch (FileNotFoundException e) {
|
||||
// If we failed to find a system trust store, load our own fallback trust store. This can fail on Android
|
||||
// but we should never reach it there.
|
||||
KeyStore keyStore = KeyStore.getInstance("JKS");
|
||||
InputStream is = getClass().getResourceAsStream("cacerts");
|
||||
keyStore.load(is, defaultPassword);
|
||||
return keyStore;
|
||||
return loadFallbackStore(defaultPassword);
|
||||
}
|
||||
}
|
||||
|
||||
private KeyStore loadFallbackStore(char[] defaultPassword) throws KeyStoreException, IOException, NoSuchAlgorithmException, CertificateException {
|
||||
KeyStore keyStore = KeyStore.getInstance("JKS");
|
||||
InputStream is = getClass().getResourceAsStream("cacerts");
|
||||
keyStore.load(is, defaultPassword);
|
||||
return keyStore;
|
||||
}
|
||||
|
||||
private void parsePaymentRequest(Protos.PaymentRequest request) throws PaymentRequestException {
|
||||
try {
|
||||
if (request == null)
|
||||
|
@ -20,9 +20,14 @@ import com.google.bitcoin.protocols.payments.PaymentRequestException;
|
||||
import com.google.bitcoin.protocols.payments.PaymentSession;
|
||||
import com.google.bitcoin.uri.BitcoinURI;
|
||||
import com.google.bitcoin.uri.BitcoinURIParseException;
|
||||
import org.bitcoin.protocols.payments.Protos;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.Date;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
@ -42,7 +47,12 @@ public class PaymentProtocol {
|
||||
try {
|
||||
URI uri = new URI(arg);
|
||||
PaymentSession session;
|
||||
if (uri.getScheme().equals("http")) {
|
||||
if (arg.startsWith("/")) {
|
||||
FileInputStream stream = new FileInputStream(arg);
|
||||
Protos.PaymentRequest request = Protos.PaymentRequest.parseFrom(stream);
|
||||
stream.close();
|
||||
session = new PaymentSession(request);
|
||||
} else if (uri.getScheme().equals("http")) {
|
||||
session = PaymentSession.createFromUrl(arg).get();
|
||||
} else if (uri.getScheme().equals("bitcoin")) {
|
||||
BitcoinURI bcuri = new BitcoinURI(arg);
|
||||
@ -75,13 +85,24 @@ public class PaymentProtocol {
|
||||
System.err.println("Could not parse URI: " + e.getMessage());
|
||||
} catch (BitcoinURIParseException e) {
|
||||
System.err.println("Could not parse URI: " + e.getMessage());
|
||||
} catch (PaymentRequestException.PkiVerificationException e) {
|
||||
System.err.println(e.getMessage());
|
||||
if (e.certificates != null) {
|
||||
for (X509Certificate certificate : e.certificates) {
|
||||
System.err.println(" " + certificate);
|
||||
}
|
||||
}
|
||||
} catch (PaymentRequestException e) {
|
||||
System.err.println("Could not handle payment URL: " + e.getMessage());
|
||||
System.err.println("Could not handle payment request: " + e.getMessage());
|
||||
} catch (InterruptedException e) {
|
||||
System.err.println("Interrupted whilst processing/downloading.");
|
||||
} catch (ExecutionException e) {
|
||||
System.err.println("Failed whilst retrieving payment URL: " + e.getMessage());
|
||||
e.printStackTrace();
|
||||
} catch (FileNotFoundException e) {
|
||||
System.err.println(e.getMessage());
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user