blob: ad444bc6f6d67e8950777190af2211fa361fa235 [file] [log] [blame]
/*
* 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);
}