Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rename Status to VerificationStatus #59

Merged
merged 1 commit into from
Dec 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,11 @@ public PublicKey verifyChain(String[] certificates, boolean performRevocationChe
parsedCertificates.add(certificateFactory.generateCertificate(derEncodedCert));
}
} catch (Exception e) {
throw new VerificationException(Status.INVALID_CERTIFICATE, e);
throw new VerificationException(VerificationStatus.INVALID_CERTIFICATE, e);
}

if (parsedCertificates.size() != EXPECTED_CHAIN_LENGTH) {
throw new VerificationException(Status.INVALID_CHAIN_LENGTH);
throw new VerificationException(VerificationStatus.INVALID_CHAIN_LENGTH);
}

try {
Expand All @@ -82,7 +82,7 @@ public PublicKey verifyChain(String[] certificates, boolean performRevocationChe
PKIXCertPathValidatorResult certPathValidatorResult = (PKIXCertPathValidatorResult) certPathValidator.validate(certPath, parameters);
return certPathValidatorResult.getPublicKey();
} catch (Exception e) {
throw new VerificationException(Status.INVALID_CHAIN, e);
throw new VerificationException(VerificationStatus.INVALID_CHAIN, e);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,10 @@ public SignedDataVerifier(Set<InputStream> rootCertificates, String bundleId, Lo
public JWSTransactionDecodedPayload verifyAndDecodeTransaction(String signedTransaction) throws VerificationException {
JWSTransactionDecodedPayload transaction = decodeSignedObject(signedTransaction, JWSTransactionDecodedPayload.class);
if (!bundleId.equals(transaction.getBundleId())) {
throw new VerificationException(Status.INVALID_APP_IDENTIFIER);
throw new VerificationException(VerificationStatus.INVALID_APP_IDENTIFIER);
}
if (!this.environment.equals(transaction.getEnvironment())) {
throw new VerificationException(Status.INVALID_ENVIRONMENT);
throw new VerificationException(VerificationStatus.INVALID_ENVIRONMENT);
}
return transaction;
}
Expand All @@ -85,7 +85,7 @@ public JWSTransactionDecodedPayload verifyAndDecodeTransaction(String signedTran
public JWSRenewalInfoDecodedPayload verifyAndDecodeRenewalInfo(String signedRenewalInfo) throws VerificationException {
JWSRenewalInfoDecodedPayload renewalInfo = decodeSignedObject(signedRenewalInfo, JWSRenewalInfoDecodedPayload.class);
if (!this.environment.equals(renewalInfo.getEnvironment())) {
throw new VerificationException(Status.INVALID_ENVIRONMENT);
throw new VerificationException(VerificationStatus.INVALID_ENVIRONMENT);
}
return renewalInfo;
}
Expand All @@ -103,10 +103,10 @@ public ResponseBodyV2DecodedPayload verifyAndDecodeNotification(String signedPay
Long appAppleId = notification.getData() != null ? notification.getData().getAppAppleId() : (notification.getSummary() != null ? notification.getSummary().getAppAppleId() : null);
String bundleId = notification.getData() != null ? notification.getData().getBundleId() : (notification.getSummary() != null ? notification.getSummary().getBundleId() : null);
if (!this.bundleId.equals(bundleId) || (this.environment.equals(Environment.PRODUCTION) && !this.appAppleId.equals(appAppleId))) {
throw new VerificationException(Status.INVALID_APP_IDENTIFIER);
throw new VerificationException(VerificationStatus.INVALID_APP_IDENTIFIER);
}
if (!this.environment.equals(notificationEnv)) {
throw new VerificationException(Status.INVALID_ENVIRONMENT);
throw new VerificationException(VerificationStatus.INVALID_ENVIRONMENT);
}
return notification;
}
Expand All @@ -121,10 +121,10 @@ public AppTransaction verifyAndDecodeAppTransaction(String signedAppTransaction)
AppTransaction appTransaction = decodeSignedObject(signedAppTransaction, AppTransaction.class);
Environment environment = appTransaction.getReceiptType();
if (!this.bundleId.equals(appTransaction.getBundleId()) || (this.environment.equals(Environment.PRODUCTION) && !this.appAppleId.equals(appTransaction.getAppAppleId()))) {
throw new VerificationException(Status.INVALID_APP_IDENTIFIER);
throw new VerificationException(VerificationStatus.INVALID_APP_IDENTIFIER);
}
if (!this.environment.equals(environment)) {
throw new VerificationException(Status.INVALID_ENVIRONMENT);
throw new VerificationException(VerificationStatus.INVALID_ENVIRONMENT);
}
return appTransaction;
}
Expand All @@ -139,21 +139,21 @@ protected <T extends DecodedSignedData> T decodeSignedObject(String signedObject
}
String[] x5cChain = unverifiedJWT.getHeaderClaim("x5c").asArray(String.class);
if (x5cChain == null) {
throw new VerificationException(Status.VERIFICATION_FAILURE, "x5c claim was null");
throw new VerificationException(VerificationStatus.VERIFICATION_FAILURE, "x5c claim was null");
}
T decodedData = parseJWTPayload(clazz, unverifiedJWT);
Date effectiveDate = this.enableOnlineChecks || decodedData.getSignedDate() == null ? new Date() : new Date(decodedData.getSignedDate());
PublicKey signingKey = chainVerifier.verifyChain(x5cChain, enableOnlineChecks, effectiveDate);
if ("ES256".equals(unverifiedJWT.getAlgorithm())) {
JWT.require(Algorithm.ECDSA256((ECPublicKey) signingKey)).build().verify(unverifiedJWT);
} else {
throw new VerificationException(Status.VERIFICATION_FAILURE, "Unrecognized JWT algorithm + " + unverifiedJWT.getAlgorithm());
throw new VerificationException(VerificationStatus.VERIFICATION_FAILURE, "Unrecognized JWT algorithm + " + unverifiedJWT.getAlgorithm());
}
return decodedData;
} catch (VerificationException e) {
throw e;
} catch (Exception e) {
throw new VerificationException(Status.VERIFICATION_FAILURE, e);
throw new VerificationException(VerificationStatus.VERIFICATION_FAILURE, e);
}
}

Expand All @@ -162,7 +162,7 @@ protected <T extends DecodedSignedData> T parseJWTPayload(Class<T> clazz, Decode
try {
return objectMapper.readValue(payload, clazz);
} catch (JsonProcessingException e) {
throw new VerificationException(Status.VERIFICATION_FAILURE, e);
throw new VerificationException(VerificationStatus.VERIFICATION_FAILURE, e);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,24 @@

public class VerificationException extends Exception {

private final Status status;
private final VerificationStatus status;

public VerificationException(Status status) {
public VerificationException(VerificationStatus status) {
super("Verification failed with status " + status);
this.status = status;
}

public VerificationException(Status status, String message) {
public VerificationException(VerificationStatus status, String message) {
super("Verification failed with status " + status + ". " + message);
this.status = status;
}

public VerificationException(Status status, Throwable cause) {
public VerificationException(VerificationStatus status, Throwable cause) {
super("Verification failed with status " + status, cause);
this.status = status;
}

public Status getStatus() {
public VerificationStatus getStatus() {
return this.status;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

package com.apple.itunes.storekit.verification;

public enum Status {
public enum VerificationStatus {
OK,
VERIFICATION_FAILURE,
INVALID_APP_IDENTIFIER,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ public void testValidChainInvalidIntermediateOIDWithoutOCSP() {
INTERMEDIATE_CA_INVALID_OID_BASE64_ENCODED,
LEAF_CERT_FOR_INTERMEDIATE_CA_INVALID_OID_BASE64_ENCODED
}, false, EFFECTIVE_DATE));
Assertions.assertEquals(Status.INVALID_CHAIN,exception.getStatus());
Assertions.assertEquals(VerificationStatus.INVALID_CHAIN,exception.getStatus());
Throwable cause = exception.getCause();
Assertions.assertInstanceOf(CertPathValidatorException.class, cause);
Assertions.assertTrue(cause.toString().contains("OID: 1.2.840.113635.100.6.2.1 was not found on the intermediate WWDR certificate"));
Expand All @@ -64,7 +64,7 @@ public void testValidChainInvalidLeafOIDWithoutOCSP() {
INTERMEDIATE_CA_BASE64_ENCODED,
ROOT_CA_BASE64_ENCODED
}, false, EFFECTIVE_DATE));
Assertions.assertEquals(Status.INVALID_CHAIN, exception.getStatus());
Assertions.assertEquals(VerificationStatus.INVALID_CHAIN, exception.getStatus());
Throwable cause = exception.getCause();
Assertions.assertInstanceOf(CertPathValidatorException.class, cause);
Assertions.assertTrue(cause.toString().contains("OID: 1.2.840.113635.100.6.11.1 was not found on the signing certificate"));
Expand All @@ -77,7 +77,7 @@ public void testInvalidChainLength() {
INTERMEDIATE_CA_BASE64_ENCODED,
ROOT_CA_BASE64_ENCODED
}, false, EFFECTIVE_DATE));
Assertions.assertEquals(Status.INVALID_CHAIN_LENGTH, exception.getStatus());
Assertions.assertEquals(VerificationStatus.INVALID_CHAIN_LENGTH, exception.getStatus());
}

@Test
Expand All @@ -88,7 +88,7 @@ public void testMalformedBase64InCertificateList() {
INTERMEDIATE_CA_BASE64_ENCODED,
ROOT_CA_BASE64_ENCODED
}, false, EFFECTIVE_DATE));
Assertions.assertEquals(Status.INVALID_CERTIFICATE, exception.getStatus());
Assertions.assertEquals(VerificationStatus.INVALID_CERTIFICATE, exception.getStatus());
}

@Test
Expand All @@ -99,7 +99,7 @@ public void testMalformedCertificateList() {
INTERMEDIATE_CA_BASE64_ENCODED,
ROOT_CA_BASE64_ENCODED
}, false, EFFECTIVE_DATE));
Assertions.assertEquals(Status.INVALID_CERTIFICATE, exception.getStatus());
Assertions.assertEquals(VerificationStatus.INVALID_CERTIFICATE, exception.getStatus());
}

