Use APNs signing keys instead of expiring certificates.
This commit is contained in:
parent
001a9310c3
commit
b1d11d4f69
|
@ -82,9 +82,11 @@ database: # Postgresql database configuration
|
|||
url:
|
||||
|
||||
apn: # Apple Push Notifications configuration
|
||||
sandbox: true
|
||||
bundleId:
|
||||
pushCertificate:
|
||||
pushKey:
|
||||
keyId:
|
||||
teamId:
|
||||
signingKey:
|
||||
|
||||
gcm: # GCM Configuration
|
||||
senderId:
|
||||
|
|
|
@ -24,11 +24,15 @@ public class ApnConfiguration {
|
|||
|
||||
@NotEmpty
|
||||
@JsonProperty
|
||||
private String pushCertificate;
|
||||
private String teamId;
|
||||
|
||||
@NotEmpty
|
||||
@JsonProperty
|
||||
private String pushKey;
|
||||
private String keyId;
|
||||
|
||||
@NotEmpty
|
||||
@JsonProperty
|
||||
private String signingKey;
|
||||
|
||||
@NotEmpty
|
||||
@JsonProperty
|
||||
|
@ -37,12 +41,16 @@ public class ApnConfiguration {
|
|||
@JsonProperty
|
||||
private boolean sandbox = false;
|
||||
|
||||
public String getPushCertificate() {
|
||||
return pushCertificate;
|
||||
public String getTeamId() {
|
||||
return teamId;
|
||||
}
|
||||
|
||||
public String getPushKey() {
|
||||
return pushKey;
|
||||
public String getKeyId() {
|
||||
return keyId;
|
||||
}
|
||||
|
||||
public String getSigningKey() {
|
||||
return signingKey;
|
||||
}
|
||||
|
||||
public String getBundleId() {
|
||||
|
|
|
@ -35,6 +35,8 @@ import org.whispersystems.textsecuregcm.util.Constants;
|
|||
|
||||
import javax.annotation.Nullable;
|
||||
import java.io.IOException;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.Date;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
|
@ -61,13 +63,14 @@ public class APNSender implements Managed {
|
|||
private final RetryingApnsClient apnsClient;
|
||||
|
||||
public APNSender(AccountsManager accountsManager, ApnConfiguration configuration)
|
||||
throws IOException
|
||||
throws IOException, NoSuchAlgorithmException, InvalidKeyException
|
||||
{
|
||||
this.accountsManager = accountsManager;
|
||||
this.bundleId = configuration.getBundleId();
|
||||
this.sandbox = configuration.isSandboxEnabled();
|
||||
this.apnsClient = new RetryingApnsClient(configuration.getPushCertificate(),
|
||||
configuration.getPushKey(),
|
||||
this.apnsClient = new RetryingApnsClient(configuration.getSigningKey(),
|
||||
configuration.getTeamId(),
|
||||
configuration.getKeyId(),
|
||||
sandbox);
|
||||
}
|
||||
|
||||
|
|
|
@ -7,28 +7,26 @@ import com.eatthepath.pushy.apns.ApnsClient;
|
|||
import com.eatthepath.pushy.apns.ApnsClientBuilder;
|
||||
import com.eatthepath.pushy.apns.DeliveryPriority;
|
||||
import com.eatthepath.pushy.apns.PushNotificationResponse;
|
||||
import com.eatthepath.pushy.apns.auth.ApnsSigningKey;
|
||||
import com.eatthepath.pushy.apns.metrics.dropwizard.DropwizardApnsClientMetricsListener;
|
||||
import com.eatthepath.pushy.apns.util.SimpleApnsPushNotification;
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
import com.google.common.util.concurrent.SettableFuture;
|
||||
import org.bouncycastle.openssl.PEMReader;
|
||||
import io.netty.util.concurrent.GenericFutureListener;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.whispersystems.textsecuregcm.util.Constants;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.security.KeyPair;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
import static com.codahale.metrics.MetricRegistry.name;
|
||||
import io.netty.util.concurrent.GenericFutureListener;
|
||||
|
||||
public class RetryingApnsClient {
|
||||
|
||||
|
@ -36,8 +34,8 @@ public class RetryingApnsClient {
|
|||
|
||||
private final ApnsClient apnsClient;
|
||||
|
||||
RetryingApnsClient(String apnCertificate, String apnKey, boolean sandbox)
|
||||
throws IOException
|
||||
RetryingApnsClient(String apnSigningKey, String teamId, String keyId, boolean sandbox)
|
||||
throws IOException, InvalidKeyException, NoSuchAlgorithmException
|
||||
{
|
||||
MetricRegistry metricRegistry = SharedMetricRegistries.getOrCreate(Constants.METRICS_NAME);
|
||||
DropwizardApnsClientMetricsListener metricsListener = new DropwizardApnsClientMetricsListener();
|
||||
|
@ -46,8 +44,7 @@ public class RetryingApnsClient {
|
|||
metricRegistry.register(name(getClass(), entry.getKey()), entry.getValue());
|
||||
}
|
||||
|
||||
this.apnsClient = new ApnsClientBuilder().setClientCredentials(initializeCertificate(apnCertificate),
|
||||
initializePrivateKey(apnKey), null)
|
||||
this.apnsClient = new ApnsClientBuilder().setSigningKey(ApnsSigningKey.loadFromInputStream(new ByteArrayInputStream(apnSigningKey.getBytes()), teamId, keyId))
|
||||
.setMetricsListener(metricsListener)
|
||||
.setApnsServer(sandbox ? ApnsClientBuilder.DEVELOPMENT_APNS_HOST : ApnsClientBuilder.PRODUCTION_APNS_HOST)
|
||||
.build();
|
||||
|
@ -71,16 +68,6 @@ public class RetryingApnsClient {
|
|||
apnsClient.close();
|
||||
}
|
||||
|
||||
private static X509Certificate initializeCertificate(String pemCertificate) throws IOException {
|
||||
PEMReader reader = new PEMReader(new InputStreamReader(new ByteArrayInputStream(pemCertificate.getBytes())));
|
||||
return (X509Certificate) reader.readObject();
|
||||
}
|
||||
|
||||
private static PrivateKey initializePrivateKey(String pemKey) throws IOException {
|
||||
PEMReader reader = new PEMReader(new InputStreamReader(new ByteArrayInputStream(pemKey.getBytes())));
|
||||
return ((KeyPair) reader.readObject()).getPrivate();
|
||||
}
|
||||
|
||||
private static final class ResponseHandler implements GenericFutureListener<io.netty.util.concurrent.Future<PushNotificationResponse<SimpleApnsPushNotification>>> {
|
||||
|
||||
private final SettableFuture<ApnResult> future;
|
||||
|
|
Loading…
Reference in New Issue