diff --git a/pushy/src/main/java/com/eatthepath/pushy/apns/ApnsClientBuilder.java b/pushy/src/main/java/com/eatthepath/pushy/apns/ApnsClientBuilder.java index 3ce5fb7b3..b935f83e4 100644 --- a/pushy/src/main/java/com/eatthepath/pushy/apns/ApnsClientBuilder.java +++ b/pushy/src/main/java/com/eatthepath/pushy/apns/ApnsClientBuilder.java @@ -241,6 +241,24 @@ public ApnsClientBuilder setClientCredentials(final InputStream p12InputStream, return this.setClientCredentials(x509Certificate, privateKey, p12Password); } + /** + *

Sets the TLS credentials for the client under construction. Clients constructed with TLS credentials will use + * TLS-based authentication when sending push notifications. This method assumes that the given private key does + * not require a password.

+ * + *

Clients may not have both TLS credentials and a signing key.

+ * + * @param clientCertificate the certificate to be used to identify the client to the APNs server + * @param privateKey the private key for the client certificate + * + * @return a reference to this builder + * + * @since 0.16 + */ + public ApnsClientBuilder setClientCredentials(final X509Certificate clientCertificate, final PrivateKey privateKey) { + return this.setClientCredentials(clientCertificate, privateKey, null); + } + /** *

Sets the TLS credentials for the client under construction. Clients constructed with TLS credentials will use * TLS-based authentication when sending push notifications.

diff --git a/pushy/src/main/java/com/eatthepath/pushy/apns/server/BaseHttp2ServerBuilder.java b/pushy/src/main/java/com/eatthepath/pushy/apns/server/BaseHttp2ServerBuilder.java index 5efd4e0e4..05eea2f18 100644 --- a/pushy/src/main/java/com/eatthepath/pushy/apns/server/BaseHttp2ServerBuilder.java +++ b/pushy/src/main/java/com/eatthepath/pushy/apns/server/BaseHttp2ServerBuilder.java @@ -125,6 +125,21 @@ public BaseHttp2ServerBuilder setServerCredentials(final InputStream certific return this; } + /** + *

Sets the credentials for the server under construction. This method assumes that the given private key does + * not require a password.

+ * + * @param certificates a certificate chain including the server's own certificate + * @param privateKey the private key for the server's certificate + * + * @return a reference to this builder + * + * @since 0.16 + */ + public BaseHttp2ServerBuilder setServerCredentials(final X509Certificate[] certificates, final PrivateKey privateKey) { + return this.setServerCredentials(certificates, privateKey, null); + } + /** *

Sets the credentials for the server under construction.

* diff --git a/pushy/src/main/java/com/eatthepath/pushy/apns/server/BenchmarkApnsServerBuilder.java b/pushy/src/main/java/com/eatthepath/pushy/apns/server/BenchmarkApnsServerBuilder.java index 72ab6c2e7..f506391f2 100644 --- a/pushy/src/main/java/com/eatthepath/pushy/apns/server/BenchmarkApnsServerBuilder.java +++ b/pushy/src/main/java/com/eatthepath/pushy/apns/server/BenchmarkApnsServerBuilder.java @@ -57,6 +57,12 @@ public BenchmarkApnsServerBuilder setServerCredentials(final InputStream certifi return this; } + @Override + public BenchmarkApnsServerBuilder setServerCredentials(final X509Certificate[] certificates, final PrivateKey privateKey) { + super.setServerCredentials(certificates, privateKey); + return this; + } + @Override public BenchmarkApnsServerBuilder setServerCredentials(final X509Certificate[] certificates, final PrivateKey privateKey, final String privateKeyPassword) { super.setServerCredentials(certificates, privateKey, privateKeyPassword); diff --git a/pushy/src/main/java/com/eatthepath/pushy/apns/server/MockApnsServerBuilder.java b/pushy/src/main/java/com/eatthepath/pushy/apns/server/MockApnsServerBuilder.java index 35259d417..ac24a2740 100644 --- a/pushy/src/main/java/com/eatthepath/pushy/apns/server/MockApnsServerBuilder.java +++ b/pushy/src/main/java/com/eatthepath/pushy/apns/server/MockApnsServerBuilder.java @@ -62,6 +62,12 @@ public MockApnsServerBuilder setServerCredentials(final InputStream certificateP return this; } + @Override + public MockApnsServerBuilder setServerCredentials(final X509Certificate[] certificates, final PrivateKey privateKey) { + super.setServerCredentials(certificates, privateKey); + return this; + } + @Override public MockApnsServerBuilder setServerCredentials(final X509Certificate[] certificates, final PrivateKey privateKey, final String privateKeyPassword) { super.setServerCredentials(certificates, privateKey, privateKeyPassword); diff --git a/pushy/src/test/java/com/eatthepath/pushy/apns/ApnsClientBuilderTest.java b/pushy/src/test/java/com/eatthepath/pushy/apns/ApnsClientBuilderTest.java index da606a97e..4df34a2f5 100644 --- a/pushy/src/test/java/com/eatthepath/pushy/apns/ApnsClientBuilderTest.java +++ b/pushy/src/test/java/com/eatthepath/pushy/apns/ApnsClientBuilderTest.java @@ -107,6 +107,24 @@ void testBuildClientWithCertificateAndPasswordProtectedKey() throws Exception { } } + @Test + void testBuildClientWithCertificateAndUnprotectedKeyNoPassword() throws Exception { + // We DO need a password to unlock the keystore, but the key itself should be unprotected + try (final InputStream p12InputStream = this.getClass().getResourceAsStream(SINGLE_TOPIC_CLIENT_KEYSTORE_UNPROTECTED_FILENAME)) { + + final PrivateKeyEntry privateKeyEntry = + P12Util.getFirstPrivateKeyEntryFromP12InputStream(p12InputStream, KEYSTORE_PASSWORD); + + final ApnsClient client = new ApnsClientBuilder() + .setApnsServer(ApnsClientBuilder.PRODUCTION_APNS_HOST) + .setEventLoopGroup(EVENT_LOOP_GROUP) + .setClientCredentials((X509Certificate) privateKeyEntry.getCertificate(), privateKeyEntry.getPrivateKey()) + .build(); + + client.close().get(); + } + } + @Test void testBuildClientWithCertificateAndUnprotectedKey() throws Exception { // We DO need a password to unlock the keystore, but the key itself should be unprotected diff --git a/pushy/src/test/java/com/eatthepath/pushy/apns/server/MockApnsServerBuilderTest.java b/pushy/src/test/java/com/eatthepath/pushy/apns/server/MockApnsServerBuilderTest.java index 2c30b2a6d..99391f1bf 100644 --- a/pushy/src/test/java/com/eatthepath/pushy/apns/server/MockApnsServerBuilderTest.java +++ b/pushy/src/test/java/com/eatthepath/pushy/apns/server/MockApnsServerBuilderTest.java @@ -78,7 +78,7 @@ void testSetServerCredentialsX509CertificateArrayPrivateKeyString() throws Excep // We're happy here as long as nothing explodes new MockApnsServerBuilder() - .setServerCredentials(new X509Certificate[] { (X509Certificate) privateKeyEntry.getCertificate() }, privateKeyEntry.getPrivateKey(), null) + .setServerCredentials(new X509Certificate[] { (X509Certificate) privateKeyEntry.getCertificate() }, privateKeyEntry.getPrivateKey()) .setHandlerFactory(new AcceptAllPushNotificationHandlerFactory()) .build(); }