/* * Copyright (C) 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.car.encryptionrunner; import android.annotation.NonNull; /** * A generalized interface that allows for generating shared secrets as well as encrypting * messages. * * To use this interface: * 1. As a client. * * HandshakeMessage initialClientMessage = clientRunner.initHandshake(); * sendToServer(initialClientMessage.getNextMessage()); * byte message = getServerResponse(); * * HandshakeMessage message = clientRunner.continueHandshake(message); * message.getHandshakeState() should be VERIFICATION_NEEDED, * otherwise if IN_PROGRESS just send the result of getNextMessage(); * * Show user the verification code and ask to verify. * message.getVerificationCode() * * if user agrees * HandshakeMessage lastMessage = clientRunner.verifyPin(); * otherwise * clientRunner.invalidPin(); * * Use lastMessage.getKey() for encryption. * * 2. As a server. * * byte[] initialMessage = getClientMessageBytes(); * HandshakeMesssage message = serverRunner.respondToInitRequest(initialMessage); * * sendToClient(message.getNextMessage()); * * message.getHandshakeState() should be VERIFICATION_NEEDED, * if so show user code and ask to verify * message.getVerificationCode(); * * serverRunner.verifyPin or invalidPin and continue same as client above. * * * Also see {@link EncryptionRunnerTest} for examples. */ public interface EncryptionRunner { String TAG = "EncryptionRunner"; /** * Starts an encryption handshake. * * @return A handshake message with information about the handshake that is started. */ HandshakeMessage initHandshake(); /** * Starts an encryption handshake where the device that is being communicated with already * initiated the request. * * @param initializationRequest the bytes that the other device sent over. * @return a handshake message with information about the handshake. * * @throws HandshakeException if initialization request is invalid. */ HandshakeMessage respondToInitRequest(@NonNull byte[] initializationRequest) throws HandshakeException; /** * Continues a handshake after receiving another response from the connected device. * * @param response the response from the other device. * @return a message that can be used to continue the handshake. * * @throws HandshakeException if unexpected bytes in response. */ HandshakeMessage continueHandshake(@NonNull byte[] response) throws HandshakeException; /** * Verifies the pin shown to the user. The result is the next handshake message and will * typically contain an encryption key. * * @throws HandshakeException if not in state to verify pin. */ HandshakeMessage verifyPin() throws HandshakeException; /** * Notifies the encryption runner that the user failed to validate the pin. After calling this * method the runner should not be used, and will throw exceptions. */ void invalidPin(); /** * De-serializes a previously serialized key generated by an instance of this encryption runner. * * @param serialized the serialized bytes of the key. * @return the Key object used for encryption. */ Key keyOf(@NonNull byte[] serialized); }