googlesamples / android-play-safetynet

Samples for the Google SafetyNet Attestation API
Apache License 2.0
287 stars 133 forks source link

AttestationStatement.java getApkDigestSha256() does not properly handle null #19

Open dphillipsprosper opened 5 years ago

dphillipsprosper commented 5 years ago

According to the docs at https://developer.android.com/training/safetynet/attestation:

If the device is tampered—that is, if basicIntegrity is set to false in the response—the verdict might not contain data about the calling app, such as the apkPackageName and apkCertificateDigestSha256. This occurs when our systems cannot reliably determine the calling app.

Sure enough, I've got a test device w/ Magisk right now, that is failing SafetyNet. I get an attestation response like so:

{
  "nonce": "Y2MyOGQ2YWEtNzA5Yi00ODUyLTk2MTItZGU4N2EwMDFlZDRh",
  "timestampMs": 1553123841535,
  "ctsProfileMatch": false,
  "apkCertificateDigestSha256": [],
  "basicIntegrity": false,
  "advice": "RESTORE_TO_FACTORY_ROM"
}

However, the getApkDigestSha256() property in the AttestationStatement.java example file for offline server validation does not take this null into account.

public byte[] getApkDigestSha256() {
    return Base64.decodeBase64(apkDigestSha256);
}

So, if you call this property on a failing device, it explodes.

The fix is simple, we just need a null check:

public byte[] getApkDigestSha256() {
    return apkDigestSha256 != null ? Base64.decodeBase64(apkDigestSha256) : new byte[0];
}

I've fixed this locally, filing this so I can contribute the fix.