-
Notifications
You must be signed in to change notification settings - Fork 106
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
app: display Knox TEE integrity status info
Signed-off-by: BlackMesa123 <[email protected]>
- Loading branch information
1 parent
6f18c6c
commit 9de9049
Showing
8 changed files
with
366 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
106 changes: 106 additions & 0 deletions
106
app/src/main/java/io/github/vvb2060/keyattestation/attestation/AuthResult.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
package io.github.vvb2060.keyattestation.attestation; | ||
|
||
import com.google.common.io.BaseEncoding; | ||
|
||
import org.bouncycastle.asn1.ASN1Encodable; | ||
import org.bouncycastle.asn1.ASN1Primitive; | ||
import org.bouncycastle.asn1.ASN1Sequence; | ||
import org.bouncycastle.asn1.ASN1SequenceParser; | ||
import org.bouncycastle.asn1.ASN1TaggedObject; | ||
|
||
import java.io.IOException; | ||
import java.security.cert.CertificateParsingException; | ||
|
||
public class AuthResult { | ||
private static final int CALLER_AUTH_RESULT = 0; | ||
private static final int CALLING_PACKAGE = 1; | ||
private static final int CALLING_PACKAGE_SIGS = 2; | ||
private static final int CALLING_PACKAGE_AUTH_RESULT = 3; | ||
|
||
public static final int STATUS_NORMAL = 0; | ||
public static final int STATUS_ABNORMAL = 1; | ||
public static final int STATUS_NOT_SUPPORT = 2; | ||
|
||
private int callerAuthResult; | ||
private byte[] callingPackage; | ||
private byte[] callingPackageSigs; | ||
private int callingPackageAuthResult; | ||
|
||
public AuthResult(ASN1Encodable asn1Encodable) throws CertificateParsingException { | ||
if (!(asn1Encodable instanceof ASN1Sequence sequence)) { | ||
throw new CertificateParsingException("Expected sequence for caller auth, found " | ||
+ asn1Encodable.getClass().getName()); | ||
} | ||
|
||
ASN1SequenceParser parser = sequence.parser(); | ||
ASN1TaggedObject entry = parseAsn1TaggedObject(parser); | ||
|
||
for (; entry != null; entry = parseAsn1TaggedObject(parser)) { | ||
int tag = entry.getTagNo(); | ||
ASN1Primitive value = entry.getBaseObject().toASN1Primitive(); | ||
|
||
switch (tag) { | ||
case CALLER_AUTH_RESULT: | ||
callerAuthResult = Asn1Utils.getIntegerFromAsn1(value); | ||
break; | ||
case CALLING_PACKAGE: | ||
callingPackage = Asn1Utils.getByteArrayFromAsn1(value); | ||
break; | ||
case CALLING_PACKAGE_SIGS: | ||
callingPackageSigs = Asn1Utils.getByteArrayFromAsn1(value); | ||
break; | ||
case CALLING_PACKAGE_AUTH_RESULT: | ||
callingPackageAuthResult = Asn1Utils.getIntegerFromAsn1(value); | ||
break; | ||
} | ||
} | ||
} | ||
|
||
private static ASN1TaggedObject parseAsn1TaggedObject(ASN1SequenceParser parser) | ||
throws CertificateParsingException { | ||
ASN1Encodable asn1Encodable = parseAsn1Encodable(parser); | ||
if (asn1Encodable == null || asn1Encodable instanceof ASN1TaggedObject) { | ||
return (ASN1TaggedObject) asn1Encodable; | ||
} | ||
throw new CertificateParsingException( | ||
"Expected tagged object, found " + asn1Encodable.getClass().getName()); | ||
} | ||
|
||
private static ASN1Encodable parseAsn1Encodable(ASN1SequenceParser parser) | ||
throws CertificateParsingException { | ||
try { | ||
return parser.readObject(); | ||
} catch (IOException e) { | ||
throw new CertificateParsingException("Failed to parse ASN1 sequence", e); | ||
} | ||
} | ||
|
||
public String statusToString(int status, boolean isCallingPackageAuthResult) { | ||
switch (status) { | ||
case STATUS_NORMAL: | ||
return "Normal"; | ||
case STATUS_ABNORMAL: | ||
return "Abnormal"; | ||
case STATUS_NOT_SUPPORT: | ||
return "Not support"; | ||
default: | ||
if (isCallingPackageAuthResult) { | ||
return "Not support"; | ||
} | ||
return Integer.toHexString(status); | ||
} | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
StringBuilder sb = new StringBuilder("Caller auth result: ") | ||
.append(statusToString(callerAuthResult, false)).append('\n') | ||
.append("Calling package: ") | ||
.append(new String(callingPackage)).append('\n') | ||
.append("Calling package signatures: ") | ||
.append(BaseEncoding.base64().encode(callingPackageSigs)).append(" (base64)").append('\n') | ||
.append("Calling package auth result: ") | ||
.append(statusToString(callingPackageAuthResult, true)); | ||
return sb.toString(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
117 changes: 117 additions & 0 deletions
117
app/src/main/java/io/github/vvb2060/keyattestation/attestation/IntegrityStatus.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
package io.github.vvb2060.keyattestation.attestation; | ||
|
||
import org.bouncycastle.asn1.ASN1Encodable; | ||
import org.bouncycastle.asn1.ASN1Primitive; | ||
import org.bouncycastle.asn1.ASN1Sequence; | ||
import org.bouncycastle.asn1.ASN1SequenceParser; | ||
import org.bouncycastle.asn1.ASN1TaggedObject; | ||
|
||
import java.io.IOException; | ||
import java.security.cert.CertificateParsingException; | ||
|
||
public class IntegrityStatus { | ||
private static final int TRUST_BOOT = 0; | ||
private static final int WARRANTY = 1; | ||
private static final int ICD = 2; | ||
private static final int KERNEL_STATUS = 3; | ||
private static final int SYSTEM_STATUS = 4; | ||
private static final int AUTH_RESULT = 5; | ||
|
||
public static final int STATUS_NORMAL = 0; | ||
public static final int STATUS_ABNORMAL = 1; | ||
public static final int STATUS_NOT_SUPPORT = 2; | ||
|
||
private int trustBoot; | ||
private int warranty; | ||
private int icd; | ||
private int kernelStatus; | ||
private int systemStatus; | ||
private AuthResult authResult; | ||
|
||
public IntegrityStatus(ASN1Encodable asn1Encodable) throws CertificateParsingException { | ||
if (!(asn1Encodable instanceof ASN1Sequence sequence)) { | ||
throw new CertificateParsingException("Expected sequence for integrity status, found " | ||
+ asn1Encodable.getClass().getName()); | ||
} | ||
|
||
ASN1SequenceParser parser = sequence.parser(); | ||
ASN1TaggedObject entry = parseAsn1TaggedObject(parser); | ||
|
||
for (; entry != null; entry = parseAsn1TaggedObject(parser)) { | ||
int tag = entry.getTagNo(); | ||
ASN1Primitive value = entry.getBaseObject().toASN1Primitive(); | ||
|
||
switch (tag) { | ||
case TRUST_BOOT: | ||
trustBoot = Asn1Utils.getIntegerFromAsn1(value); | ||
break; | ||
case WARRANTY: | ||
warranty = Asn1Utils.getIntegerFromAsn1(value); | ||
break; | ||
case ICD: | ||
icd = Asn1Utils.getIntegerFromAsn1(value); | ||
break; | ||
case KERNEL_STATUS: | ||
kernelStatus = Asn1Utils.getIntegerFromAsn1(value); | ||
break; | ||
case SYSTEM_STATUS: | ||
systemStatus = Asn1Utils.getIntegerFromAsn1(value); | ||
break; | ||
case AUTH_RESULT: | ||
authResult = new AuthResult(value); | ||
break; | ||
} | ||
} | ||
} | ||
|
||
private static ASN1TaggedObject parseAsn1TaggedObject(ASN1SequenceParser parser) | ||
throws CertificateParsingException { | ||
ASN1Encodable asn1Encodable = parseAsn1Encodable(parser); | ||
if (asn1Encodable == null || asn1Encodable instanceof ASN1TaggedObject) { | ||
return (ASN1TaggedObject) asn1Encodable; | ||
} | ||
throw new CertificateParsingException( | ||
"Expected tagged object, found " + asn1Encodable.getClass().getName()); | ||
} | ||
|
||
private static ASN1Encodable parseAsn1Encodable(ASN1SequenceParser parser) | ||
throws CertificateParsingException { | ||
try { | ||
return parser.readObject(); | ||
} catch (IOException e) { | ||
throw new CertificateParsingException("Failed to parse ASN1 sequence", e); | ||
} | ||
} | ||
|
||
public AuthResult getAuthResult() { | ||
return authResult; | ||
} | ||
|
||
public String statusToString(int status) { | ||
switch (status) { | ||
case STATUS_NORMAL: | ||
return "Normal"; | ||
case STATUS_ABNORMAL: | ||
return "Abnormal"; | ||
case STATUS_NOT_SUPPORT: | ||
return "Not support"; | ||
default: | ||
return Integer.toHexString(status); | ||
} | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
StringBuilder sb = new StringBuilder("Trustboot: ") | ||
.append(statusToString(trustBoot)).append('\n') | ||
.append("Warranty bit: ") | ||
.append(statusToString(warranty)).append('\n') | ||
.append("ICD: ") | ||
.append(statusToString(icd)).append('\n') | ||
.append("Kernel status: ") | ||
.append(statusToString(kernelStatus)).append('\n') | ||
.append("System status: ") | ||
.append(statusToString(systemStatus)); | ||
return sb.toString(); | ||
} | ||
} |
Oops, something went wrong.