Line data Source code
1 : /*
2 : *
3 : * Copyright 2015, Google Inc.
4 : * All rights reserved.
5 : *
6 : * Redistribution and use in source and binary forms, with or without
7 : * modification, are permitted provided that the following conditions are
8 : * met:
9 : *
10 : * * Redistributions of source code must retain the above copyright
11 : * notice, this list of conditions and the following disclaimer.
12 : * * Redistributions in binary form must reproduce the above
13 : * copyright notice, this list of conditions and the following disclaimer
14 : * in the documentation and/or other materials provided with the
15 : * distribution.
16 : * * Neither the name of Google Inc. nor the names of its
17 : * contributors may be used to endorse or promote products derived from
18 : * this software without specific prior written permission.
19 : *
20 : * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 : * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 : * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 : * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 : * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 : * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 : * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 : * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 : * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 : * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 : * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 : *
32 : */
33 :
34 : #include "src/core/security/base64.h"
35 :
36 : #include <string.h>
37 :
38 : #include <grpc/support/alloc.h>
39 : #include <grpc/support/log.h>
40 : #include <grpc/support/slice.h>
41 : #include "test/core/util/test_config.h"
42 :
43 12 : static int buffers_are_equal(const unsigned char *buf1,
44 : const unsigned char *buf2, size_t size) {
45 : size_t i;
46 3072 : for (i = 0; i < size; i++) {
47 3060 : if (buf1[i] != buf2[i]) {
48 0 : gpr_log(GPR_ERROR, "buf1 and buf2 differ: buf1[%d] = %x vs buf2[%d] = %x",
49 0 : (int)i, buf1[i], (int)i, buf2[i]);
50 0 : return 0;
51 : }
52 : }
53 12 : return 1;
54 : }
55 :
56 4 : static void test_simple_encode_decode_b64(int url_safe, int multiline) {
57 4 : const char *hello = "hello";
58 4 : char *hello_b64 =
59 4 : grpc_base64_encode(hello, strlen(hello), url_safe, multiline);
60 4 : gpr_slice hello_slice = grpc_base64_decode(hello_b64, url_safe);
61 4 : GPR_ASSERT(GPR_SLICE_LENGTH(hello_slice) == strlen(hello));
62 4 : GPR_ASSERT(strncmp((const char *)GPR_SLICE_START_PTR(hello_slice), hello,
63 : GPR_SLICE_LENGTH(hello_slice)) == 0);
64 :
65 4 : gpr_slice_unref(hello_slice);
66 4 : gpr_free(hello_b64);
67 4 : }
68 :
69 4 : static void test_full_range_encode_decode_b64(int url_safe, int multiline) {
70 : unsigned char orig[256];
71 : size_t i;
72 : char *b64;
73 : gpr_slice orig_decoded;
74 4 : for (i = 0; i < sizeof(orig); i++) orig[i] = (gpr_uint8)i;
75 :
76 : /* Try all the different paddings. */
77 16 : for (i = 0; i < 3; i++) {
78 12 : b64 = grpc_base64_encode(orig, sizeof(orig) - i, url_safe, multiline);
79 12 : orig_decoded = grpc_base64_decode(b64, url_safe);
80 12 : GPR_ASSERT(GPR_SLICE_LENGTH(orig_decoded) == (sizeof(orig) - i));
81 12 : GPR_ASSERT(buffers_are_equal(orig, GPR_SLICE_START_PTR(orig_decoded),
82 : sizeof(orig) - i));
83 12 : gpr_slice_unref(orig_decoded);
84 12 : gpr_free(b64);
85 : }
86 4 : }
87 :
88 1 : static void test_simple_encode_decode_b64_no_multiline(void) {
89 1 : test_simple_encode_decode_b64(0, 0);
90 1 : }
91 :
92 1 : static void test_simple_encode_decode_b64_multiline(void) {
93 1 : test_simple_encode_decode_b64(0, 1);
94 1 : }
95 :
96 1 : static void test_simple_encode_decode_b64_urlsafe_no_multiline(void) {
97 1 : test_simple_encode_decode_b64(1, 0);
98 1 : }
99 :
100 1 : static void test_simple_encode_decode_b64_urlsafe_multiline(void) {
101 1 : test_simple_encode_decode_b64(1, 1);
102 1 : }
103 :
104 1 : static void test_full_range_encode_decode_b64_no_multiline(void) {
105 1 : test_full_range_encode_decode_b64(0, 0);
106 1 : }
107 :
108 1 : static void test_full_range_encode_decode_b64_multiline(void) {
109 1 : test_full_range_encode_decode_b64(0, 1);
110 1 : }
111 :
112 1 : static void test_full_range_encode_decode_b64_urlsafe_no_multiline(void) {
113 1 : test_full_range_encode_decode_b64(1, 0);
114 1 : }
115 :
116 1 : static void test_full_range_encode_decode_b64_urlsafe_multiline(void) {
117 1 : test_full_range_encode_decode_b64(1, 1);
118 1 : }
119 :
120 1 : static void test_url_safe_unsafe_mismtach_failure(void) {
121 : unsigned char orig[256];
122 : size_t i;
123 : char *b64;
124 : gpr_slice orig_decoded;
125 1 : int url_safe = 1;
126 1 : for (i = 0; i < sizeof(orig); i++) orig[i] = (gpr_uint8)i;
127 :
128 1 : b64 = grpc_base64_encode(orig, sizeof(orig), url_safe, 0);
129 1 : orig_decoded = grpc_base64_decode(b64, !url_safe);
130 1 : GPR_ASSERT(GPR_SLICE_IS_EMPTY(orig_decoded));
131 1 : gpr_free(b64);
132 1 : gpr_slice_unref(orig_decoded);
133 :
134 1 : b64 = grpc_base64_encode(orig, sizeof(orig), !url_safe, 0);
135 1 : orig_decoded = grpc_base64_decode(b64, url_safe);
136 1 : GPR_ASSERT(GPR_SLICE_IS_EMPTY(orig_decoded));
137 1 : gpr_free(b64);
138 1 : gpr_slice_unref(orig_decoded);
139 1 : }
140 :
141 1 : static void test_rfc4648_test_vectors(void) {
142 : char *b64;
143 :
144 1 : b64 = grpc_base64_encode("", 0, 0, 0);
145 1 : GPR_ASSERT(strcmp("", b64) == 0);
146 1 : gpr_free(b64);
147 :
148 1 : b64 = grpc_base64_encode("f", 1, 0, 0);
149 1 : GPR_ASSERT(strcmp("Zg==", b64) == 0);
150 1 : gpr_free(b64);
151 :
152 1 : b64 = grpc_base64_encode("fo", 2, 0, 0);
153 1 : GPR_ASSERT(strcmp("Zm8=", b64) == 0);
154 1 : gpr_free(b64);
155 :
156 1 : b64 = grpc_base64_encode("foo", 3, 0, 0);
157 1 : GPR_ASSERT(strcmp("Zm9v", b64) == 0);
158 1 : gpr_free(b64);
159 :
160 1 : b64 = grpc_base64_encode("foob", 4, 0, 0);
161 1 : GPR_ASSERT(strcmp("Zm9vYg==", b64) == 0);
162 1 : gpr_free(b64);
163 :
164 1 : b64 = grpc_base64_encode("fooba", 5, 0, 0);
165 1 : GPR_ASSERT(strcmp("Zm9vYmE=", b64) == 0);
166 1 : gpr_free(b64);
167 :
168 1 : b64 = grpc_base64_encode("foobar", 6, 0, 0);
169 1 : GPR_ASSERT(strcmp("Zm9vYmFy", b64) == 0);
170 1 : gpr_free(b64);
171 1 : }
172 :
173 1 : static void test_unpadded_decode(void) {
174 : gpr_slice decoded;
175 :
176 1 : decoded = grpc_base64_decode("Zm9vYmFy", 0);
177 1 : GPR_ASSERT(!GPR_SLICE_IS_EMPTY(decoded));
178 1 : GPR_ASSERT(gpr_slice_str_cmp(decoded, "foobar") == 0);
179 1 : gpr_slice_unref(decoded);
180 :
181 1 : decoded = grpc_base64_decode("Zm9vYmE", 0);
182 1 : GPR_ASSERT(!GPR_SLICE_IS_EMPTY(decoded));
183 1 : GPR_ASSERT(gpr_slice_str_cmp(decoded, "fooba") == 0);
184 1 : gpr_slice_unref(decoded);
185 :
186 1 : decoded = grpc_base64_decode("Zm9vYg", 0);
187 1 : GPR_ASSERT(!GPR_SLICE_IS_EMPTY(decoded));
188 1 : GPR_ASSERT(gpr_slice_str_cmp(decoded, "foob") == 0);
189 1 : gpr_slice_unref(decoded);
190 :
191 1 : decoded = grpc_base64_decode("Zm9v", 0);
192 1 : GPR_ASSERT(!GPR_SLICE_IS_EMPTY(decoded));
193 1 : GPR_ASSERT(gpr_slice_str_cmp(decoded, "foo") == 0);
194 1 : gpr_slice_unref(decoded);
195 :
196 1 : decoded = grpc_base64_decode("Zm8", 0);
197 1 : GPR_ASSERT(!GPR_SLICE_IS_EMPTY(decoded));
198 1 : GPR_ASSERT(gpr_slice_str_cmp(decoded, "fo") == 0);
199 1 : gpr_slice_unref(decoded);
200 :
201 1 : decoded = grpc_base64_decode("Zg", 0);
202 1 : GPR_ASSERT(!GPR_SLICE_IS_EMPTY(decoded));
203 1 : GPR_ASSERT(gpr_slice_str_cmp(decoded, "f") == 0);
204 1 : gpr_slice_unref(decoded);
205 :
206 1 : decoded = grpc_base64_decode("", 0);
207 1 : GPR_ASSERT(GPR_SLICE_IS_EMPTY(decoded));
208 1 : }
209 :
210 1 : int main(int argc, char **argv) {
211 1 : grpc_test_init(argc, argv);
212 1 : test_simple_encode_decode_b64_no_multiline();
213 1 : test_simple_encode_decode_b64_multiline();
214 1 : test_simple_encode_decode_b64_urlsafe_no_multiline();
215 1 : test_simple_encode_decode_b64_urlsafe_multiline();
216 1 : test_full_range_encode_decode_b64_no_multiline();
217 1 : test_full_range_encode_decode_b64_multiline();
218 1 : test_full_range_encode_decode_b64_urlsafe_no_multiline();
219 1 : test_full_range_encode_decode_b64_urlsafe_multiline();
220 1 : test_url_safe_unsafe_mismtach_failure();
221 1 : test_rfc4648_test_vectors();
222 1 : test_unpadded_decode();
223 1 : return 0;
224 : }
|