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