diff options
Diffstat (limited to 'pjlib-util')
-rw-r--r-- | pjlib-util/src/pjlib-util-test/encryption.c | 103 | ||||
-rw-r--r-- | pjlib-util/src/pjlib-util/base64.c | 58 |
2 files changed, 91 insertions, 70 deletions
diff --git a/pjlib-util/src/pjlib-util-test/encryption.c b/pjlib-util/src/pjlib-util-test/encryption.c index 3db0d9a0..b0d3d6a8 100644 --- a/pjlib-util/src/pjlib-util-test/encryption.c +++ b/pjlib-util/src/pjlib-util-test/encryption.c @@ -494,6 +494,12 @@ static int crc32_test(void) return 0; } +enum +{ + ENCODE = 1, + DECODE = 2, + ENCODE_DECODE = 3 +}; /* * Base64 test vectors (RFC 4648) @@ -502,48 +508,70 @@ static struct base64_test_vec { const char *base256; const char *base64; + unsigned flag; } base64_test_vec[] = { { "", - "" + "", + ENCODE_DECODE }, { "f", - "Zg==" + "Zg==", + ENCODE_DECODE }, { "fo", - "Zm8=" + "Zm8=", + ENCODE_DECODE }, { "foo", - "Zm9v" + "Zm9v", + ENCODE_DECODE }, { "foob", - "Zm9vYg==" + "Zm9vYg==", + ENCODE_DECODE }, { "fooba", "Zm9vYmE=", + ENCODE_DECODE }, { "foobar", - "Zm9vYmFy" + "Zm9vYmFy", + ENCODE_DECODE }, { "\x14\xfb\x9c\x03\xd9\x7e", - "FPucA9l+" + "FPucA9l+", + ENCODE_DECODE }, { "\x14\xfb\x9c\x03\xd9", - "FPucA9k=" + "FPucA9k=", + ENCODE_DECODE }, { "\x14\xfb\x9c\x03", - "FPucAw==" - } + "FPucAw==", + ENCODE_DECODE + }, + /* with whitespaces */ + { + "foobar", + "Zm9v\r\nYmFy", + DECODE + }, + { + "foobar", + "\nZ\r\nm 9\tv\nYm\nF\ny\n", + DECODE + }, }; @@ -556,38 +584,43 @@ static int base64_test(void) PJ_LOG(3, (THIS_FILE, " base64 test..")); for (i=0; i<PJ_ARRAY_SIZE(base64_test_vec); ++i) { - /* Encode test */ pj_str_t input; - int out_len = sizeof(output); - - rc = pj_base64_encode((pj_uint8_t*)base64_test_vec[i].base256, - strlen(base64_test_vec[i].base256), - output, &out_len); - if (rc != PJ_SUCCESS) - return -90; + int out_len; - if (out_len != (int)strlen(base64_test_vec[i].base64)) - return -91; - - output[out_len] = '\0'; - if (strcmp(output, base64_test_vec[i].base64) != 0) - return -92; + /* Encode test */ + if (base64_test_vec[i].flag & ENCODE) { + out_len = sizeof(output); + rc = pj_base64_encode((pj_uint8_t*)base64_test_vec[i].base256, + strlen(base64_test_vec[i].base256), + output, &out_len); + if (rc != PJ_SUCCESS) + return -90; + + if (out_len != (int)strlen(base64_test_vec[i].base64)) + return -91; + + output[out_len] = '\0'; + if (strcmp(output, base64_test_vec[i].base64) != 0) + return -92; + } /* Decode test */ - out_len = sizeof(output); - input.ptr = (char*)base64_test_vec[i].base64; - input.slen = strlen(base64_test_vec[i].base64); - rc = pj_base64_decode(&input, (pj_uint8_t*)output, &out_len); - if (rc != PJ_SUCCESS) - return -95; + if (base64_test_vec[i].flag & DECODE) { + out_len = sizeof(output); + input.ptr = (char*)base64_test_vec[i].base64; + input.slen = strlen(base64_test_vec[i].base64); + rc = pj_base64_decode(&input, (pj_uint8_t*)output, &out_len); + if (rc != PJ_SUCCESS) + return -95; - if (out_len != (int)strlen(base64_test_vec[i].base256)) - return -96; + if (out_len != (int)strlen(base64_test_vec[i].base256)) + return -96; - output[out_len] = '\0'; + output[out_len] = '\0'; - if (strcmp(output, base64_test_vec[i].base256) != 0) - return -97; + if (strcmp(output, base64_test_vec[i].base256) != 0) + return -97; + } } return 0; diff --git a/pjlib-util/src/pjlib-util/base64.c b/pjlib-util/src/pjlib-util/base64.c index 63371fd4..3702ce3c 100644 --- a/pjlib-util/src/pjlib-util/base64.c +++ b/pjlib-util/src/pjlib-util/base64.c @@ -47,7 +47,9 @@ static int base256_char(char c) else if (c == '/') return (63); else { - pj_assert(!"Should not happen as '=' should have been filtered"); + /* It *may* happen on bad input, so this is not a good idea. + * pj_assert(!"Should not happen as '=' should have been filtered"); + */ return INV; } } @@ -124,8 +126,8 @@ PJ_DEF(pj_status_t) pj_base64_decode(const pj_str_t *input, { const char *buf = input->ptr; int len = input->slen; - int i, j; - int c1, c2, c3, c4; + int i, j, k; + int c[4]; PJ_ASSERT_RETURN(input && out && out_len, PJ_EINVAL); @@ -135,42 +137,28 @@ PJ_DEF(pj_status_t) pj_base64_decode(const pj_str_t *input, PJ_ASSERT_RETURN(*out_len >= PJ_BASE64_TO_BASE256_LEN(len), PJ_ETOOSMALL); - for (i=0, j=0; i+3 < len; i+=4) { - c1 = base256_char(buf[i]); - c2 = base256_char(buf[i+1]); - c3 = base256_char(buf[i+2]); - c4 = base256_char(buf[i+3]); - - out[j++] = (pj_uint8_t)((c1<<2) | ((c2 & 0x30)>>4)); - out[j++] = (pj_uint8_t)(((c2 & 0x0F)<<4) | ((c3 & 0x3C)>>2)); - out[j++] = (pj_uint8_t)(((c3 & 0x03)<<6) | (c4 & 0x3F)); - } - - if (i < len) { - c1 = base256_char(buf[i]); - - if (i+1 < len) - c2 = base256_char(buf[i+1]); - else - c2 = (INV); - - if (i+2 < len) - c3 = base256_char(buf[i+2]); - else - c3 = (INV); - - c4 = (INV); + for (i=0, j=0; i<len; ) { + /* Fill up c, silently ignoring invalid characters */ + for (k=0; k<4 && i<len; ++k) { + do { + c[k] = base256_char(buf[i++]); + } while (c[k]==INV && i<len); + } - if (c2 != INV) { - out[j++] = (pj_uint8_t)((c1<<2) | ((c2 & 0x30)>>4)); - if (c3 != INV) { - out[j++] = (pj_uint8_t)(((c2 & 0x0F)<<4) | ((c3 & 0x3C)>>2)); - if (c4 != INV) { - out[j++] = (pj_uint8_t)(((c3 & 0x03)<<6) | (c4 & 0x3F)); + if (k<4) { + if (k > 1) { + out[j++] = (pj_uint8_t)((c[0]<<2) | ((c[1] & 0x30)>>4)); + if (k > 2) { + out[j++] = (pj_uint8_t) + (((c[1] & 0x0F)<<4) | ((c[2] & 0x3C)>>2)); } } + break; } - + + out[j++] = (pj_uint8_t)((c[0]<<2) | ((c[1] & 0x30)>>4)); + out[j++] = (pj_uint8_t)(((c[1] & 0x0F)<<4) | ((c[2] & 0x3C)>>2)); + out[j++] = (pj_uint8_t)(((c[2] & 0x03)<<6) | (c[3] & 0x3F)); } pj_assert(j < *out_len); |