Thanks to visit codestin.com
Credit goes to github.com

Skip to content
This repository was archived by the owner on Aug 15, 2018. It is now read-only.

Commit f4d8395

Browse files
author
Jinesh Varia
committed
rearranging the files and folders
1 parent 554e86d commit f4d8395

28 files changed

+14388
-0
lines changed

.DS_Store

12 KB
Binary file not shown.

src/.DS_Store

6 KB
Binary file not shown.

src/common/AWSClient.cpp

Lines changed: 356 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,356 @@
1+
/*
2+
* AWSClient.cpp
3+
*
4+
* See AWSClient.h for description.
5+
*
6+
* Created on: Jul 8, 2014
7+
* Author: hoffmaj
8+
*/
9+
10+
#include "AWSClient.h"
11+
#include "Utils.h"
12+
#include "DeviceIndependentInterfaces.h"
13+
#include "AWSFoundationalTypes.h"
14+
#include "sha256.h"
15+
#include <string.h>
16+
#include <stdlib.h>
17+
#include <stdio.h>
18+
19+
/* Constants string, formats, and lengths. */
20+
static const char* CANONICAL_FORM_POST_LINE = "POST\n/\n\n";
21+
static const int CANONICAL_FORM_POST_LINE_LEN = 8;
22+
static const char* HTTPS_REQUEST_POST_LINE =
23+
"POST https://%s.%s.%s/ HTTPS/1.1\n";
24+
static const int HTTPS_REQUEST_POST_LINE_LEN = 29;
25+
static const char* HTTP_REQUEST_POST_LINE = "POST http://%s.%s.%s/ HTTP/1.1\n";
26+
static const int HTTP_REQUEST_POST_LINE_LEN = 27;
27+
static const char* CURL_START = "curl --silent -X POST ";
28+
static const int CURL_START_LEN = 22;
29+
static const char* HTTPS_CURL_END = "https://%s.%s.%s";
30+
static const int HTTPS_CURL_END_LEN = 10;
31+
static const char* HTTP_CURL_END = "http://%s.%s.%s";
32+
static const int HTTP_CURL_END_LEN = 9;
33+
static const char* TO_SIGN_TEMPLATE =
34+
"AWS4-HMAC-SHA256\n%sT%sZ\n%s/%s/%s/aws4_request\n%s";
35+
static const int TO_SIGN_TEMPLATE_LEN = 36;
36+
static const char* CONTENT_LENGTH_HEADER = "content-length:%d";
37+
static const int CONTENT_LENGTH_HEADER_LEN = 15;
38+
static const char* HOST_HEADER = "host:%s.%s.%s";
39+
static const int HOST_HEADER_LEN = 7;
40+
static const char* CONNECTION_HEADER = "Connection:close";
41+
static const int CONNECTION_HEADER_LEN = 16;
42+
static const char* CONTENT_TYPE_HEADER = "content-type:%s";
43+
static const int CONTENT_TYPE_HEADER_LEN = 13;
44+
static const char* X_AMZ_DATE_HEADER = "x-amz-date:%sT%sZ";
45+
static const int X_AMZ_DATE_HEADER_LEN = 13;
46+
static const char* X_AMZ_TARGET_HEADER = "x-amz-target:%s";
47+
static const int X_AMZ_TARGET_HEADER_LEN = 13;
48+
static const char* AUTHORIZATION_HEADER =
49+
"Authorization: AWS4-HMAC-SHA256 Credential=%s/%s/%s/%s/aws4_request, SignedHeaders=%s, Signature=%s";
50+
static const int AUTHORIZATION_HEADER_LEN = 87;
51+
static const char* SIGNED_HEADERS =
52+
"content-length;content-type;host;x-amz-date;x-amz-target";
53+
static const int SIGNED_HEADERS_LEN = 56;
54+
55+
AWSClient::AWSClient() {
56+
/* Null until set in init method. */
57+
awsRegion = 0;
58+
awsEndpoint = 0;
59+
awsSecKey = 0;
60+
awsKeyID = 0;
61+
httpClient = 0;
62+
dateTimeProvider = 0;
63+
}
64+
65+
void AWSClient::setAWSRegion(const char * awsRegion) {
66+
int len = strlen(awsRegion) + 1;
67+
this->awsRegion = new char[len]();
68+
strcpy(this->awsRegion, awsRegion);
69+
}
70+
void AWSClient::setAWSEndpoint(const char * awsEndpoint) {
71+
int len = strlen(awsEndpoint) + 1;
72+
this->awsEndpoint = new char[len]();
73+
strcpy(this->awsEndpoint, awsEndpoint);
74+
}
75+
void AWSClient::setAWSSecretKey(const char * awsSecKey) {
76+
int len = strlen(awsSecKey) + 1;
77+
this->awsSecKey = new char[len]();
78+
strcpy(this->awsSecKey, awsSecKey);
79+
}
80+
void AWSClient::setAWSKeyID(const char * awsKeyID) {
81+
int len = strlen(awsKeyID) + 1;
82+
this->awsKeyID = new char[len]();
83+
strcpy(this->awsKeyID, awsKeyID);
84+
}
85+
void AWSClient::setHttpClient(IHttpClient* httpClient) {
86+
this->httpClient = httpClient;
87+
}
88+
void AWSClient::setDateTimeProvider(IDateTimeProvider* dateTimeProvider) {
89+
this->dateTimeProvider = dateTimeProvider;
90+
}
91+
92+
AWSClient::~AWSClient() {
93+
if (awsRegion != 0)
94+
delete[] awsRegion;
95+
if (awsEndpoint != 0)
96+
delete[] awsEndpoint;
97+
if (awsSecKey != 0)
98+
delete[] awsSecKey;
99+
if (awsKeyID != 0)
100+
delete[] awsKeyID;
101+
}
102+
103+
void AWSClient::initSignedHeaders() {
104+
/* For each of the formats for unsigned headers, determine the size of the
105+
* formatted string, allocate that much space in the next available element
106+
* in the headers array, create the string, and add it's length to the
107+
* headerLens array. */
108+
109+
int contentLen = payload.length();
110+
int len = CONTENT_LENGTH_HEADER_LEN + digitCount(contentLen);
111+
headers[headersCreated] = new char[len + 1]();
112+
sprintf(headers[headersCreated], CONTENT_LENGTH_HEADER, contentLen);
113+
headerLens[headersCreated++] = len;
114+
115+
len = CONTENT_TYPE_HEADER_LEN + strlen(contentType);
116+
headers[headersCreated] = new char[len + 1]();
117+
sprintf(headers[headersCreated], CONTENT_TYPE_HEADER, contentType);
118+
headerLens[headersCreated++] = len;
119+
120+
len = HOST_HEADER_LEN + strlen(awsService) + strlen(awsRegion)
121+
+ strlen(awsEndpoint);
122+
headers[headersCreated] = new char[len + 1]();
123+
sprintf(headers[headersCreated], HOST_HEADER, awsService, awsRegion,
124+
awsEndpoint);
125+
headerLens[headersCreated++] = len;
126+
127+
len = X_AMZ_DATE_HEADER_LEN + AWS_DATE_LEN + AWS_TIME_LEN;
128+
headers[headersCreated] = new char[len + 1]();
129+
sprintf(headers[headersCreated], X_AMZ_DATE_HEADER, awsDate, awsTime);
130+
headerLens[headersCreated++] = len;
131+
132+
len = X_AMZ_TARGET_HEADER_LEN + strlen(target);
133+
headers[headersCreated] = new char[len + 1]();
134+
sprintf(headers[headersCreated], X_AMZ_TARGET_HEADER, target);
135+
headerLens[headersCreated++] = len;
136+
}
137+
138+
char* AWSClient::createStringToSign(void) {
139+
SHA256* sha256 = new SHA256();
140+
char* hashed;
141+
/* Calculate length of canonicalForm string. */
142+
int canonicalFormLen = CANONICAL_FORM_POST_LINE_LEN;
143+
for (int i = 0; i < headersCreated; i++) {
144+
/* +1 for newlines */
145+
canonicalFormLen += *(headerLens + i) + 1;
146+
}
147+
/* +2 for newlines. */
148+
canonicalFormLen += SIGNED_HEADERS_LEN + HASH_HEX_LEN + 2;
149+
150+
char* canonicalForm = new char[canonicalFormLen + 1]();
151+
152+
/* Write the cannonicalForm string. */
153+
int canonicalFormWritten = 0;
154+
canonicalFormWritten += strlen(
155+
strcpy(canonicalForm + canonicalFormWritten,
156+
CANONICAL_FORM_POST_LINE));
157+
for (int i = 0; i < headersCreated; i++) {
158+
canonicalFormWritten += sprintf(canonicalForm + canonicalFormWritten,
159+
"%s\n", *(headers + i));
160+
}
161+
canonicalFormWritten += sprintf(canonicalForm + canonicalFormWritten,
162+
"\n%s\n", SIGNED_HEADERS);
163+
hashed = (*sha256)(payload.getCStr(), payload.length());
164+
strcpy(canonicalForm + canonicalFormWritten, hashed);
165+
delete[] hashed;
166+
canonicalFormWritten += HASH_HEX_LEN;
167+
168+
/* Hash the canonicalForm string. */
169+
hashed = (*sha256)(canonicalForm, canonicalFormWritten);
170+
delete sha256;
171+
172+
delete[] canonicalForm;
173+
174+
/* Determine the size to the string to sign. */
175+
int toSignLen = TO_SIGN_TEMPLATE_LEN + 2 * AWS_DATE_LEN + AWS_TIME_LEN
176+
+ strlen(awsRegion) + strlen(awsService) + HASH_HEX_LEN;
177+
178+
/* Create and return the string to sign. */
179+
char* toSign = new char[toSignLen + 1]();
180+
sprintf(toSign, TO_SIGN_TEMPLATE, awsDate, awsTime, awsDate, awsRegion,
181+
awsService, hashed);
182+
delete[] hashed;
183+
return toSign;
184+
185+
}
186+
char* AWSClient::createSignature(const char* toSign) {
187+
188+
/* Allocate memory for the signature */
189+
char* signature = new char[HASH_HEX_LEN + 1]();
190+
191+
/* Create the signature key */
192+
/* + 4 for "AWS4" */
193+
int keyLen = strlen(awsSecKey) + 4;
194+
char* key = new char[keyLen + 1]();
195+
sprintf(key, "AWS4%s", awsSecKey);
196+
197+
/* repeatedly apply hmac with the appropriate values. See
198+
* http://docs.aws.amazon.com/general/latest/gr/sigv4-calculate-signature.html
199+
* for algorithm. */
200+
char* k1 = hmacSha256(key, keyLen, awsDate, strlen(awsDate));
201+
delete[] key;
202+
char* k2 = hmacSha256(k1, SHA256_DEC_HASH_LEN, awsRegion,
203+
strlen(awsRegion));
204+
delete[] k1;
205+
char* k3 = hmacSha256(k2, SHA256_DEC_HASH_LEN, awsService,
206+
strlen(awsService));
207+
delete[] k2;
208+
char* k4 = hmacSha256(k3, SHA256_DEC_HASH_LEN, "aws4_request", 12);
209+
delete[] k3;
210+
char* k5 = hmacSha256(k4, SHA256_DEC_HASH_LEN, toSign, strlen(toSign));
211+
delete[] k4;
212+
213+
/* Convert the chars in hash to hex for signature. */
214+
for (int i = 0; i < SHA256_DEC_HASH_LEN; ++i) {
215+
sprintf(signature + 2 * i, "%02lx", 0xff & (unsigned long) k5[i]);
216+
}
217+
delete[] k5;
218+
return signature;
219+
}
220+
221+
void AWSClient::initUnsignedHeaders(const char* signature) {
222+
int len = AUTHORIZATION_HEADER_LEN + strlen(awsKeyID) + AWS_DATE_LEN
223+
+ strlen(awsRegion) + strlen(awsService) + SIGNED_HEADERS_LEN
224+
+ HASH_HEX_LEN;
225+
headers[headersCreated] = new char[len + 1]();
226+
sprintf(headers[headersCreated], AUTHORIZATION_HEADER, awsKeyID, awsDate,
227+
awsRegion, awsService, SIGNED_HEADERS, signature);
228+
headerLens[headersCreated++] = len;
229+
230+
len = CONNECTION_HEADER_LEN;
231+
headers[headersCreated] = new char[len + 1]();
232+
strcpy(headers[headersCreated], CONNECTION_HEADER);
233+
headerLens[headersCreated++] = len;
234+
}
235+
236+
void AWSClient::createRequestInit(MinimalString &reqPayload) {
237+
//initialize object-scoped variables
238+
const char* dateTime = dateTimeProvider->getDateTime();
239+
sprintf(awsDate, "%.8s", dateTime);
240+
sprintf(awsTime, "%.6s", dateTime + 8);
241+
payload = reqPayload;
242+
headersCreated = 0;
243+
244+
//Create signature and headers
245+
initSignedHeaders();
246+
char* toSign = createStringToSign();
247+
char* signature = createSignature(toSign);
248+
delete[] toSign;
249+
initUnsignedHeaders(signature);
250+
delete[] signature;
251+
}
252+
253+
void AWSClient::createRequestCleanup() {
254+
/* Free each header */
255+
for (int i = 0; i < headersCreated; i++) {
256+
delete[] headers[i];
257+
}
258+
}
259+
260+
char* AWSClient::headersToRequest() {
261+
/* Determine whether to use https or http postLine values. */
262+
int postLineLen =
263+
httpS ? HTTPS_REQUEST_POST_LINE_LEN : HTTP_REQUEST_POST_LINE_LEN;
264+
const char* postLine =
265+
httpS ? HTTPS_REQUEST_POST_LINE : HTTP_REQUEST_POST_LINE;
266+
267+
/* Calculate length of httpRequest string. */
268+
int httpRequestLen = postLineLen + strlen(awsService) + strlen(awsRegion)
269+
+ strlen(awsEndpoint);
270+
for (int i = 0; i < headersCreated; i++) {
271+
/* +1 for newline. */
272+
httpRequestLen += *(headerLens + i) + 1;
273+
}
274+
/* +1 for newline. */
275+
httpRequestLen += payload.length() + 1;
276+
277+
/* Create and write to the httpRequest string. */
278+
char* httpRequest = new char[httpRequestLen + 1]();
279+
int httpRequestWritten = 0;
280+
httpRequestWritten += sprintf(httpRequest + httpRequestWritten, postLine,
281+
awsService, awsRegion, awsEndpoint);
282+
for (int i = 0; i < headersCreated; i++) {
283+
httpRequestWritten += sprintf(httpRequest + httpRequestWritten, "%s\n",
284+
*(headers + i));
285+
}
286+
httpRequestWritten += sprintf(httpRequest + httpRequestWritten, "\n%s",
287+
payload.getCStr());
288+
289+
return httpRequest;
290+
}
291+
292+
char* AWSClient::headersToCurlRequest() {
293+
/* Add backslashes before quotes in json string */
294+
char* escapedPayload = escapeQuotes(payload.getCStr());
295+
296+
/* Determine whether to use https or http curlEnd values. */
297+
int curlEndLen = httpS ? HTTPS_CURL_END_LEN : HTTP_CURL_END_LEN;
298+
const char* curlEnd = httpS ? HTTPS_CURL_END : HTTP_CURL_END;
299+
300+
/* Calculate length of curl command. +6 for "-d", 2 spaces, 2 quotes. */
301+
int httpRequestLen = CURL_START_LEN + curlEndLen + strlen(awsService)
302+
+ strlen(awsRegion) + strlen(awsEndpoint) + strlen(escapedPayload)
303+
+ 6;
304+
for (int i = 0; i < headersCreated; i++) {
305+
/* +6 for "-H", 2 spaces, 2 quotes */
306+
httpRequestLen += *(headerLens + i) + 6;
307+
}
308+
309+
/* Create and write to the httpRequest string. */
310+
char* httpRequest = new char[httpRequestLen + 1]();
311+
int httpRequestWritten = 0;
312+
httpRequestWritten += strlen(strcpy(httpRequest, CURL_START));
313+
for (int i = 0; i < headersCreated; i++) {
314+
httpRequestWritten += sprintf(httpRequest + httpRequestWritten,
315+
"-H \"%s\" ", *(headers + i));
316+
}
317+
httpRequestWritten += sprintf(httpRequest + httpRequestWritten,
318+
"-d \"%s\" ", escapedPayload);
319+
delete[] escapedPayload;
320+
httpRequestWritten += sprintf(httpRequest + httpRequestWritten, curlEnd,
321+
awsService, awsRegion, awsEndpoint);
322+
323+
return httpRequest;
324+
}
325+
326+
char* AWSClient::createRequest(MinimalString &reqPayload) {
327+
/* Check that all values have been initialized. */
328+
if (awsRegion == 0 || awsEndpoint == 0 || awsSecKey == 0 || awsKeyID == 0
329+
|| httpClient == 0 || dateTimeProvider == 0)
330+
return 0;
331+
createRequestInit(reqPayload);
332+
char* request = headersToRequest();
333+
createRequestCleanup();
334+
return request;
335+
}
336+
337+
char* AWSClient::createCurlRequest(MinimalString &reqPayload) {
338+
/* Check that all values have been initialized. */
339+
if (awsRegion == 0 || awsEndpoint == 0 || awsSecKey == 0 || awsKeyID == 0
340+
|| httpClient == 0 || dateTimeProvider == 0)
341+
return 0;
342+
createRequestInit(reqPayload);
343+
char* request = headersToCurlRequest();
344+
createRequestCleanup();
345+
return request;
346+
}
347+
348+
char* AWSClient::sendData(const char* data) {
349+
char* server = new char[strlen(awsService) + strlen(awsRegion)
350+
+ strlen(awsEndpoint) + 4]();
351+
sprintf(server, "%s.%s.%s", awsService, awsRegion, awsEndpoint);
352+
int port = httpS ? 443 : 80;
353+
char* response = httpClient->send(data, server, port);
354+
delete[] server;
355+
return response;
356+
}

0 commit comments

Comments
 (0)