• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  **
3  ** Copyright 2020, The Android Open Source Project
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 #include "SocketTransport.h"
18 
19 #include <arpa/inet.h>
20 #include <errno.h>
21 #include <sys/socket.h>
22 #include <memory>
23 #include <vector>
24 
25 #include <android-base/logging.h>
26 
27 #include "ITransport.h"
28 
29 #define PORT 8080
30 #define IPADDR "192.168.9.112"
31 #define MAX_RECV_BUFFER_SIZE 2500
32 
33 namespace keymint::javacard {
34 using std::shared_ptr;
35 using std::vector;
36 
openConnection()37 bool SocketTransport::openConnection() {
38     struct sockaddr_in serv_addr;
39     if ((mSocket = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
40         LOG(ERROR) << "Socket creation failed"
41                    << " Error: " << strerror(errno);
42         return false;
43     }
44 
45     serv_addr.sin_family = AF_INET;
46     serv_addr.sin_port = htons(PORT);
47 
48     // Convert IPv4 and IPv6 addresses from text to binary form
49     if (inet_pton(AF_INET, IPADDR, &serv_addr.sin_addr) <= 0) {
50         LOG(ERROR) << "Invalid address/ Address not supported.";
51         return false;
52     }
53 
54     if (connect(mSocket, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0) {
55         close(mSocket);
56         LOG(ERROR) << "Connection failed. Error: " << strerror(errno);
57         return false;
58     }
59     socketStatus = true;
60     return true;
61 }
62 
sendData(const vector<uint8_t> & inData,vector<uint8_t> & output)63 bool SocketTransport::sendData(const vector<uint8_t>& inData, vector<uint8_t>& output) {
64     int count = 1;
65     while (!socketStatus && count++ < 5) {
66         sleep(1);
67         LOG(ERROR) << "Trying to open socket connection... count: " << count;
68         openConnection();
69     }
70 
71     if (count >= 5) {
72         LOG(ERROR) << "Failed to open socket connection";
73         return false;
74     }
75     // Prepend the input length to the inputData before sending.
76     vector<uint8_t> inDataPrependedLength;
77     inDataPrependedLength.push_back(static_cast<uint8_t>(inData.size() >> 8));
78     inDataPrependedLength.push_back(static_cast<uint8_t>(inData.size() & 0xFF));
79     inDataPrependedLength.insert(inDataPrependedLength.end(), inData.begin(), inData.end());
80 
81     if (0 >
82         send(mSocket, inDataPrependedLength.data(), inDataPrependedLength.size(), MSG_NOSIGNAL)) {
83         static int connectionResetCnt = 0; /* To avoid loop */
84         if ((ECONNRESET == errno || EPIPE == errno) && connectionResetCnt == 0) {
85             // Connection reset. Try open socket and then sendData.
86             socketStatus = false;
87             connectionResetCnt++;
88             return sendData(inData, output);
89         }
90         LOG(ERROR) << "Failed to send data over socket err: " << errno;
91         connectionResetCnt = 0;
92         return false;
93     }
94 
95     return readData(output);
96 }
97 
closeConnection()98 bool SocketTransport::closeConnection() {
99     close(mSocket);
100     socketStatus = false;
101     return true;
102 }
103 
isConnected()104 bool SocketTransport::isConnected() {
105     return socketStatus;
106 }
107 
readData(vector<uint8_t> & output)108 bool SocketTransport::readData(vector<uint8_t>& output) {
109     uint8_t buffer[MAX_RECV_BUFFER_SIZE];
110     ssize_t expectedResponseLen = 0;
111     ssize_t totalBytesRead = 0;
112     // The first 2 bytes in the response contains the expected response length.
113     do {
114         size_t i = 0;
115         ssize_t numBytes = read(mSocket, buffer, MAX_RECV_BUFFER_SIZE);
116         if (0 > numBytes) {
117           LOG(ERROR) << "Failed to read data from socket.";
118           return false;
119         }
120         totalBytesRead += numBytes;
121         if (expectedResponseLen == 0) {
122           // First two bytes in the response contains the expected response length.
123           expectedResponseLen |=  static_cast<ssize_t>(buffer[1] & 0xFF);
124           expectedResponseLen |=  static_cast<ssize_t>((buffer[0] << 8) & 0xFF00);
125           // 2 bytes for storing the length.
126           expectedResponseLen += 2;
127           i = 2;
128         }
129         for (; i < numBytes; i++) {
130           output.push_back(buffer[i]);
131         }
132     } while(totalBytesRead < expectedResponseLen);
133 
134     return true;
135 }
136 
137 }  // namespace keymint::javacard
138