Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
G
Grpc
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Container Registry
Model registry
Operate
Environments
Monitor
Incidents
Service Desk
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
tci-gateway-module
Grpc
Commits
6ab0de15
Commit
6ab0de15
authored
9 years ago
by
Nicolas Noble
Browse files
Options
Downloads
Plain Diff
Merge pull request #2216 from jboeuf/unpadded_base64
Base64 decode improvements
parents
89933071
73d8b57a
No related branches found
No related tags found
No related merge requests found
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
src/core/security/base64.c
+66
-33
66 additions, 33 deletions
src/core/security/base64.c
src/core/security/base64.h
+4
-0
4 additions, 0 deletions
src/core/security/base64.h
test/core/security/base64_test.c
+38
-0
38 additions, 0 deletions
test/core/security/base64_test.c
with
108 additions
and
33 deletions
src/core/security/base64.c
+
66
−
33
View file @
6ab0de15
...
@@ -120,7 +120,68 @@ char *grpc_base64_encode(const void *vdata, size_t data_size, int url_safe,
...
@@ -120,7 +120,68 @@ char *grpc_base64_encode(const void *vdata, size_t data_size, int url_safe,
}
}
gpr_slice
grpc_base64_decode
(
const
char
*
b64
,
int
url_safe
)
{
gpr_slice
grpc_base64_decode
(
const
char
*
b64
,
int
url_safe
)
{
size_t
b64_len
=
strlen
(
b64
);
return
grpc_base64_decode_with_len
(
b64
,
strlen
(
b64
),
url_safe
);
}
static
void
decode_one_char
(
const
unsigned
char
*
codes
,
unsigned
char
*
result
,
size_t
*
result_offset
)
{
gpr_uint32
packed
=
(
codes
[
0
]
<<
2
)
|
(
codes
[
1
]
>>
4
);
result
[(
*
result_offset
)
++
]
=
(
unsigned
char
)
packed
;
}
static
void
decode_two_chars
(
const
unsigned
char
*
codes
,
unsigned
char
*
result
,
size_t
*
result_offset
)
{
gpr_uint32
packed
=
(
codes
[
0
]
<<
10
)
|
(
codes
[
1
]
<<
4
)
|
(
codes
[
2
]
>>
2
);
result
[(
*
result_offset
)
++
]
=
(
unsigned
char
)(
packed
>>
8
);
result
[(
*
result_offset
)
++
]
=
(
unsigned
char
)(
packed
);
}
static
int
decode_group
(
const
unsigned
char
*
codes
,
size_t
num_codes
,
unsigned
char
*
result
,
size_t
*
result_offset
)
{
GPR_ASSERT
(
num_codes
<=
4
);
/* Short end groups that may not have padding. */
if
(
num_codes
==
1
)
{
gpr_log
(
GPR_ERROR
,
"Invalid group. Must be at least 2 bytes."
);
return
0
;
}
if
(
num_codes
==
2
)
{
decode_one_char
(
codes
,
result
,
result_offset
);
return
1
;
}
if
(
num_codes
==
3
)
{
decode_two_chars
(
codes
,
result
,
result_offset
);
return
1
;
}
/* Regular 4 byte groups with padding or not. */
GPR_ASSERT
(
num_codes
==
4
);
if
(
codes
[
0
]
==
GRPC_BASE64_PAD_BYTE
||
codes
[
1
]
==
GRPC_BASE64_PAD_BYTE
)
{
gpr_log
(
GPR_ERROR
,
"Invalid padding detected."
);
return
0
;
}
if
(
codes
[
2
]
==
GRPC_BASE64_PAD_BYTE
)
{
if
(
codes
[
3
]
==
GRPC_BASE64_PAD_BYTE
)
{
decode_one_char
(
codes
,
result
,
result_offset
);
}
else
{
gpr_log
(
GPR_ERROR
,
"Invalid padding detected."
);
return
0
;
}
}
else
if
(
codes
[
3
]
==
GRPC_BASE64_PAD_BYTE
)
{
decode_two_chars
(
codes
,
result
,
result_offset
);
}
else
{
/* No padding. */
gpr_uint32
packed
=
(
codes
[
0
]
<<
18
)
|
(
codes
[
1
]
<<
12
)
|
(
codes
[
2
]
<<
6
)
|
codes
[
3
];
result
[(
*
result_offset
)
++
]
=
(
unsigned
char
)(
packed
>>
16
);
result
[(
*
result_offset
)
++
]
=
(
unsigned
char
)(
packed
>>
8
);
result
[(
*
result_offset
)
++
]
=
(
unsigned
char
)(
packed
);
}
return
1
;
}
gpr_slice
grpc_base64_decode_with_len
(
const
char
*
b64
,
size_t
b64_len
,
int
url_safe
)
{
gpr_slice
result
=
gpr_slice_malloc
(
b64_len
);
gpr_slice
result
=
gpr_slice_malloc
(
b64_len
);
unsigned
char
*
current
=
GPR_SLICE_START_PTR
(
result
);
unsigned
char
*
current
=
GPR_SLICE_START_PTR
(
result
);
size_t
result_size
=
0
;
size_t
result_size
=
0
;
...
@@ -151,43 +212,15 @@ gpr_slice grpc_base64_decode(const char *b64, int url_safe) {
...
@@ -151,43 +212,15 @@ gpr_slice grpc_base64_decode(const char *b64, int url_safe) {
}
else
{
}
else
{
codes
[
num_codes
++
]
=
(
unsigned
char
)
code
;
codes
[
num_codes
++
]
=
(
unsigned
char
)
code
;
if
(
num_codes
==
4
)
{
if
(
num_codes
==
4
)
{
if
(
codes
[
0
]
==
GRPC_BASE64_PAD_BYTE
||
if
(
!
decode_group
(
codes
,
num_codes
,
current
,
&
result_size
))
goto
fail
;
codes
[
1
]
==
GRPC_BASE64_PAD_BYTE
)
{
gpr_log
(
GPR_ERROR
,
"Invalid padding detected."
);
goto
fail
;
}
if
(
codes
[
2
]
==
GRPC_BASE64_PAD_BYTE
)
{
if
(
codes
[
3
]
==
GRPC_BASE64_PAD_BYTE
)
{
/* Double padding. */
gpr_uint32
packed
=
(
gpr_uint32
)((
codes
[
0
]
<<
2
)
|
(
codes
[
1
]
>>
4
));
current
[
result_size
++
]
=
(
unsigned
char
)
packed
;
}
else
{
gpr_log
(
GPR_ERROR
,
"Invalid padding detected."
);
goto
fail
;
}
}
else
if
(
codes
[
3
]
==
GRPC_BASE64_PAD_BYTE
)
{
/* Single padding. */
gpr_uint32
packed
=
(
gpr_uint32
)((
codes
[
0
]
<<
10
)
|
(
codes
[
1
]
<<
4
)
|
(
codes
[
2
]
>>
2
));
current
[
result_size
++
]
=
(
unsigned
char
)(
packed
>>
8
);
current
[
result_size
++
]
=
(
unsigned
char
)(
packed
);
}
else
{
/* No padding. */
gpr_uint32
packed
=
(
gpr_uint32
)((
codes
[
0
]
<<
18
)
|
(
codes
[
1
]
<<
12
)
|
(
codes
[
2
]
<<
6
)
|
codes
[
3
]);
current
[
result_size
++
]
=
(
unsigned
char
)(
packed
>>
16
);
current
[
result_size
++
]
=
(
unsigned
char
)(
packed
>>
8
);
current
[
result_size
++
]
=
(
unsigned
char
)(
packed
);
}
num_codes
=
0
;
num_codes
=
0
;
}
}
}
}
}
}
if
(
num_codes
!=
0
)
{
if
(
num_codes
!=
0
&&
gpr_log
(
GPR_ERROR
,
"Invalid base64."
);
!
decode_group
(
codes
,
num_codes
,
current
,
&
result_size
))
{
gpr_slice_unref
(
result
);
goto
fail
;
return
gpr_empty_slice
();
}
}
GPR_SLICE_SET_LENGTH
(
result
,
result_size
);
GPR_SLICE_SET_LENGTH
(
result
,
result_size
);
return
result
;
return
result
;
...
...
This diff is collapsed.
Click to expand it.
src/core/security/base64.h
+
4
−
0
View file @
6ab0de15
...
@@ -45,4 +45,8 @@ char *grpc_base64_encode(const void *data, size_t data_size, int url_safe,
...
@@ -45,4 +45,8 @@ char *grpc_base64_encode(const void *data, size_t data_size, int url_safe,
slice in case of failure. */
slice in case of failure. */
gpr_slice
grpc_base64_decode
(
const
char
*
b64
,
int
url_safe
);
gpr_slice
grpc_base64_decode
(
const
char
*
b64
,
int
url_safe
);
/* Same as above except that the length is provided by the caller. */
gpr_slice
grpc_base64_decode_with_len
(
const
char
*
b64
,
size_t
b64_len
,
int
url_safe
);
#endif
/* GRPC_INTERNAL_CORE_SECURITY_BASE64_H */
#endif
/* GRPC_INTERNAL_CORE_SECURITY_BASE64_H */
This diff is collapsed.
Click to expand it.
test/core/security/base64_test.c
+
38
−
0
View file @
6ab0de15
...
@@ -169,6 +169,43 @@ static void test_rfc4648_test_vectors(void) {
...
@@ -169,6 +169,43 @@ static void test_rfc4648_test_vectors(void) {
gpr_free
(
b64
);
gpr_free
(
b64
);
}
}
static
void
test_unpadded_decode
(
void
)
{
gpr_slice
decoded
;
decoded
=
grpc_base64_decode
(
"Zm9vYmFy"
,
0
);
GPR_ASSERT
(
!
GPR_SLICE_IS_EMPTY
(
decoded
));
GPR_ASSERT
(
gpr_slice_str_cmp
(
decoded
,
"foobar"
)
==
0
);
gpr_slice_unref
(
decoded
);
decoded
=
grpc_base64_decode
(
"Zm9vYmE"
,
0
);
GPR_ASSERT
(
!
GPR_SLICE_IS_EMPTY
(
decoded
));
GPR_ASSERT
(
gpr_slice_str_cmp
(
decoded
,
"fooba"
)
==
0
);
gpr_slice_unref
(
decoded
);
decoded
=
grpc_base64_decode
(
"Zm9vYg"
,
0
);
GPR_ASSERT
(
!
GPR_SLICE_IS_EMPTY
(
decoded
));
GPR_ASSERT
(
gpr_slice_str_cmp
(
decoded
,
"foob"
)
==
0
);
gpr_slice_unref
(
decoded
);
decoded
=
grpc_base64_decode
(
"Zm9v"
,
0
);
GPR_ASSERT
(
!
GPR_SLICE_IS_EMPTY
(
decoded
));
GPR_ASSERT
(
gpr_slice_str_cmp
(
decoded
,
"foo"
)
==
0
);
gpr_slice_unref
(
decoded
);
decoded
=
grpc_base64_decode
(
"Zm8"
,
0
);
GPR_ASSERT
(
!
GPR_SLICE_IS_EMPTY
(
decoded
));
GPR_ASSERT
(
gpr_slice_str_cmp
(
decoded
,
"fo"
)
==
0
);
gpr_slice_unref
(
decoded
);
decoded
=
grpc_base64_decode
(
"Zg"
,
0
);
GPR_ASSERT
(
!
GPR_SLICE_IS_EMPTY
(
decoded
));
GPR_ASSERT
(
gpr_slice_str_cmp
(
decoded
,
"f"
)
==
0
);
gpr_slice_unref
(
decoded
);
decoded
=
grpc_base64_decode
(
""
,
0
);
GPR_ASSERT
(
GPR_SLICE_IS_EMPTY
(
decoded
));
}
int
main
(
int
argc
,
char
**
argv
)
{
int
main
(
int
argc
,
char
**
argv
)
{
grpc_test_init
(
argc
,
argv
);
grpc_test_init
(
argc
,
argv
);
test_simple_encode_decode_b64_no_multiline
();
test_simple_encode_decode_b64_no_multiline
();
...
@@ -181,5 +218,6 @@ int main(int argc, char **argv) {
...
@@ -181,5 +218,6 @@ int main(int argc, char **argv) {
test_full_range_encode_decode_b64_urlsafe_multiline
();
test_full_range_encode_decode_b64_urlsafe_multiline
();
test_url_safe_unsafe_mismtach_failure
();
test_url_safe_unsafe_mismtach_failure
();
test_rfc4648_test_vectors
();
test_rfc4648_test_vectors
();
test_unpadded_decode
();
return
0
;
return
0
;
}
}
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment