Skip to content

Commit

Permalink
1.3.0
Browse files Browse the repository at this point in the history
  • Loading branch information
JesusMcCloud committed Sep 20, 2023
1 parent 9178e17 commit 4930aee
Show file tree
Hide file tree
Showing 7 changed files with 53 additions and 17 deletions.
7 changes: 6 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,4 +69,9 @@ attestation on Android, please re-read the readme!
- introduce builder for `AppData`
- Introduce `ByteArray.parseToPublicKey` which takes ANSI X9.63 and DER-encoded byte arrays
(only P-256 is supported for ANSI)
- Update android-attestation to 1.1.0
- Update android-attestation to 1.1.0

### 1.3.0
- Documentation updates
- Update to android-attestation 1.2.0
- Refactor exceptions
2 changes: 1 addition & 1 deletion android-attestation-root
4 changes: 2 additions & 2 deletions attestation-service/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ plugins {
}

group = "at.asitplus"
version = "1.2.0"
version = "1.3.0"

sourceSets.test {
kotlin {
Expand All @@ -20,7 +20,7 @@ sourceSets.test {
}

dependencies {
api("at.asitplus:android-attestation:1.1.0")
api("at.asitplus:android-attestation:1.2.0")
api(datetime())
implementation("ch.veehait.devicecheck:devicecheck-appattest:0.9.6")
implementation("com.fasterxml.jackson.dataformat:jackson-dataformat-cbor:2.14.2")
Expand Down
7 changes: 4 additions & 3 deletions attestation-service/src/main/kotlin/AttestationService.kt
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package at.asitplus.attestation

import at.asitplus.attestation.AttestationException
import at.asitplus.attestation.IOSAttestationConfiguration.AppData
import at.asitplus.attestation.android.*
import at.asitplus.attestation.android.exceptions.AttestationException
import at.asitplus.attestation.android.exceptions.CertificateInvalidException
import ch.veehait.devicecheck.appattest.AppleAppAttest
import ch.veehait.devicecheck.appattest.assertion.Assertion
Expand Down Expand Up @@ -55,7 +55,8 @@ data class IOSAttestationConfiguration @JvmOverloads constructor(
constructor(singleApp: AppData, iosVersion: String? = null) : this(listOf(singleApp), iosVersion)

init {
if (applications.isEmpty()) throw AttestationException("No apps configured")
if (applications.isEmpty())
throw AttestationException.Configuration(Platform.IOS, "No apps configured")
}

/**
Expand Down Expand Up @@ -681,7 +682,7 @@ class DefaultAttestationService(
val configuredVersion = SemVer.parse(it)
if (parsedVersion < configuredVersion)
return AttestationResult.Error(
"iOS version $parsedVersion <$configuredVersion",
"iOS version $parsedVersion < $configuredVersion",
AttException.Content(Platform.IOS)
)
}
Expand Down
33 changes: 31 additions & 2 deletions attestation-service/src/main/kotlin/Throwables.kt
Original file line number Diff line number Diff line change
@@ -1,19 +1,48 @@
package at.asitplus.attestation


//not very idiomatic, but

enum class Platform {
IOS,
ANDROID
}

/**
* Provides additional details on why an attestation attempt failed, indicating which [platform] was being attested.
* Although many reasons exist, why an attestation may fail, these can be put into two categories:
* * [Content] e.g. version, app name, challenge, or key mismatch
* * [Certificate] e.g. chain rooted in an untrusted certificate, revocation, validity period
*
* If more specific details about why the attestation failed are available, [message] and/or [cause] will be set.
* Especially when acting upon Errors propagating from a failed Android attestation, the type of the [cause] and
* [error codes contained within](https://a-sit-plus.github.io/android-attestation/-android%20%20-attestation%20-library/at.asitplus.attestation.android.exceptions/index.html)
* will provide insights.
*
*/
sealed class AttestationException(val platform: Platform, message: String? = null, cause: Throwable? = null) :
Throwable(message, cause) {

/**
* Indicates that some value (key to be attests, bundle identifier or package name, team identified or signer certificate, etc.) failed to verify
* This usually means that either the client's OS or the app was compromised/modified.
*/
open class Content(platform: Platform, message: String? = null, cause: Throwable? = null) :
AttestationException(platform, message = message, cause = cause)

/**
* Indicates a problem verifying the certificate chain the attestation statement is built upon.
* This can either be just a borked certificate chain (i.e. just a wrong certificate somewhere in the chain),
* or the chain not being rooted in a valid trust anchor.
* Most probably, however, a legitimate app on a trusted OS will simply have fallen victim to the system clock
* being too far ahead. This heavily depends on the OS a device was originally shipped with,
* (or just Samsung being Samsung and being unable to correctly encode a timestamp conforming to ASN.1)
*/

class Certificate(platform: Platform, message: String? = null, cause: Throwable? = null) :
AttestationException(platform, message = message, cause = cause)

/**
* Thrown on instantiation, for illegal configurations (e.g. no apps configured)
*/
class Configuration(platform: Platform, message: String? = null, cause: Throwable? = null) :
AttestationException(platform, message = message, cause = cause)
}
15 changes: 8 additions & 7 deletions attestation-service/src/test/java/JavaInteropTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
import at.asitplus.attestation.android.AndroidAttestationConfiguration;
import at.asitplus.attestation.android.HardwareAttestationChecker;
import at.asitplus.attestation.android.PatchLevel;
import at.asitplus.attestation.android.exceptions.AttestationException;
import at.asitplus.attestation.android.exceptions.AndroidAttestationException;
import at.asitplus.attestation.android.exceptions.AttestationValueException;
import at.asitplus.attestation.android.exceptions.CertificateInvalidException;
import at.asitplus.attestation.android.exceptions.RevocationException;
import com.google.android.attestation.ParsedAttestationRecord;
Expand All @@ -21,7 +22,7 @@ public class JavaInteropTest {


public static void testDefaults() {
Assertions.assertThrows(AttestationException.class, () -> {
Assertions.assertThrows(AndroidAttestationException.class, () -> {
new DefaultAttestationService(
new AndroidAttestationConfiguration.Builder(new AndroidAttestationConfiguration.AppData(
"at.asitplus.attestation-example", Collections.emptyList())).build(),
Expand All @@ -31,7 +32,7 @@ public static void testDefaults() {
},
"No signature digests specified");

Assertions.assertThrows(AttestationException.class, () -> {
Assertions.assertThrows(AndroidAttestationException.class, () -> {
new DefaultAttestationService(
new AndroidAttestationConfiguration.Builder(new AndroidAttestationConfiguration.AppData("at.asitplus.attestation-example",
new ArrayList<>()
Expand All @@ -43,7 +44,7 @@ public static void testDefaults() {
},
"No signature digests specified");

Assertions.assertThrows(AttestationException.class, () -> {
Assertions.assertThrows(AndroidAttestationException.class, () -> {
new DefaultAttestationService(
new AndroidAttestationConfiguration.Builder(new AndroidAttestationConfiguration.AppData("at.asitplus.attestation-example",
new ArrayList<>(),
Expand All @@ -56,7 +57,7 @@ public static void testDefaults() {
},
"No signature digests specified");

Assertions.assertThrows(AttestationException.class, () -> {
Assertions.assertThrows(AndroidAttestationException.class, () -> {
new DefaultAttestationService(
new AndroidAttestationConfiguration.Builder(new AndroidAttestationConfiguration.AppData("at.asitplus.attestation-example",
new ArrayList<>(),
Expand All @@ -71,7 +72,7 @@ public static void testDefaults() {
},
"No signature digests specified");

Assertions.assertThrows(AttestationException.class, () -> {
Assertions.assertThrows(AndroidAttestationException.class, () -> {
new DefaultAttestationService(
new AndroidAttestationConfiguration.Builder(new AndroidAttestationConfiguration.AppData("at.asitplus.attestation-example",
new ArrayList<>()
Expand Down Expand Up @@ -133,7 +134,7 @@ public static void javaDemo() {
try {
ParsedAttestationRecord attestationRecord = checker.verifyAttestation(certificateChain, new Date(), challenge);
//all good
} catch (AttestationException | CertificateInvalidException | RevocationException e) {
} catch (AttestationValueException | CertificateInvalidException | RevocationException e) {
//untrusted device/app
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -521,7 +521,7 @@ class DefaultAttestationServiceTest : FreeSpec() {

//just to check whether this propagates
"no signature digests, cannot instantiate" {
shouldThrow<at.asitplus.attestation.android.exceptions.AttestationException> {
shouldThrow<at.asitplus.attestation.android.exceptions.AndroidAttestationException> {
attestationService(
androidAppSignatureDigest = listOf(), timeSource = FixedTimeClock(
recordedAttestation.verificationDate.toInstant()
Expand Down

0 comments on commit 4930aee

Please sign in to comment.