• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2020 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.car.encryptionrunner;
18 
19 import android.text.TextUtils;
20 
21 import androidx.annotation.IntDef;
22 import androidx.annotation.NonNull;
23 import androidx.annotation.Nullable;
24 
25 import java.lang.annotation.Retention;
26 import java.lang.annotation.RetentionPolicy;
27 
28 /**
29  * During an {@link EncryptionRunner} handshake process, these are the messages returned as part
30  * of each step.
31  */
32 public class HandshakeMessage {
33 
34     /**
35      * States for handshake progress.
36      */
37     @Retention(RetentionPolicy.SOURCE)
38     @IntDef({HandshakeState.UNKNOWN, HandshakeState.IN_PROGRESS, HandshakeState.VERIFICATION_NEEDED,
39             HandshakeState.FINISHED, HandshakeState.INVALID, HandshakeState.RESUMING_SESSION,
40             HandshakeState.OOB_VERIFICATION_NEEDED})
41     public @interface HandshakeState {
42         /**
43          * The initial state, this value is not expected to be returned.
44          */
45         int UNKNOWN = 0;
46         /**
47          * The handshake is in progress.
48          */
49         int IN_PROGRESS = 1;
50         /**
51          * The handshake is complete, but verification of the code is needed.
52          */
53         int VERIFICATION_NEEDED = 2;
54         /**
55          * The handshake is complete.
56          */
57         int FINISHED = 3;
58         /**
59          * The handshake is complete and not successful.
60          */
61         int INVALID = 4;
62         /**
63          * The handshake is complete, but extra verification is needed.
64          */
65         int RESUMING_SESSION = 5;
66         /**
67          * The handshake is complete, but out of band verification of the code is needed.
68          */
69         int OOB_VERIFICATION_NEEDED = 6;
70     }
71 
72     @HandshakeState
73     private final int mHandshakeState;
74     private final Key mKey;
75     private final byte[] mNextMessage;
76     private final String mVerificationCode;
77     private final byte[] mOobVerificationCode;
78 
79     /**
80      * @return Returns a builder for {@link HandshakeMessage}.
81      */
newBuilder()82     public static Builder newBuilder() {
83         return new Builder();
84     }
85 
86     /**
87      * Use the builder;
88      */
HandshakeMessage( @andshakeState int handshakeState, @Nullable Key key, @Nullable byte[] nextMessage, @Nullable String verificationCode, @Nullable byte[] oobVerificationCode)89     private HandshakeMessage(
90             @HandshakeState int handshakeState,
91             @Nullable Key key,
92             @Nullable byte[] nextMessage,
93             @Nullable String verificationCode,
94             @Nullable byte[] oobVerificationCode) {
95         mHandshakeState = handshakeState;
96         mKey = key;
97         mNextMessage = nextMessage;
98         mVerificationCode = verificationCode;
99         mOobVerificationCode = oobVerificationCode;
100     }
101 
102     /**
103      * Returns the next message to send in a handshake.
104      */
105     @Nullable
getNextMessage()106     public byte[] getNextMessage() {
107         return mNextMessage == null ? null : mNextMessage.clone();
108     }
109 
110     /**
111      * Returns the state of the handshake.
112      */
113     @HandshakeState
getHandshakeState()114     public int getHandshakeState() {
115         return mHandshakeState;
116     }
117 
118     /**
119      * Returns the encryption key that can be used to encrypt data.
120      */
121     @Nullable
getKey()122     public Key getKey() {
123         return mKey;
124     }
125 
126     /**
127      * Returns a verification code to show to the user.
128      */
129     @Nullable
getVerificationCode()130     public String getVerificationCode() {
131         return mVerificationCode;
132     }
133 
134     /**
135      * Returns a verification code to be encrypted using an out-of-band key and sent to the remote
136      * device.
137      */
138     @Nullable
getOobVerificationCode()139     public byte[] getOobVerificationCode() {
140         return mOobVerificationCode;
141     }
142 
143     static class Builder {
144         @HandshakeState
145         int mHandshakeState;
146         Key mKey;
147         byte[] mNextMessage;
148         String mVerificationCode;
149         byte[] mOobVerificationCode;
150 
setHandshakeState(@andshakeState int handshakeState)151         Builder setHandshakeState(@HandshakeState int handshakeState) {
152             mHandshakeState = handshakeState;
153             return this;
154         }
155 
setKey(@ullable Key key)156         Builder setKey(@Nullable Key key) {
157             mKey = key;
158             return this;
159         }
160 
setNextMessage(@ullable byte[] nextMessage)161         Builder setNextMessage(@Nullable byte[] nextMessage) {
162             mNextMessage = nextMessage == null ? null : nextMessage.clone();
163             return this;
164         }
165 
setVerificationCode(@ullable String verificationCode)166         Builder setVerificationCode(@Nullable String verificationCode) {
167             mVerificationCode = verificationCode;
168             return this;
169         }
170 
setOobVerificationCode(@onNull byte[] oobVerificationCode)171         Builder setOobVerificationCode(@NonNull byte[] oobVerificationCode) {
172             mOobVerificationCode = oobVerificationCode;
173             return this;
174         }
175 
build()176         HandshakeMessage build() {
177             if (mHandshakeState == HandshakeState.UNKNOWN) {
178                 throw new IllegalStateException("must set handshake state before calling build");
179             }
180             if (mHandshakeState == HandshakeState.VERIFICATION_NEEDED
181                     && TextUtils.isEmpty(mVerificationCode)) {
182                 throw new IllegalStateException(
183                         "State is verification needed, but verification code null.");
184             }
185             if (mHandshakeState == HandshakeState.OOB_VERIFICATION_NEEDED
186                     && (mOobVerificationCode == null || mOobVerificationCode.length == 0)) {
187                 throw new IllegalStateException(
188                         "State is OOB verification needed, but OOB verification code null.");
189             }
190             return new HandshakeMessage(mHandshakeState, mKey, mNextMessage, mVerificationCode,
191                     mOobVerificationCode);
192         }
193 
194     }
195 }
196