google.golang.org/grpc@v1.74.2/credentials/alts/internal/conn/common.go (about) 1 /* 2 * 3 * Copyright 2018 gRPC authors. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 */ 18 19 package conn 20 21 import ( 22 "encoding/binary" 23 "errors" 24 "fmt" 25 ) 26 27 const ( 28 // GcmTagSize is the GCM tag size is the difference in length between 29 // plaintext and ciphertext. From crypto/cipher/gcm.go in Go crypto 30 // library. 31 GcmTagSize = 16 32 ) 33 34 // ErrAuth occurs on authentication failure. 35 var ErrAuth = errors.New("message authentication failed") 36 37 // SliceForAppend takes a slice and a requested number of bytes. It returns a 38 // slice with the contents of the given slice followed by that many bytes and a 39 // second slice that aliases into it and contains only the extra bytes. If the 40 // original slice has sufficient capacity then no allocation is performed. 41 func SliceForAppend(in []byte, n int) (head, tail []byte) { 42 if total := len(in) + n; cap(in) >= total { 43 head = in[:total] 44 } else { 45 head = make([]byte, total) 46 copy(head, in) 47 } 48 tail = head[len(in):] 49 return head, tail 50 } 51 52 // ParseFramedMsg parse the provided buffer and returns a frame of the format 53 // msgLength+msg and any remaining bytes in that buffer. 54 func ParseFramedMsg(b []byte, maxLen uint32) ([]byte, []byte, error) { 55 // If the size field is not complete, return the provided buffer as 56 // remaining buffer. 57 length, sufficientBytes := parseMessageLength(b) 58 if !sufficientBytes { 59 return nil, b, nil 60 } 61 if length > maxLen { 62 return nil, nil, fmt.Errorf("received the frame length %d larger than the limit %d", length, maxLen) 63 } 64 if len(b) < int(length)+4 { // account for the first 4 msg length bytes. 65 // Frame is not complete yet. 66 return nil, b, nil 67 } 68 return b[:MsgLenFieldSize+length], b[MsgLenFieldSize+length:], nil 69 } 70 71 // parseMessageLength returns the message length based on frame header. It also 72 // returns a boolean indicating if the buffer contains sufficient bytes to parse 73 // the length header. If there are insufficient bytes, (0, false) is returned. 74 func parseMessageLength(b []byte) (uint32, bool) { 75 if len(b) < MsgLenFieldSize { 76 return 0, false 77 } 78 msgLenField := b[:MsgLenFieldSize] 79 return binary.LittleEndian.Uint32(msgLenField), true 80 }