@Test
Expand All @@ -110,7 +110,7 @@ public void testValidChainExpired() {
INTERMEDIATE_CA_BASE64_ENCODED,
ROOT_CA_BASE64_ENCODED
}, false, new Date(2280946846000L)));
Assertions.assertEquals(Status.INVALID_CHAIN, exception.getStatus());
Assertions.assertEquals(VerificationStatus.INVALID_CHAIN, exception.getStatus());
}

@Test
Expand All @@ -132,7 +132,7 @@ public void testChainDifferentThanRootCertificate() {
INTERMEDIATE_CA_BASE64_ENCODED,
ROOT_CA_BASE64_ENCODED
}, false, EFFECTIVE_DATE));
Assertions.assertEquals(Status.INVALID_CHAIN, exception.getStatus());
Assertions.assertEquals(VerificationStatus.INVALID_CHAIN, exception.getStatus());
Throwable cause = exception.getCause();
Assertions.assertInstanceOf(CertPathValidatorException.class, cause);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,35 +26,35 @@ public void testAppStoreServerNotificationDecoding() throws VerificationExceptio
public void testMissingX5CHeader() throws IOException {
SignedDataVerifier verifier = TestingUtility.getSignedPayloadVerifier(Environment.SANDBOX, "com.example");
VerificationException exception = Assertions.assertThrows(VerificationException.class, () -> verifier.verifyAndDecodeNotification(TestingUtility.readFile("mock_signed_data/missingX5CHeaderClaim")));
Assertions.assertEquals(Status.VERIFICATION_FAILURE, exception.getStatus());
Assertions.assertEquals(VerificationStatus.VERIFICATION_FAILURE, exception.getStatus());
}

