From e22094eb1390759ecfe28178cf67d8a80aebbfbb Mon Sep 17 00:00:00 2001 From: Frank Denis Date: Mon, 2 Oct 2017 21:43:54 +0200 Subject: [PATCH] ext/sodium: +base64 codecs (timing-safe) --- ext/sodium/libsodium.c | 87 ++++++++++++++++++++++++++++++++++++++ ext/sodium/php_libsodium.h | 2 + 2 files changed, 89 insertions(+) diff --git a/ext/sodium/libsodium.c b/ext/sodium/libsodium.c index 62245d5604..07d2c5e038 100644 --- a/ext/sodium/libsodium.c +++ b/ext/sodium/libsodium.c @@ -317,6 +317,10 @@ const zend_function_entry sodium_functions[] = { PHP_FE(sodium_bin2hex, AI_String) PHP_FE(sodium_hex2bin, AI_StringAndMaybeString) +#ifdef sodium_base64_VARIANT_ORIGINAL + PHP_FE(sodium_bin2base64, AI_StringAndId) + PHP_FE(sodium_base642bin, AI_StringAndIdAndMaybeString) +#endif /* aliases */ @@ -564,6 +568,16 @@ PHP_MINIT_FUNCTION(sodium) crypto_stream_NONCEBYTES, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_STREAM_KEYBYTES", crypto_stream_KEYBYTES, CONST_CS | CONST_PERSISTENT); +#ifdef sodium_base64_VARIANT_ORIGINAL + REGISTER_LONG_CONSTANT("SODIUM_BASE64_VARIANT_ORIGINAL", + sodium_base64_VARIANT_ORIGINAL, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SODIUM_BASE64_VARIANT_ORIGINAL_NO_PADDING", + sodium_base64_VARIANT_ORIGINAL_NO_PADDING, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SODIUM_BASE64_VARIANT_URLSAFE", + sodium_base64_VARIANT_URLSAFE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SODIUM_BASE64_VARIANT_URLSAFE_NO_PADDING", + sodium_base64_VARIANT_URLSAFE_NO_PADDING, CONST_CS | CONST_PERSISTENT); +#endif return SUCCESS; } @@ -2639,6 +2653,79 @@ PHP_FUNCTION(sodium_hex2bin) RETURN_STR(bin); } +#ifdef sodium_base64_VARIANT_ORIGINAL +PHP_FUNCTION(sodium_bin2base64) +{ + zend_string *b64; + unsigned char *bin; + zend_long variant; + size_t bin_len; + size_t b64_len; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "sl", + &bin, &bin_len, &variant) == FAILURE) { + return; + } + if ((((unsigned int) variant) & ~ 0x6U) != 0x1U) { + zend_throw_exception(sodium_exception_ce, + "invalid base64 variant identifier", 0); + return; + } + if (bin_len >= SIZE_MAX / 4U * 3U - 3U - 1U) { + zend_throw_exception(sodium_exception_ce, "arithmetic overflow", 0); + return; + } + b64_len = sodium_base64_ENCODED_LEN(bin_len, variant); + b64 = zend_string_alloc((size_t) b64_len - 1U, 0); + sodium_bin2base64(ZSTR_VAL(b64), b64_len, bin, bin_len, (int) variant); + + RETURN_STR(b64); +} + +PHP_FUNCTION(sodium_base642bin) +{ + zend_string *bin; + char *b64; + const char *end; + char *ignore = NULL; + zend_long variant; + size_t bin_real_len; + size_t bin_len; + size_t b64_len; + size_t ignore_len = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "sl|s", + &b64, &b64_len, &variant, + &ignore, &ignore_len) == FAILURE) { + return; + } + if ((((unsigned int) variant) & ~ 0x6U) != 0x1U) { + zend_throw_exception(sodium_exception_ce, + "invalid base64 variant identifier", 0); + return; + } + bin_len = b64_len / 4U * 3U; + bin = zend_string_alloc(bin_len, 0); + if (sodium_base642bin((unsigned char *) ZSTR_VAL(bin), bin_len, + b64, b64_len, + ignore, &bin_real_len, &end, (int) variant) != 0 || + end != b64 + b64_len) { + zend_string_free(bin); + zend_throw_exception(sodium_exception_ce, "invalid base64 string", 0); + return; + } + if (bin_real_len >= SIZE_MAX || bin_real_len > bin_len) { + zend_string_free(bin); + zend_throw_exception(sodium_exception_ce, "arithmetic overflow", 0); + return; + } + PHP_SODIUM_ZSTR_TRUNCATE(bin, (size_t) bin_real_len); + ZSTR_VAL(bin)[bin_real_len] = 0; + + RETURN_STR(bin); +} +#endif + PHP_FUNCTION(sodium_crypto_scalarmult) { zend_string *q; diff --git a/ext/sodium/php_libsodium.h b/ext/sodium/php_libsodium.h index acaca2a16d..d586a2b7dc 100644 --- a/ext/sodium/php_libsodium.h +++ b/ext/sodium/php_libsodium.h @@ -35,6 +35,8 @@ PHP_RSHUTDOWN_FUNCTION(sodium); PHP_MINFO_FUNCTION(sodium); PHP_FUNCTION(sodium_add); +PHP_FUNCTION(sodium_base642bin); +PHP_FUNCTION(sodium_bin2base64); PHP_FUNCTION(sodium_bin2hex); PHP_FUNCTION(sodium_compare); PHP_FUNCTION(sodium_crypto_aead_aes256gcm_decrypt); -- 2.50.1