1 /*
2  * Copyright (C) 2019 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.annotation.IntDef;
20 
21 import com.android.internal.annotations.VisibleForTesting;
22 
23 import java.lang.annotation.Retention;
24 import java.lang.annotation.RetentionPolicy;
25 
26 /**
27  * An encryption runner that doesn't actually do encryption. Useful for debugging. Do not use in
28  * production environments.
29  */
30 @VisibleForTesting
31 public class DummyEncryptionRunner implements EncryptionRunner {
32 
33     private static final String KEY = "key";
34     @VisibleForTesting
35     public static final String INIT = "init";
36     @VisibleForTesting
37     public static final String INIT_RESPONSE = "initResponse";
38     @VisibleForTesting
39     public static final String CLIENT_RESPONSE = "clientResponse";
40     public static final String VERIFICATION_CODE = "1234";
41 
42     @Retention(RetentionPolicy.SOURCE)
43     @IntDef({Mode.UNKNOWN, Mode.CLIENT, Mode.SERVER})
44     private @interface Mode {
45 
46         int UNKNOWN = 0;
47         int CLIENT = 1;
48         int SERVER = 2;
49     }
50 
51     @Mode
52     private int mMode;
53     @HandshakeMessage.HandshakeState
54     private int mState;
55 
56     @Override
initHandshake()57     public HandshakeMessage initHandshake() {
58         checkRunnerIsNew();
59         mMode = Mode.CLIENT;
60         mState = HandshakeMessage.HandshakeState.IN_PROGRESS;
61         return HandshakeMessage.newBuilder()
62                 .setHandshakeState(mState)
63                 .setNextMessage(INIT.getBytes())
64                 .build();
65     }
66 
67     @Override
respondToInitRequest(byte[] initializationRequest)68     public HandshakeMessage respondToInitRequest(byte[] initializationRequest)
69             throws HandshakeException {
70         checkRunnerIsNew();
71         mMode = Mode.SERVER;
72         if (!new String(initializationRequest).equals(INIT)) {
73             throw new HandshakeException("Unexpected initialization request");
74         }
75         mState = HandshakeMessage.HandshakeState.IN_PROGRESS;
76         return HandshakeMessage.newBuilder()
77                 .setHandshakeState(HandshakeMessage.HandshakeState.IN_PROGRESS)
78                 .setNextMessage(INIT_RESPONSE.getBytes())
79                 .build();
80     }
81 
checkRunnerIsNew()82     private void checkRunnerIsNew() {
83         if (mState != HandshakeMessage.HandshakeState.UNKNOWN) {
84             throw new IllegalStateException("runner already initialized.");
85         }
86     }
87 
88     @Override
continueHandshake(byte[] response)89     public HandshakeMessage continueHandshake(byte[] response) throws HandshakeException {
90         if (mState != HandshakeMessage.HandshakeState.IN_PROGRESS) {
91             throw new HandshakeException("not waiting for response but got one");
92         }
93         switch(mMode) {
94             case Mode.SERVER:
95                 if (!CLIENT_RESPONSE.equals(new String(response))) {
96                     throw new HandshakeException("unexpected response: " + new String(response));
97                 }
98                 mState = HandshakeMessage.HandshakeState.VERIFICATION_NEEDED;
99                 return HandshakeMessage.newBuilder()
100                         .setVerificationCode(VERIFICATION_CODE)
101                         .setHandshakeState(mState)
102                         .build();
103             case Mode.CLIENT:
104                 if (!INIT_RESPONSE.equals(new String(response))) {
105                     throw new HandshakeException("unexpected response: " + new String(response));
106                 }
107                 mState = HandshakeMessage.HandshakeState.VERIFICATION_NEEDED;
108                 return HandshakeMessage.newBuilder()
109                         .setHandshakeState(mState)
110                         .setNextMessage(CLIENT_RESPONSE.getBytes())
111                         .setVerificationCode(VERIFICATION_CODE)
112                         .build();
113             default:
114                 throw new IllegalStateException("unexpected state: "  + mState);
115         }
116     }
117 
118     @Override
keyOf(byte[] serialized)119     public Key keyOf(byte[] serialized) {
120         return new DummyKey();
121     }
122 
123     @Override
verifyPin()124     public HandshakeMessage verifyPin() throws HandshakeException {
125         if (mState != HandshakeMessage.HandshakeState.VERIFICATION_NEEDED) {
126             throw new IllegalStateException("asking to verify pin, state = " + mState);
127         }
128         mState = HandshakeMessage.HandshakeState.FINISHED;
129         return HandshakeMessage.newBuilder()
130                 .setHandshakeState(mState)
131                 .setKey(new DummyKey())
132                 .build();
133     }
134 
135     @Override
invalidPin()136     public void invalidPin() {
137         mState = HandshakeMessage.HandshakeState.INVALID;
138     }
139 
140     private class DummyKey implements Key {
141 
142         @Override
asBytes()143         public byte[] asBytes() {
144             return KEY.getBytes();
145         }
146 
147         @Override
encryptData(byte[] data)148         public byte[] encryptData(byte[] data) {
149             return data;
150         }
151 
152         @Override
decryptData(byte[] encryptedData)153         public byte[] decryptData(byte[] encryptedData) {
154             return encryptedData;
155         }
156     }
157 }
158