1 /* 2 * Copyright 2018 The gRPC Authors 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 io.grpc.alts.internal; 18 19 import io.netty.buffer.ByteBufAllocator; 20 import java.nio.ByteBuffer; 21 import java.security.GeneralSecurityException; 22 23 /** 24 * This object protects and unprotects buffers once the handshake is done. 25 * 26 * <p>A typical usage of this object would be: 27 * 28 * <pre>{@code 29 * ByteBuffer buffer = allocateDirect(ALLOCATE_SIZE); 30 * while (true) { 31 * while (true) { 32 * tsiHandshaker.getBytesToSendToPeer(buffer.clear()); 33 * if (!buffer.hasRemaining()) break; 34 * yourTransportSendMethod(buffer.flip()); 35 * assert(!buffer.hasRemaining()); // Guaranteed by yourTransportReceiveMethod(...) 36 * } 37 * if (!tsiHandshaker.isInProgress()) break; 38 * while (true) { 39 * assert(!buffer.hasRemaining()); 40 * yourTransportReceiveMethod(buffer.clear()); 41 * if (tsiHandshaker.processBytesFromPeer(buffer.flip())) break; 42 * } 43 * if (!tsiHandshaker.isInProgress()) break; 44 * assert(!buffer.hasRemaining()); 45 * } 46 * yourCheckPeerMethod(tsiHandshaker.extractPeer()); 47 * TsiFrameProtector tsiFrameProtector = tsiHandshaker.createFrameProtector(MAX_FRAME_SIZE); 48 * if (buffer.hasRemaining()) tsiFrameProtector.unprotect(buffer, messageBuffer); 49 * }</pre> 50 * 51 * <p>Implementations of this object must be thread compatible. 52 */ 53 public interface TsiHandshaker { 54 /** 55 * Gets bytes that need to be sent to the peer. 56 * 57 * @param bytes The buffer to put handshake bytes. 58 */ getBytesToSendToPeer(ByteBuffer bytes)59 void getBytesToSendToPeer(ByteBuffer bytes) throws GeneralSecurityException; 60 61 /** 62 * Process the bytes received from the peer. 63 * 64 * @param bytes The buffer containing the handshake bytes from the peer. 65 * @return true, if the handshake has all the data it needs to process and false, if the method 66 * must be called again to complete processing. 67 */ processBytesFromPeer(ByteBuffer bytes)68 boolean processBytesFromPeer(ByteBuffer bytes) throws GeneralSecurityException; 69 70 /** 71 * Returns true if and only if the handshake is still in progress 72 * 73 * @return true, if the handshake is still in progress, false otherwise. 74 */ isInProgress()75 boolean isInProgress(); 76 77 /** 78 * Returns the peer extracted from a completed handshake. 79 * 80 * @return the extracted peer. 81 */ extractPeer()82 TsiPeer extractPeer() throws GeneralSecurityException; 83 84 /** 85 * Returns the peer extracted from a completed handshake. 86 * 87 * @return the extracted peer. 88 */ extractPeerObject()89 public Object extractPeerObject() throws GeneralSecurityException; 90 91 /** 92 * Creates a frame protector from a completed handshake. No other methods may be called after the 93 * frame protector is created. 94 * 95 * @param maxFrameSize the requested max frame size, the callee is free to ignore. 96 * @param alloc used for allocating ByteBufs. 97 * @return a new TsiFrameProtector. 98 */ createFrameProtector(int maxFrameSize, ByteBufAllocator alloc)99 TsiFrameProtector createFrameProtector(int maxFrameSize, ByteBufAllocator alloc); 100 101 /** 102 * Creates a frame protector from a completed handshake. No other methods may be called after the 103 * frame protector is created. 104 * 105 * @param alloc used for allocating ByteBufs. 106 * @return a new TsiFrameProtector. 107 */ createFrameProtector(ByteBufAllocator alloc)108 TsiFrameProtector createFrameProtector(ByteBufAllocator alloc); 109 } 110