@Test
public void testWrongBundleIdForServerNotification() throws IOException {
SignedDataVerifier verifier = TestingUtility.getSignedPayloadVerifier(Environment.SANDBOX, "com.example");
VerificationException exception = Assertions.assertThrows(VerificationException.class, () -> verifier.verifyAndDecodeNotification(TestingUtility.readFile("mock_signed_data/wrongBundleId")));
Assertions.assertEquals(Status.INVALID_APP_IDENTIFIER, exception.getStatus());
Assertions.assertEquals(VerificationStatus.INVALID_APP_IDENTIFIER, exception.getStatus());
}

@Test
public void testWrongAppAppleIdForNotification() throws IOException {
SignedDataVerifier verifier = TestingUtility.getSignedPayloadVerifier(Environment.PRODUCTION, "com.example", 1235L);
VerificationException exception = Assertions.assertThrows(VerificationException.class, () -> verifier.verifyAndDecodeNotification(TestingUtility.readFile("mock_signed_data/testNotification")));
Assertions.assertEquals(Status.INVALID_APP_IDENTIFIER, exception.getStatus());
Assertions.assertEquals(VerificationStatus.INVALID_APP_IDENTIFIER, exception.getStatus());
}

@Test
public void testWrongBundleIdForTransaction() throws IOException {
SignedDataVerifier verifier = TestingUtility.getSignedPayloadVerifier(Environment.SANDBOX, "com.example.x");
VerificationException exception = Assertions.assertThrows(VerificationException.class, () -> verifier.verifyAndDecodeTransaction(TestingUtility.readFile("mock_signed_data/transactionInfo")));
Assertions.assertEquals(Status.INVALID_APP_IDENTIFIER, exception.getStatus());
Assertions.assertEquals(VerificationStatus.INVALID_APP_IDENTIFIER, exception.getStatus());
}

