• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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     private static final int VERIFIED_BOOT_HASH_INDEX = 3;
31 
32     public static final int KM_VERIFIED_BOOT_VERIFIED = 0;
33     public static final int KM_VERIFIED_BOOT_SELF_SIGNED = 1;
34     public static final int KM_VERIFIED_BOOT_UNVERIFIED = 2;
35     public static final int KM_VERIFIED_BOOT_FAILED = 3;
36 
37     private final byte[] mVerifiedBootKey;
38     private final boolean mDeviceLocked;
39     private final int mVerifiedBootState;
40     private final byte[] mVerifiedBootHash;
41 
RootOfTrust(ASN1Encodable asn1Encodable)42     public RootOfTrust(ASN1Encodable asn1Encodable) throws CertificateParsingException {
43         this(asn1Encodable, true);
44     }
45 
RootOfTrust(ASN1Encodable asn1Encodable, boolean strictParsing)46     public RootOfTrust(ASN1Encodable asn1Encodable, boolean strictParsing)
47             throws CertificateParsingException {
48         if (!(asn1Encodable instanceof ASN1Sequence)) {
49             throw new CertificateParsingException("Expected sequence for root of trust, found "
50                     + asn1Encodable.getClass().getName());
51         }
52 
53         ASN1Sequence sequence = (ASN1Sequence) asn1Encodable;
54         mVerifiedBootKey =
55                 Asn1Utils.getByteArrayFromAsn1(sequence.getObjectAt(VERIFIED_BOOT_KEY_INDEX));
56         mDeviceLocked = Asn1Utils.getBooleanFromAsn1(
57                 sequence.getObjectAt(DEVICE_LOCKED_INDEX), strictParsing);
58         mVerifiedBootState =
59                 Asn1Utils.getIntegerFromAsn1(sequence.getObjectAt(VERIFIED_BOOT_STATE_INDEX));
60         mVerifiedBootHash =
61               Asn1Utils.getByteArrayFromAsn1(sequence.getObjectAt(VERIFIED_BOOT_HASH_INDEX));
62     }
63 
64 
RootOfTrust(byte[] verifiedBootKey, boolean deviceLocked, int verifiedBootState, byte[] verifiedBootHash)65     RootOfTrust(byte[] verifiedBootKey, boolean deviceLocked, int verifiedBootState,
66                 byte[] verifiedBootHash) {
67         this.mVerifiedBootKey = verifiedBootKey;
68         this.mDeviceLocked = deviceLocked;
69         this.mVerifiedBootState = verifiedBootState;
70         this.mVerifiedBootHash = verifiedBootHash;
71     }
72 
verifiedBootStateToString(int verifiedBootState)73     public static String verifiedBootStateToString(int verifiedBootState) {
74         switch (verifiedBootState) {
75             case KM_VERIFIED_BOOT_VERIFIED:
76                 return "Verified";
77             case KM_VERIFIED_BOOT_SELF_SIGNED:
78                 return "Self-signed";
79             case KM_VERIFIED_BOOT_UNVERIFIED:
80                 return "Unverified";
81             case KM_VERIFIED_BOOT_FAILED:
82                 return "Failed";
83             default:
84                 return "Unknown";
85         }
86     }
87 
getVerifiedBootKey()88     public byte[] getVerifiedBootKey() {
89         return mVerifiedBootKey;
90     }
91 
isDeviceLocked()92     public boolean isDeviceLocked() {
93         return mDeviceLocked;
94     }
95 
getVerifiedBootState()96     public int getVerifiedBootState() {
97         return mVerifiedBootState;
98     }
99 
getVerifiedBootHash()100     public byte[] getVerifiedBootHash() {
101         return mVerifiedBootHash;
102     }
103 
104     @Override
toString()105     public String toString() {
106         return new StringBuilder()
107                 .append("\nVerified boot Key: ")
108                 .append(mVerifiedBootKey != null
109                             ? BaseEncoding.base64().encode(mVerifiedBootKey)
110                             : "null")
111                 .append("\nDevice locked: ")
112                 .append(mDeviceLocked)
113                 .append("\nVerified boot state: ")
114                 .append(verifiedBootStateToString(mVerifiedBootState))
115                 .append("\nVerified boot hash: ")
116                 .append(mVerifiedBootHash != null
117                             ? BaseEncoding.base64().encode(mVerifiedBootHash)
118                             : "null")
119                 .toString();
120     }
121 
122     public static class Builder {
123         private byte[] mVerifiedBootKey;
124         private boolean mDeviceLocked = false;
125         private int mVerifiedBootState = -1;
126         private byte[] mVerifiedBootHash;
127 
setVerifiedBootKey(byte[] verifiedBootKey)128         public Builder setVerifiedBootKey(byte[] verifiedBootKey) {
129             this.mVerifiedBootKey = verifiedBootKey;
130             return this;
131         }
setDeviceLocked(boolean deviceLocked)132         public Builder setDeviceLocked(boolean deviceLocked) {
133             this.mDeviceLocked = deviceLocked;
134             return this;
135         }
setVerifiedBootState(int verifiedBootState)136         public Builder setVerifiedBootState(int verifiedBootState) {
137             this.mVerifiedBootState = verifiedBootState;
138             return this;
139         }
setVerifiedBootHash(byte[] verifiedBootHash)140         public Builder setVerifiedBootHash(byte[] verifiedBootHash) {
141             this.mVerifiedBootHash = verifiedBootHash;
142             return this;
143         }
build()144         public RootOfTrust build() {
145             return new RootOfTrust(mVerifiedBootKey, mDeviceLocked,
146                                    mVerifiedBootState, mVerifiedBootHash);
147         }
148     }
149 }
150