Skip to content

Commit ca6ae59

Browse files
authored
chore: add support for new style Dafny test vectors (#817)
* chore: add support for new style Dafny test vectors
1 parent 019b106 commit ca6ae59

File tree

506 files changed

+27162
-2
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

506 files changed

+27162
-2
lines changed

.github/workflows/clang-format.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,4 @@ jobs:
1313
source: '.'
1414
exclude: 'docker-images,doxygen,examples,testing-resources'
1515
extensions: 'h,c,cpp'
16-
clangFormatVersion: 9
16+
clangFormatVersion: 9

.github/workflows/osx.yml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@ jobs:
1515
os: [macos-13, macos-latest-large]
1616
openssl_version: [[email protected]]
1717

18+
permissions:
19+
id-token: write
20+
contents: read
21+
1822
steps:
1923
- run: brew install ${{ matrix.openssl_version }}
2024

@@ -53,6 +57,13 @@ jobs:
5357
xcodebuild -target ALL_BUILD
5458
xcodebuild -target install
5559
60+
- name: Configure AWS Credentials
61+
uses: aws-actions/configure-aws-credentials@v2
62+
with:
63+
aws-region: us-west-2
64+
role-to-assume: arn:aws:iam::370957321024:role/GitHub-CI-Public-ESDK-Dafny-Role-us-west-2
65+
role-session-name: CESDKTests
66+
5667
- name: Build C-ESDK
5768
env:
5869
OPENSSL_VERSION: ${{ matrix.openssl_version }}
@@ -63,3 +74,10 @@ jobs:
6374
cmake -G Xcode -DBUILD_SHARED_LIBS=ON -DCMAKE_INSTALL_PREFIX=${{github.workspace}}/install -DCMAKE_PREFIX_PATH=${{github.workspace}}/install -DOPENSSL_ROOT_DIR="/usr/local/opt/${OPENSSL_VERSION}" ../
6475
xcodebuild -target ALL_BUILD
6576
xcodebuild -scheme RUN_TESTS
77+
78+
- name: Run Interop Test Vectors
79+
run: |
80+
cd tests/TestVectors/
81+
make decrypt_dafny
82+
make encrypt
83+
make decrypt

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
# limitations under the License.
1313
#
1414

15-
cmake_minimum_required (VERSION 3.9)
15+
cmake_minimum_required (VERSION 3.10)
1616
project (aws-encryption-sdk LANGUAGES C)
1717

1818
include(GNUInstallDirs)
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
json.h

tests/TestVectors/.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
local
2+
test_vectors*

tests/TestVectors/Makefile

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
test_vectors: *.cpp *.h
2+
g++ -g -ggdb --std=c++14 -o test_vectors -I../../include/ \
3+
base64.cpp do_decrypt.cpp do_encrypt.cpp parse_encrypt.cpp parse_keys.cpp test_vectors.cpp \
4+
-I/opt/homebrew/include/ -L/opt/homebrew/lib/ \
5+
-I../../install/include/ -L../../install/lib/ -I ../../aws-encryption-sdk-cpp/include/ \
6+
../../build-aws-encryption-sdk-c/Debug/libaws-encryption-sdk.dylib \
7+
../../build-aws-encryption-sdk-c/aws-encryption-sdk-cpp/Debug/libaws-encryption-sdk-cpp.dylib \
8+
-laws-cpp-sdk-core -laws-cpp-sdk-kms -laws-c-common -lcrypto
9+
install_name_tool -add_rpath ../../build-aws-encryption-sdk-c/Debug/ test_vectors
10+
install_name_tool -add_rpath ../../build-aws-encryption-sdk-c/aws-encryption-sdk-cpp/Debug/ test_vectors
11+
install_name_tool -add_rpath ../../install/lib/ test_vectors
12+
13+
decrypt_dafny: test_vectors
14+
./test_vectors decrypt --manifest-path ./from-dafny --manifest-name decrypt-manifest.json || exit 1
15+
16+
encrypt: test_vectors
17+
rm -rf local
18+
mkdir -p local
19+
./test_vectors encrypt --manifest-path ./from-dafny --decrypt-manifest-path ./local || exit 1
20+
21+
decrypt: test_vectors
22+
./test_vectors decrypt --manifest-path ./local --manifest-name decrypt-manifest.json || exit 1
23+
24+
clean:
25+
rm -f test_vectors

tests/TestVectors/base64.cpp

Lines changed: 284 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,284 @@
1+
/*
2+
base64.cpp and base64.h
3+
4+
base64 encoding and decoding with C++.
5+
More information at
6+
https://renenyffenegger.ch/notes/development/Base64/Encoding-and-decoding-base-64-with-cpp
7+
8+
Version: 2.rc.09 (release candidate)
9+
10+
Copyright (C) 2004-2017, 2020-2022 René Nyffenegger
11+
12+
This source code is provided 'as-is', without any express or implied
13+
warranty. In no event will the author be held liable for any damages
14+
arising from the use of this software.
15+
16+
Permission is granted to anyone to use this software for any purpose,
17+
including commercial applications, and to alter it and redistribute it
18+
freely, subject to the following restrictions:
19+
20+
1. The origin of this source code must not be misrepresented; you must not
21+
claim that you wrote the original source code. If you use this source code
22+
in a product, an acknowledgment in the product documentation would be
23+
appreciated but is not required.
24+
25+
2. Altered source versions must be plainly marked as such, and must not be
26+
misrepresented as being the original source code.
27+
28+
3. This notice may not be removed or altered from any source distribution.
29+
30+
René Nyffenegger [email protected]
31+
32+
*/
33+
34+
#include "base64.h"
35+
36+
#include <algorithm>
37+
#include <stdexcept>
38+
39+
//
40+
// Depending on the url parameter in base64_chars, one of
41+
// two sets of base64 characters needs to be chosen.
42+
// They differ in their last two characters.
43+
//
44+
static const char *base64_chars[2] = {
45+
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
46+
"abcdefghijklmnopqrstuvwxyz"
47+
"0123456789"
48+
"+/",
49+
50+
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
51+
"abcdefghijklmnopqrstuvwxyz"
52+
"0123456789"
53+
"-_"
54+
};
55+
56+
static unsigned int pos_of_char(const unsigned char chr) {
57+
//
58+
// Return the position of chr within base64_encode()
59+
//
60+
61+
if (chr >= 'A' && chr <= 'Z')
62+
return chr - 'A';
63+
else if (chr >= 'a' && chr <= 'z')
64+
return chr - 'a' + ('Z' - 'A') + 1;
65+
else if (chr >= '0' && chr <= '9')
66+
return chr - '0' + ('Z' - 'A') + ('z' - 'a') + 2;
67+
else if (chr == '+' || chr == '-')
68+
return 62; // Be liberal with input and accept both url ('-') and non-url ('+') base 64 characters (
69+
else if (chr == '/' || chr == '_')
70+
return 63; // Ditto for '/' and '_'
71+
else
72+
//
73+
// 2020-10-23: Throw std::exception rather than const char*
74+
//(Pablo Martin-Gomez, https://github.com/Bouska)
75+
//
76+
throw std::runtime_error("Input is not valid base64-encoded data.");
77+
}
78+
79+
static std::string insert_linebreaks(std::string str, size_t distance) {
80+
//
81+
// Provided by https://github.com/JomaCorpFX, adapted by me.
82+
//
83+
if (!str.length()) {
84+
return "";
85+
}
86+
87+
size_t pos = distance;
88+
89+
while (pos < str.size()) {
90+
str.insert(pos, "\n");
91+
pos += distance + 1;
92+
}
93+
94+
return str;
95+
}
96+
97+
template <typename String, unsigned int line_length>
98+
static std::string encode_with_line_breaks(String s) {
99+
return insert_linebreaks(base64_encode(s, false), line_length);
100+
}
101+
102+
template <typename String>
103+
static std::string encode_pem(String s) {
104+
return encode_with_line_breaks<String, 64>(s);
105+
}
106+
107+
template <typename String>
108+
static std::string encode_mime(String s) {
109+
return encode_with_line_breaks<String, 76>(s);
110+
}
111+
112+
template <typename String>
113+
static std::string encode(String s, bool url) {
114+
return base64_encode(reinterpret_cast<const unsigned char *>(s.data()), s.length(), url);
115+
}
116+
117+
std::string base64_encode(unsigned char const *bytes_to_encode, size_t in_len, bool url) {
118+
size_t len_encoded = (in_len + 2) / 3 * 4;
119+
120+
unsigned char trailing_char = url ? '.' : '=';
121+
122+
//
123+
// Choose set of base64 characters. They differ
124+
// for the last two positions, depending on the url
125+
// parameter.
126+
// A bool (as is the parameter url) is guaranteed
127+
// to evaluate to either 0 or 1 in C++ therefore,
128+
// the correct character set is chosen by subscripting
129+
// base64_chars with url.
130+
//
131+
const char *base64_chars_ = base64_chars[url];
132+
133+
std::string ret;
134+
ret.reserve(len_encoded);
135+
136+
unsigned int pos = 0;
137+
138+
while (pos < in_len) {
139+
ret.push_back(base64_chars_[(bytes_to_encode[pos + 0] & 0xfc) >> 2]);
140+
141+
if (pos + 1 < in_len) {
142+
ret.push_back(
143+
base64_chars_[((bytes_to_encode[pos + 0] & 0x03) << 4) + ((bytes_to_encode[pos + 1] & 0xf0) >> 4)]);
144+
145+
if (pos + 2 < in_len) {
146+
ret.push_back(
147+
base64_chars_[((bytes_to_encode[pos + 1] & 0x0f) << 2) + ((bytes_to_encode[pos + 2] & 0xc0) >> 6)]);
148+
ret.push_back(base64_chars_[bytes_to_encode[pos + 2] & 0x3f]);
149+
} else {
150+
ret.push_back(base64_chars_[(bytes_to_encode[pos + 1] & 0x0f) << 2]);
151+
ret.push_back(trailing_char);
152+
}
153+
} else {
154+
ret.push_back(base64_chars_[(bytes_to_encode[pos + 0] & 0x03) << 4]);
155+
ret.push_back(trailing_char);
156+
ret.push_back(trailing_char);
157+
}
158+
159+
pos += 3;
160+
}
161+
162+
return ret;
163+
}
164+
165+
template <typename String>
166+
static std::string decode(String const &encoded_string, bool remove_linebreaks) {
167+
//
168+
// decode(…) is templated so that it can be used with String = const std::string&
169+
// or std::string_view (requires at least C++17)
170+
//
171+
172+
if (encoded_string.empty()) return std::string();
173+
174+
if (remove_linebreaks) {
175+
std::string copy(encoded_string);
176+
177+
copy.erase(std::remove(copy.begin(), copy.end(), '\n'), copy.end());
178+
179+
return base64_decode(copy, false);
180+
}
181+
182+
size_t length_of_string = encoded_string.length();
183+
size_t pos = 0;
184+
185+
//
186+
// The approximate length (bytes) of the decoded string might be one or
187+
// two bytes smaller, depending on the amount of trailing equal signs
188+
// in the encoded string. This approximation is needed to reserve
189+
// enough space in the string to be returned.
190+
//
191+
size_t approx_length_of_decoded_string = length_of_string / 4 * 3;
192+
std::string ret;
193+
ret.reserve(approx_length_of_decoded_string);
194+
195+
while (pos < length_of_string) {
196+
//
197+
// Iterate over encoded input string in chunks. The size of all
198+
// chunks except the last one is 4 bytes.
199+
//
200+
// The last chunk might be padded with equal signs or dots
201+
// in order to make it 4 bytes in size as well, but this
202+
// is not required as per RFC 2045.
203+
//
204+
// All chunks except the last one produce three output bytes.
205+
//
206+
// The last chunk produces at least one and up to three bytes.
207+
//
208+
209+
size_t pos_of_char_1 = pos_of_char(encoded_string.at(pos + 1));
210+
211+
//
212+
// Emit the first output byte that is produced in each chunk:
213+
//
214+
ret.push_back(static_cast<std::string::value_type>(
215+
((pos_of_char(encoded_string.at(pos + 0))) << 2) + ((pos_of_char_1 & 0x30) >> 4)));
216+
217+
if ((pos + 2 <
218+
length_of_string) && // Check for data that is not padded with equal signs (which is allowed by RFC 2045)
219+
encoded_string.at(pos + 2) != '=' &&
220+
encoded_string.at(pos + 2) != '.' // accept URL-safe base 64 strings, too, so check for '.' also.
221+
) {
222+
//
223+
// Emit a chunk's second byte (which might not be produced in the last chunk).
224+
//
225+
unsigned int pos_of_char_2 = pos_of_char(encoded_string.at(pos + 2));
226+
ret.push_back(
227+
static_cast<std::string::value_type>(((pos_of_char_1 & 0x0f) << 4) + ((pos_of_char_2 & 0x3c) >> 2)));
228+
229+
if ((pos + 3 < length_of_string) && encoded_string.at(pos + 3) != '=' &&
230+
encoded_string.at(pos + 3) != '.') {
231+
//
232+
// Emit a chunk's third byte (which might not be produced in the last chunk).
233+
//
234+
ret.push_back(static_cast<std::string::value_type>(
235+
((pos_of_char_2 & 0x03) << 6) + pos_of_char(encoded_string.at(pos + 3))));
236+
}
237+
}
238+
239+
pos += 4;
240+
}
241+
242+
return ret;
243+
}
244+
245+
std::string base64_decode(std::string const &s, bool remove_linebreaks) {
246+
return decode(s, remove_linebreaks);
247+
}
248+
249+
std::string base64_encode(std::string const &s, bool url) {
250+
return encode(s, url);
251+
}
252+
253+
std::string base64_encode_pem(std::string const &s) {
254+
return encode_pem(s);
255+
}
256+
257+
std::string base64_encode_mime(std::string const &s) {
258+
return encode_mime(s);
259+
}
260+
261+
#if __cplusplus >= 201703L
262+
//
263+
// Interface with std::string_view rather than const std::string&
264+
// Requires C++17
265+
// Provided by Yannic Bonenberger (https://github.com/Yannic)
266+
//
267+
268+
std::string base64_encode(std::string_view s, bool url) {
269+
return encode(s, url);
270+
}
271+
272+
std::string base64_encode_pem(std::string_view s) {
273+
return encode_pem(s);
274+
}
275+
276+
std::string base64_encode_mime(std::string_view s) {
277+
return encode_mime(s);
278+
}
279+
280+
std::string base64_decode(std::string_view s, bool remove_linebreaks) {
281+
return decode(s, remove_linebreaks);
282+
}
283+
284+
#endif // __cplusplus >= 201703L

0 commit comments

Comments
 (0)