From e7eec49671e27ecd68ab51a572fe37eb82b9cf16 Mon Sep 17 00:00:00 2001 From: Andreas Schildbach Date: Sat, 29 Mar 2014 14:44:34 +0100 Subject: [PATCH] Extract getDisplayNameFromCertificate() into new X509Utils class. Also joins PkiVerificationData.name and .orgName into one .displayName. Adds tests using client/smime certificates of mine. --- .../protocols/payments/PaymentSession.java | 69 ++++--------------- .../bitcoin/protocols/payments/X509Utils.java | 67 ++++++++++++++++++ .../payments/PaymentSessionTest.java | 4 +- .../protocols/payments/X509UtilsTest.java | 40 +++++++++++ .../protocols/payments/comodo-smime.crt | 30 ++++++++ .../protocols/payments/startssl-client.crt | 41 +++++++++++ .../protocols/payments/startssl-smime.crt | 40 +++++++++++ .../google/bitcoin/tools/PaymentProtocol.java | 2 +- .../com/google/bitcoin/tools/WalletTool.java | 4 +- 9 files changed, 235 insertions(+), 62 deletions(-) create mode 100644 core/src/main/java/com/google/bitcoin/protocols/payments/X509Utils.java create mode 100644 core/src/test/java/com/google/bitcoin/protocols/payments/X509UtilsTest.java create mode 100644 core/src/test/resources/com/google/bitcoin/protocols/payments/comodo-smime.crt create mode 100644 core/src/test/resources/com/google/bitcoin/protocols/payments/startssl-client.crt create mode 100644 core/src/test/resources/com/google/bitcoin/protocols/payments/startssl-smime.crt diff --git a/core/src/main/java/com/google/bitcoin/protocols/payments/PaymentSession.java b/core/src/main/java/com/google/bitcoin/protocols/payments/PaymentSession.java index 0df55dae..53121307 100644 --- a/core/src/main/java/com/google/bitcoin/protocols/payments/PaymentSession.java +++ b/core/src/main/java/com/google/bitcoin/protocols/payments/PaymentSession.java @@ -394,9 +394,7 @@ public class PaymentSession { */ public static class PkiVerificationData { /** Display name of the payment requestor, could be a domain name, email address, legal name, etc */ - public final String name; - /** The "org" part of the payment requestors ID. */ - public final String orgName; + public final String displayName; /** SSL public key that was used to sign. */ public final PublicKey merchantSigningKey; /** Object representing the CA that verified the merchant's ID */ @@ -404,34 +402,15 @@ public class PaymentSession { /** String representing the display name of the CA that verified the merchant's ID */ public final String rootAuthorityName; - private PkiVerificationData(@Nullable String name, @Nullable String orgName, PublicKey merchantSigningKey, + private PkiVerificationData(@Nullable String displayName, PublicKey merchantSigningKey, TrustAnchor rootAuthority) throws PaymentRequestException.PkiVerificationException { - this.name = name; - this.orgName = orgName; - this.merchantSigningKey = merchantSigningKey; - this.rootAuthority = rootAuthority; - this.rootAuthorityName = getNameFromCert(rootAuthority); - } - - private @Nullable String getNameFromCert(TrustAnchor rootAuthority) throws PaymentRequestException.PkiVerificationException { - org.spongycastle.asn1.x500.X500Name name = new X500Name(rootAuthority.getTrustedCert().getSubjectX500Principal().getName()); - String commonName = null, org = null, location = null, country = null; - for (RDN rdn : name.getRDNs()) { - AttributeTypeAndValue pair = rdn.getFirst(); - String val = ((ASN1String)pair.getValue()).getString(); - if (pair.getType().equals(RFC4519Style.cn)) - commonName = val; - else if (pair.getType().equals(RFC4519Style.o)) - org = val; - else if (pair.getType().equals(RFC4519Style.l)) - location = val; - else if (pair.getType().equals(RFC4519Style.c)) - country = val; - } - if (org != null) { - return Joiner.on(", ").skipNulls().join(org, location, country); - } else { - return commonName; + try { + this.displayName = displayName; + this.merchantSigningKey = merchantSigningKey; + this.rootAuthority = rootAuthority; + this.rootAuthorityName = X509Utils.getDisplayNameFromCertificate(rootAuthority.getTrustedCert()); + } catch (CertificateParsingException x) { + throw new PaymentRequestException.PkiVerificationException(x); } } } @@ -493,33 +472,11 @@ public class PaymentSession { // Signature verifies, get the names from the identity we just verified for presentation to the user. final X509Certificate cert = certs.get(0); - X500Principal principal = cert.getSubjectX500Principal(); - // At this point the Java crypto API falls flat on its face and dies - there's no clean way to get the - // different parts of the certificate name except for parsing the string. That's hard because of various - // custom escaping rules and the usual crap. So, use Bouncy Castle to re-parse the string into binary form - // again and then look for the names we want. Fail! - org.spongycastle.asn1.x500.X500Name name = new X500Name(principal.getName()); - String entityName = null, orgName = null; - for (RDN rdn : name.getRDNs()) { - AttributeTypeAndValue pair = rdn.getFirst(); - if (pair.getType().equals(RFC4519Style.cn)) - entityName = ((ASN1String)pair.getValue()).getString(); - else if (pair.getType().equals(RFC4519Style.o)) - orgName = ((ASN1String)pair.getValue()).getString(); - } - if (entityName == null && orgName == null) { - // This cert might not be an SSL cert. Just grab the first "subject alt name" if present, e.g. for - // S/MIME certs. - final Iterator> it = cert.getSubjectAlternativeNames().iterator(); - List list; - // email addresses have a type code of one. - if (it.hasNext() && (list = it.next()) != null && (Integer) list.get(0) == 1) - entityName = (String) list.get(1); - if (entityName == null) - throw new PaymentRequestException.PkiVerificationException("Could not extract name from certificate"); - } + String displayName = X509Utils.getDisplayNameFromCertificate(cert); + if (displayName == null) + throw new PaymentRequestException.PkiVerificationException("Could not extract name from certificate"); // Everything is peachy. Return some useful data to the caller. - PkiVerificationData data = new PkiVerificationData(entityName, orgName, publicKey, result.getTrustAnchor()); + PkiVerificationData data = new PkiVerificationData(displayName, publicKey, result.getTrustAnchor()); // Cache the result so we don't have to re-verify if this method is called again. pkiVerificationData = data; return data; diff --git a/core/src/main/java/com/google/bitcoin/protocols/payments/X509Utils.java b/core/src/main/java/com/google/bitcoin/protocols/payments/X509Utils.java new file mode 100644 index 00000000..13b86df4 --- /dev/null +++ b/core/src/main/java/com/google/bitcoin/protocols/payments/X509Utils.java @@ -0,0 +1,67 @@ +/** + * Copyright 2014 Andreas Schildbach + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.bitcoin.protocols.payments; + +import java.security.cert.CertificateParsingException; +import java.security.cert.X509Certificate; +import java.util.Collection; +import java.util.List; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +import org.spongycastle.asn1.ASN1ObjectIdentifier; +import org.spongycastle.asn1.ASN1String; +import org.spongycastle.asn1.x500.AttributeTypeAndValue; +import org.spongycastle.asn1.x500.RDN; +import org.spongycastle.asn1.x500.X500Name; +import org.spongycastle.asn1.x500.style.RFC4519Style; + +public class X509Utils { + + public static @Nullable String getDisplayNameFromCertificate(@Nonnull X509Certificate certificate) throws CertificateParsingException { + X500Name name = new X500Name(certificate.getSubjectX500Principal().getName()); + String commonName = null, org = null, location = null, country = null; + for (RDN rdn : name.getRDNs()) { + AttributeTypeAndValue pair = rdn.getFirst(); + String val = ((ASN1String) pair.getValue()).getString(); + ASN1ObjectIdentifier type = pair.getType(); + if (type.equals(RFC4519Style.cn)) + commonName = val; + else if (type.equals(RFC4519Style.o)) + org = val; + else if (type.equals(RFC4519Style.l)) + location = val; + else if (type.equals(RFC4519Style.c)) + country = val; + } + final Collection> subjectAlternativeNames = certificate.getSubjectAlternativeNames(); + String altName = null; + if (subjectAlternativeNames != null) + for (final List subjectAlternativeName : subjectAlternativeNames) + if ((Integer) subjectAlternativeName.get(0) == 1) // rfc822name + altName = (String) subjectAlternativeName.get(1); + + if (org != null) { + return org; + } else if (commonName != null) { + return commonName; + } else { + return altName; + } + } +} diff --git a/core/src/test/java/com/google/bitcoin/protocols/payments/PaymentSessionTest.java b/core/src/test/java/com/google/bitcoin/protocols/payments/PaymentSessionTest.java index 6963e5a3..c2d207f8 100644 --- a/core/src/test/java/com/google/bitcoin/protocols/payments/PaymentSessionTest.java +++ b/core/src/test/java/com/google/bitcoin/protocols/payments/PaymentSessionTest.java @@ -125,8 +125,8 @@ public class PaymentSessionTest { Protos.PaymentRequest paymentRequest = Protos.PaymentRequest.newBuilder().mergeFrom(in).build(); MockPaymentSession paymentSession = new MockPaymentSession(paymentRequest); PaymentSession.PkiVerificationData pkiData = paymentSession.verifyPki(); - assertEquals("www.bitcoincore.org", pkiData.name); - assertEquals("The USERTRUST Network, Salt Lake City, US", pkiData.rootAuthorityName); + assertEquals("www.bitcoincore.org", pkiData.displayName); + assertEquals("The USERTRUST Network", pkiData.rootAuthorityName); } private Protos.PaymentRequest newSimplePaymentRequest() { diff --git a/core/src/test/java/com/google/bitcoin/protocols/payments/X509UtilsTest.java b/core/src/test/java/com/google/bitcoin/protocols/payments/X509UtilsTest.java new file mode 100644 index 00000000..abdf2498 --- /dev/null +++ b/core/src/test/java/com/google/bitcoin/protocols/payments/X509UtilsTest.java @@ -0,0 +1,40 @@ +/** + * Copyright 2014 Andreas Schildbach + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.bitcoin.protocols.payments; + +import static org.junit.Assert.assertEquals; + +import java.security.cert.CertificateFactory; +import java.security.cert.X509Certificate; + +import org.junit.Test; + +public class X509UtilsTest { + + @Test + public void testDisplayName() throws Exception { + CertificateFactory cf = CertificateFactory.getInstance("X.509"); + + X509Certificate clientCert = (X509Certificate) cf.generateCertificate(getClass().getResourceAsStream( + "startssl-client.crt")); + assertEquals("Andreas Schildbach", X509Utils.getDisplayNameFromCertificate(clientCert)); + + X509Certificate comodoCert = (X509Certificate) cf.generateCertificate(getClass().getResourceAsStream( + "comodo-smime.crt")); + assertEquals("comodo.com@schildbach.de", X509Utils.getDisplayNameFromCertificate(comodoCert)); + } +} diff --git a/core/src/test/resources/com/google/bitcoin/protocols/payments/comodo-smime.crt b/core/src/test/resources/com/google/bitcoin/protocols/payments/comodo-smime.crt new file mode 100644 index 00000000..8f6d782a --- /dev/null +++ b/core/src/test/resources/com/google/bitcoin/protocols/payments/comodo-smime.crt @@ -0,0 +1,30 @@ +-----BEGIN CERTIFICATE----- +MIIFMTCCBBmgAwIBAgIQV2O4gJQ5NHgn/PPvDsU1djANBgkqhkiG9w0BAQUFADCB +kzELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G +A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxOTA3BgNV +BAMTMENPTU9ETyBDbGllbnQgQXV0aGVudGljYXRpb24gYW5kIFNlY3VyZSBFbWFp +bCBDQTAeFw0xNDAzMjkwMDAwMDBaFw0xNTAzMjkyMzU5NTlaMCkxJzAlBgkqhkiG +9w0BCQEWGGNvbW9kby5jb21Ac2NoaWxkYmFjaC5kZTCCASIwDQYJKoZIhvcNAQEB +BQADggEPADCCAQoCggEBAM61nbZo3ZN0Ojzn7UzoHBf07ZyTDm3KnwK4BdLKLgNS +NbGAJtgaYN91qKRbXf97VAFIN6FGhoXT+7MXSzlHgQHn7RkForMyREsD6F32TtyV +ZY9RuMGWjmPtABPRgeCVfNJNh9Hu87Uhhkj3Ma+H//ykfkJdDiOyBWIOJdjBFSZZ +M6bsZnyH8JCHqmxvK2qHpk+qNqpsNOZV83GYPA2gTFWd1AHjo5+A7W1Bo/qyJMrz +tpab0i+ieJPJdi6eJkMt3+nfr57Q2o4A3ZxH0Axq2D1a2dElhMK/JQilh2D+IDUp +VjoKkHgV9yji9UGOc3VHq+Sx8bNTumL7OFLCFYky9J8CAwEAAaOCAegwggHkMB8G +A1UdIwQYMBaAFHoTTgB0W8Z4Y2QnwS/ioFu8ecV7MB0GA1UdDgQWBBRWUNGbH8V3 +av0ESrIUwnvmq4aEEDAOBgNVHQ8BAf8EBAMCBaAwDAYDVR0TAQH/BAIwADAgBgNV +HSUEGTAXBggrBgEFBQcDBAYLKwYBBAGyMQEDBQIwEQYJYIZIAYb4QgEBBAQDAgUg +MEYGA1UdIAQ/MD0wOwYMKwYBBAGyMQECAQEBMCswKQYIKwYBBQUHAgEWHWh0dHBz +Oi8vc2VjdXJlLmNvbW9kby5uZXQvQ1BTMFcGA1UdHwRQME4wTKBKoEiGRmh0dHA6 +Ly9jcmwuY29tb2RvY2EuY29tL0NPTU9ET0NsaWVudEF1dGhlbnRpY2F0aW9uYW5k +U2VjdXJlRW1haWxDQS5jcmwwgYgGCCsGAQUFBwEBBHwwejBSBggrBgEFBQcwAoZG +aHR0cDovL2NydC5jb21vZG9jYS5jb20vQ09NT0RPQ2xpZW50QXV0aGVudGljYXRp +b25hbmRTZWN1cmVFbWFpbENBLmNydDAkBggrBgEFBQcwAYYYaHR0cDovL29jc3Au +Y29tb2RvY2EuY29tMCMGA1UdEQQcMBqBGGNvbW9kby5jb21Ac2NoaWxkYmFjaC5k +ZTANBgkqhkiG9w0BAQUFAAOCAQEAMFhmP1Zy16m5L9gaGCDy847tJI3btBFFZMu/ +MMqamC5515QayLfwf9K2nmu1W63nehEAKqNw+PR1xTYnhPT4fopw5zFndiNg0L5u +blEbRgSdQYBh1I2dkzzPRDRJig4LfxVzRzL66FbllLEiJ6oR/XgdsH+JFgyjhk3Y +uJt+29sXoZ+ZR29d7l07OikQGI0HWCmp/UiwBcQ4dcTrDB72JYLHyli+OTAkcu9I +rBpsIbWJq+7NjaQ/8CJjvQ2neTgDS1Dq5DzMqqRlhxQwRl4dhfCSCcF81Vf0as4S +vVDNR8vJ9puGlYyGVJHhQ6mEoFEIvpetS7E9ELHnybSC9ev8CA== +-----END CERTIFICATE----- diff --git a/core/src/test/resources/com/google/bitcoin/protocols/payments/startssl-client.crt b/core/src/test/resources/com/google/bitcoin/protocols/payments/startssl-client.crt new file mode 100644 index 00000000..44bed530 --- /dev/null +++ b/core/src/test/resources/com/google/bitcoin/protocols/payments/startssl-client.crt @@ -0,0 +1,41 @@ +-----BEGIN CERTIFICATE----- +MIIHPjCCBiagAwIBAgICH8wwDQYJKoZIhvcNAQEFBQAwgYwxCzAJBgNVBAYTAklM +MRYwFAYDVQQKEw1TdGFydENvbSBMdGQuMSswKQYDVQQLEyJTZWN1cmUgRGlnaXRh +bCBDZXJ0aWZpY2F0ZSBTaWduaW5nMTgwNgYDVQQDEy9TdGFydENvbSBDbGFzcyAx +IFByaW1hcnkgSW50ZXJtZWRpYXRlIENsaWVudCBDQTAeFw0wODA2MjIyMzA4MTJa +Fw0wOTA2MjIyMzA4MTJaMIHEMQswCQYDVQQGEwJERTEPMA0GA1UECBMGQmF5ZXJu +MREwDwYDVQQHEwhNdWVuY2hlbjEbMBkGA1UEChMSQW5kcmVhcyBTY2hpbGRiYWNo +MR4wHAYDVQQLExVQZXJzb25hIG5vdCB2YWxpZGF0ZWQxKTAnBgNVBAMTIFN0YXJ0 +Q29tIEZyZWUgQ2VydGlmaWNhdGUgTWVtYmVyMSkwJwYJKoZIhvcNAQkBFhpzdGFy +dHNzbC5jb21Ac2NoaWxkYmFjaC5kZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC +AQoCggEBAOhtSryPHR3gB5E48JZS9y8R3A9I2gRGGon+kRLNh+LCAJJ1hm28Lr41 +leH0uApWs1WP//qzkXaFUoLlilu/XzkDU48J6HCeUq+7zkxFhq7UxK2lq7J1P8fH +tbKYSBWMfzZuVmwhrbaurggfCmq/o5/angbhN7Pn+aV1aPegjAKd8n94HVvVgzkp +DDYTA5vFbX/3241MIeKRU5InYw9KzXAC1aE0BYVM21f5Z/UQ+V4PEfXrSH9OHPVW +3GWasmjzR9h+/u1omJzejkXY6Ygd15tnmatqMoxRRVMWhWS9Hg7D+AgeiZNlEQZV +NTZxIiPA8618x51Wlq0XAiV5UvkMImECAwEAAaOCA24wggNqMAwGA1UdEwQFMAMC +AQAwCwYDVR0PBAQDAgSwMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcDBDAd +BgNVHQ4EFgQUeMIc15HHtjl2TDpGnc9X2UkUV2EwgagGA1UdIwSBoDCBnYAUU3Lt +kpzg2ssBXHx+ljVO8tS4UYKhgYGkfzB9MQswCQYDVQQGEwJJTDEWMBQGA1UEChMN +U3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNh +dGUgU2lnbmluZzEpMCcGA1UEAxMgU3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRo +b3JpdHmCAQ0wggFHBgNVHSAEggE+MIIBOjCCATYGCysGAQQBgbU3AQEFMIIBJTAu +BggrBgEFBQcCARYiaHR0cDovL3d3dy5zdGFydHNzbC5jb20vcG9saWN5LnBkZjA0 +BggrBgEFBQcCARYoaHR0cDovL3d3dy5zdGFydHNzbC5jb20vaW50ZXJtZWRpYXRl +LnBkZjCBvAYIKwYBBQUHAgIwga8wFBYNU3RhcnRDb20gTHRkLjADAgEBGoGWTGlt +aXRlZCBMaWFiaWxpdHksIHJlYWQgdGhlIHNlY3Rpb24gKkxlZ2FsIExpbWl0YXRp +b25zKiBvZiB0aGUgU3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgUG9s +aWN5IGF2YWlsYWJsZSBhdCBodHRwOi8vd3d3LnN0YXJ0c3NsLmNvbS9wb2xpY3ku +cGRmMGMGA1UdHwRcMFowK6ApoCeGJWh0dHA6Ly93d3cuc3RhcnRzc2wuY29tL2Ny +dHUxLWNybC5jcmwwK6ApoCeGJWh0dHA6Ly9jcmwuc3RhcnRzc2wuY29tL2NydHUx +LWNybC5jcmwwgY4GCCsGAQUFBwEBBIGBMH8wOQYIKwYBBQUHMAGGLWh0dHA6Ly9v +Y3NwLnN0YXJ0c3NsLmNvbS9zdWIvY2xhc3MxL2NsaWVudC9jYTBCBggrBgEFBQcw +AoY2aHR0cDovL3d3dy5zdGFydHNzbC5jb20vY2VydHMvc3ViLmNsYXNzMS5jbGll +bnQuY2EuY3J0MCMGA1UdEgQcMBqGGGh0dHA6Ly93d3cuc3RhcnRzc2wuY29tLzAN +BgkqhkiG9w0BAQUFAAOCAQEAIsKaduVCShmIKRsUCqTSeJSDIjgSdRiRmvDig+vT +NkRrfhZhtpkp03lfe71agFlaV6UWtFF2nrgFaoUmq2KxMnCD1gkQPQu01TqrDDwi ++dKFkh4tSGyj++BRCX4jpYgY7pDzh0Dtb261ovpzYB3e36mMO4AiLHby10VHir+k +AUI87JVffsgsKCEEEkywA//KcXqyVfgW3FgicNczCiwXdWCLJcnBAq8aundebdIH +hTFoWB/5BuRRCY2Je9XFR8vb1EUC5SuTL+wT0mGdx2T+qNskNtbZKyHLQSp9fCoD +yupR1THhr7iqF4zRI6r5r8tRuu8jr55NgN5ZA+LCisEJ7A== +-----END CERTIFICATE----- diff --git a/core/src/test/resources/com/google/bitcoin/protocols/payments/startssl-smime.crt b/core/src/test/resources/com/google/bitcoin/protocols/payments/startssl-smime.crt new file mode 100644 index 00000000..ac8ae271 --- /dev/null +++ b/core/src/test/resources/com/google/bitcoin/protocols/payments/startssl-smime.crt @@ -0,0 +1,40 @@ +-----BEGIN CERTIFICATE----- +MIIHFDCCBfygAwIBAgIDAILwMA0GCSqGSIb3DQEBBQUAMIGMMQswCQYDVQQGEwJJ +TDEWMBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0 +YWwgQ2VydGlmaWNhdGUgU2lnbmluZzE4MDYGA1UEAxMvU3RhcnRDb20gQ2xhc3Mg +MSBQcmltYXJ5IEludGVybWVkaWF0ZSBDbGllbnQgQ0EwHhcNMDkwNjA5MDAwMDAx +WhcNMTAwNjA5MjM1OTU5WjB2MR4wHAYDVQQKExVQZXJzb25hIE5vdCBWYWxpZGF0 +ZWQxKTAnBgNVBAMTIFN0YXJ0Q29tIEZyZWUgQ2VydGlmaWNhdGUgTWVtYmVyMSkw +JwYJKoZIhvcNAQkBFhpzdGFydHNzbC5jb21Ac2NoaWxkYmFjaC5kZTCCASIwDQYJ +KoZIhvcNAQEBBQADggEPADCCAQoCggEBALA4dtu1FlTbhZQ+M9pyTFte40zotk3J +fqvEkDpWLBz3orN4SkMAUDOgTWdvNm+PakX2tEsZGD+nnWzkO3NI8x5ZhrOF3HwW +zeCaYzaDjhhRw4G1K2FKVBHK6TUkZ/LoLimVMsV8AbsAWWlmxTCXB1vyoiOMISiK +rMFsRFAQdtB5wHVuZdtVnO1++yLfQo+ckuTT35RBztpcP63GkVyo0ucFC8DxNQOA ++k8cEIVrfsr9PrLUlhTx+P5jQAaURqcVf0IAR6bNV7WdJmli7yjlWeQm7ymh8YFE +6xsy16TO24GQWR5waBFRqGaJPqRnpAdhiUc+1nbNGuaOYYCD6kATVycCAwEAAaOC +A5IwggOOMAkGA1UdEwQCMAAwCwYDVR0PBAQDAgSwMB0GA1UdJQQWMBQGCCsGAQUF +BwMCBggrBgEFBQcDBDAdBgNVHQ4EFgQUY819Gv9zSrHpLGP3e9WbCJfzEgAwJQYD +VR0RBB4wHIEac3RhcnRzc2wuY29tQHNjaGlsZGJhY2guZGUwgagGA1UdIwSBoDCB +nYAUU3Ltkpzg2ssBXHx+ljVO8tS4UYKhgYGkfzB9MQswCQYDVQQGEwJJTDEWMBQG +A1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwgQ2Vy +dGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3RhcnRDb20gQ2VydGlmaWNhdGlv +biBBdXRob3JpdHmCAQ0wggFHBgNVHSAEggE+MIIBOjCCATYGCysGAQQBgbU3AQIA +MIIBJTAuBggrBgEFBQcCARYiaHR0cDovL3d3dy5zdGFydHNzbC5jb20vcG9saWN5 +LnBkZjA0BggrBgEFBQcCARYoaHR0cDovL3d3dy5zdGFydHNzbC5jb20vaW50ZXJt +ZWRpYXRlLnBkZjCBvAYIKwYBBQUHAgIwga8wFBYNU3RhcnRDb20gTHRkLjADAgEB +GoGWTGltaXRlZCBMaWFiaWxpdHksIHJlYWQgdGhlIHNlY3Rpb24gKkxlZ2FsIExp +bWl0YXRpb25zKiBvZiB0aGUgU3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3Jp +dHkgUG9saWN5IGF2YWlsYWJsZSBhdCBodHRwOi8vd3d3LnN0YXJ0c3NsLmNvbS9w +b2xpY3kucGRmMGMGA1UdHwRcMFowK6ApoCeGJWh0dHA6Ly93d3cuc3RhcnRzc2wu +Y29tL2NydHUxLWNybC5jcmwwK6ApoCeGJWh0dHA6Ly9jcmwuc3RhcnRzc2wuY29t +L2NydHUxLWNybC5jcmwwgY4GCCsGAQUFBwEBBIGBMH8wOQYIKwYBBQUHMAGGLWh0 +dHA6Ly9vY3NwLnN0YXJ0c3NsLmNvbS9zdWIvY2xhc3MxL2NsaWVudC9jYTBCBggr +BgEFBQcwAoY2aHR0cDovL3d3dy5zdGFydHNzbC5jb20vY2VydHMvc3ViLmNsYXNz +MS5jbGllbnQuY2EuY3J0MCMGA1UdEgQcMBqGGGh0dHA6Ly93d3cuc3RhcnRzc2wu +Y29tLzANBgkqhkiG9w0BAQUFAAOCAQEAaJgOEPjkRcKMVbbofA+GVlc1iMR+kJHk +bQNmojAmgDL1pXabFuNZqx7FVUBk7MQQOUaC1vd3RbyOE+AzdXaq7/pFk5/Zxalv +xn4gSA/wGHDB0oAi+efWQy7ZsskIOWkjg7tKqy0KCRlA6ZlQhL0aTFZe2X6fu/fI +eebFb6gQ3vhOwIgAGz7CZMjRBqPjiqpPrD/Uac2LORUdLw/wowTV1YBnNwsZGnzJ +/WquZB7n/yJjaSqhSL0s37AOg3TvXEXYS2GpoA02lQKfq3Lo86piAxSh7aJf7dpT +JMVnE6/+5FyjpP8Hpl8FARv1m51c9n788cDzS4/qFibKf9s6yt1/0A== +-----END CERTIFICATE----- diff --git a/tools/src/main/java/com/google/bitcoin/tools/PaymentProtocol.java b/tools/src/main/java/com/google/bitcoin/tools/PaymentProtocol.java index 14f1195a..b4437a5e 100644 --- a/tools/src/main/java/com/google/bitcoin/tools/PaymentProtocol.java +++ b/tools/src/main/java/com/google/bitcoin/tools/PaymentProtocol.java @@ -71,7 +71,7 @@ public class PaymentProtocol { format("Bitcoin payment request, version %d%nDate: %s%n", version, session.getDate())); PaymentSession.PkiVerificationData pki = session.verifyPki(); if (pki != null) { - output.append(format("Signed by: %s%nIdentity verified by: %s%n", pki.name, pki.rootAuthorityName)); + output.append(format("Signed by: %s%nIdentity verified by: %s%n", pki.displayName, pki.rootAuthorityName)); } if (session.getPaymentDetails().hasExpires()) { output.append(format("Expires: %s%n", new Date(session.getPaymentDetails().getExpires() * 1000))); diff --git a/tools/src/main/java/com/google/bitcoin/tools/WalletTool.java b/tools/src/main/java/com/google/bitcoin/tools/WalletTool.java index 2015aa62..97a3f7b2 100644 --- a/tools/src/main/java/com/google/bitcoin/tools/WalletTool.java +++ b/tools/src/main/java/com/google/bitcoin/tools/WalletTool.java @@ -536,9 +536,7 @@ public class WalletTool { System.out.println("Date: " + session.getDate()); System.out.println("Memo: " + session.getMemo()); if (session.pkiVerificationData != null) { - System.out.println("Pki-Verified Name: " + session.pkiVerificationData.name); - if (session.pkiVerificationData.orgName != null) - System.out.println("Pki-Verified Org: " + session.pkiVerificationData.orgName); + System.out.println("Pki-Verified Name: " + session.pkiVerificationData.displayName); System.out.println("PKI data verified by: " + session.pkiVerificationData.rootAuthorityName); } final Wallet.SendRequest req = session.getSendRequest();