1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.keystore.cts; 18 19 import com.google.common.io.BaseEncoding; 20 21 import org.bouncycastle.asn1.ASN1Encodable; 22 import org.bouncycastle.asn1.ASN1Sequence; 23 24 import java.security.cert.CertificateParsingException; 25 26 public class RootOfTrust { 27 private static final int VERIFIED_BOOT_KEY_INDEX = 0; 28 private static final int DEVICE_LOCKED_INDEX = 1; 29 private static final int VERIFIED_BOOT_STATE_INDEX = 2; 30 31 public static final int KM_VERIFIED_BOOT_VERIFIED = 0; 32 public static final int KM_VERIFIED_BOOT_SELF_SIGNED = 1; 33 public static final int KM_VERIFIED_BOOT_UNVERIFIED = 2; 34 public static final int KM_VERIFIED_BOOT_FAILED = 3; 35 36 private final byte[] verifiedBootKey; 37 private final boolean deviceLocked; 38 private final int verifiedBootState; 39 RootOfTrust(ASN1Encodable asn1Encodable)40 public RootOfTrust(ASN1Encodable asn1Encodable) throws CertificateParsingException { 41 this(asn1Encodable, true); 42 } 43 RootOfTrust(ASN1Encodable asn1Encodable, boolean strictParsing)44 public RootOfTrust(ASN1Encodable asn1Encodable, boolean strictParsing) 45 throws CertificateParsingException { 46 if (!(asn1Encodable instanceof ASN1Sequence)) { 47 throw new CertificateParsingException("Expected sequence for root of trust, found " 48 + asn1Encodable.getClass().getName()); 49 } 50 51 ASN1Sequence sequence = (ASN1Sequence) asn1Encodable; 52 verifiedBootKey = 53 Asn1Utils.getByteArrayFromAsn1(sequence.getObjectAt(VERIFIED_BOOT_KEY_INDEX)); 54 deviceLocked = Asn1Utils.getBooleanFromAsn1( 55 sequence.getObjectAt(DEVICE_LOCKED_INDEX), strictParsing); 56 verifiedBootState = 57 Asn1Utils.getIntegerFromAsn1(sequence.getObjectAt(VERIFIED_BOOT_STATE_INDEX)); 58 } 59 60 RootOfTrust(byte[] verifiedBootKey, boolean deviceLocked, int verifiedBootState)61 RootOfTrust(byte[] verifiedBootKey, boolean deviceLocked, int verifiedBootState) { 62 this.verifiedBootKey = verifiedBootKey; 63 this.deviceLocked = deviceLocked; 64 this.verifiedBootState = verifiedBootState; 65 } 66 verifiedBootStateToString(int verifiedBootState)67 public static String verifiedBootStateToString(int verifiedBootState) { 68 switch (verifiedBootState) { 69 case KM_VERIFIED_BOOT_VERIFIED: 70 return "Verified"; 71 case KM_VERIFIED_BOOT_SELF_SIGNED: 72 return "Self-signed"; 73 case KM_VERIFIED_BOOT_UNVERIFIED: 74 return "Unverified"; 75 case KM_VERIFIED_BOOT_FAILED: 76 return "Failed"; 77 default: 78 return "Unknown"; 79 } 80 } 81 getVerifiedBootKey()82 public byte[] getVerifiedBootKey() { 83 return verifiedBootKey; 84 } 85 isDeviceLocked()86 public boolean isDeviceLocked() { 87 return deviceLocked; 88 } 89 getVerifiedBootState()90 public int getVerifiedBootState() { 91 return verifiedBootState; 92 } 93 94 @Override toString()95 public String toString() { 96 return new StringBuilder() 97 .append("\nVerified boot Key: ") 98 .append(verifiedBootKey != null ? 99 BaseEncoding.base64().encode(verifiedBootKey) : 100 "null") 101 .append("\nDevice locked: ") 102 .append(deviceLocked) 103 .append("\nVerified boot state: ") 104 .append(verifiedBootStateToString(verifiedBootState)) 105 .toString(); 106 } 107 108 public static class Builder { 109 private byte[] verifiedBootKey; 110 private boolean deviceLocked = false; 111 private int verifiedBootState = -1; 112 setVerifiedBootKey(byte[] verifiedBootKey)113 public Builder setVerifiedBootKey(byte[] verifiedBootKey) { 114 this.verifiedBootKey = verifiedBootKey; 115 return this; 116 } setDeviceLocked(boolean deviceLocked)117 public Builder setDeviceLocked(boolean deviceLocked) { 118 this.deviceLocked = deviceLocked; 119 return this; 120 } setVerifiedBootState(int verifiedBootState)121 public Builder setVerifiedBootState(int verifiedBootState) { 122 this.verifiedBootState = verifiedBootState; 123 return this; 124 } build()125 public RootOfTrust build() { 126 return new RootOfTrust(verifiedBootKey, deviceLocked, verifiedBootState); 127 } 128 } 129 } 130