@Test
public void testWrongEnvironmentForServerNotification() throws IOException {
SignedDataVerifier verifier = TestingUtility.getSignedPayloadVerifier(Environment.PRODUCTION, "com.example");
VerificationException exception = Assertions.assertThrows(VerificationException.class, () -> verifier.verifyAndDecodeNotification(TestingUtility.readFile("mock_signed_data/testNotification")));
Assertions.assertEquals(Status.INVALID_ENVIRONMENT, exception.getStatus());
Assertions.assertEquals(VerificationStatus.INVALID_ENVIRONMENT, exception.getStatus());
}

@Test
Expand All @@ -75,13 +75,13 @@ public void testTransactionInfoDecoding() throws VerificationException, IOExcept
public void testMalformedJWTWithTooManyParts() throws IOException {
SignedDataVerifier verifier = TestingUtility.getSignedPayloadVerifier();
VerificationException exception = Assertions.assertThrows(VerificationException.class, () -> verifier.verifyAndDecodeNotification("a.b.c.d"));
Assertions.assertEquals(Status.VERIFICATION_FAILURE, exception.getStatus());
Assertions.assertEquals(VerificationStatus.VERIFICATION_FAILURE, exception.getStatus());
}

@Test
public void testMalformedJWTWithMalformedData() throws IOException {
SignedDataVerifier verifier = TestingUtility.getSignedPayloadVerifier();
VerificationException exception = Assertions.assertThrows(VerificationException.class, () -> verifier.verifyAndDecodeNotification("a.b.c"));
Assertions.assertEquals(Status.VERIFICATION_FAILURE, exception.getStatus());
Assertions.assertEquals(VerificationStatus.VERIFICATION_FAILURE, exception.getStatus());
}
}
Loading