/* {{{ php_crypto_base64_decode_update */ static inline int php_crypto_base64_decode_update( EVP_ENCODE_CTX *ctx, char *out, int *outl, const char *in, phpc_str_size_t in_len TSRMLS_DC) { int inl, rc; /* check string length overflow */ if (php_crypto_str_size_to_int(in_len, &inl) == FAILURE) { php_crypto_error(PHP_CRYPTO_ERROR_ARGS(Base64, INPUT_DATA_LENGTH_HIGH)); return FAILURE; } rc = EVP_DecodeUpdate(ctx, (unsigned char *) out, outl, (const unsigned char *) in, inl); if (rc < 0) { php_crypto_error(PHP_CRYPTO_ERROR_ARGS(Base64, DECODE_UPDATE_FAILED)); return FAILURE; } return SUCCESS; }
/* {{{ proto Crypto\Base64::decodeFinish() Decodes characters that left in the encoding context */ PHP_CRYPTO_METHOD(Base64, decodeFinish) { char buff[PHP_CRYPTO_BASE64_DECODING_SIZE_MIN]; int final_len; PHPC_THIS_DECLARE(crypto_base64); if (zend_parse_parameters_none() == FAILURE) { return; } PHPC_THIS_FETCH(crypto_base64); if (PHPC_THIS->status != PHP_CRYPTO_BASE64_STATUS_DECODE) { php_crypto_error(PHP_CRYPTO_ERROR_ARGS(Base64, DECODE_FINISH_FORBIDDEN)); RETURN_FALSE; } php_crypto_base64_decode_finish(PHPC_THIS->ctx, buff, &final_len); if (final_len == 0) { RETURN_EMPTY_STRING(); } buff[final_len] = 0; PHPC_CSTRL_RETURN(buff, final_len); }
/* {{{ proto Crypto\Base64::decode(string $data) Decodes block of characters from $data and saves the reminder of the last block to the encoding context */ PHP_CRYPTO_METHOD(Base64, decodeUpdate) { char *in; phpc_str_size_t in_len; int update_len, real_len; PHPC_STR_DECLARE(out); PHPC_THIS_DECLARE(crypto_base64); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &in, &in_len) == FAILURE) { return; } PHPC_THIS_FETCH(crypto_base64); if (PHPC_THIS->status == PHP_CRYPTO_BASE64_STATUS_ENCODE) { php_crypto_error(PHP_CRYPTO_ERROR_ARGS(Base64, DECODE_UPDATE_FORBIDDEN)); RETURN_FALSE; } if (PHPC_THIS->status == PHP_CRYPTO_BASE64_STATUS_CLEAR) { php_crypto_base64_decode_init(PHPC_THIS->ctx); PHPC_THIS->status = PHP_CRYPTO_BASE64_STATUS_DECODE; } real_len = EVP_DECODE_LENGTH(in_len); PHPC_STR_ALLOC(out, real_len); if (php_crypto_base64_decode_update(PHPC_THIS->ctx, PHPC_STR_VAL(out), &update_len, in, in_len TSRMLS_CC) == FAILURE) { PHPC_STR_RELEASE(out); RETURN_FALSE; } if (real_len > update_len) { PHPC_STR_REALLOC(out, update_len); } PHPC_STR_VAL(out)[update_len] = '\0'; PHPC_STR_RETURN(out); }
/* {{{ proto Crypto\Base64::encodeFinish() Encodes characters that left in the encoding context */ PHP_CRYPTO_METHOD(Base64, encodeFinish) { char out[PHP_CRYPTO_BASE64_ENCODING_SIZE_MIN+1]; int out_len; PHPC_THIS_DECLARE(crypto_base64); if (zend_parse_parameters_none() == FAILURE) { return; } PHPC_THIS_FETCH(crypto_base64); if (PHPC_THIS->status != PHP_CRYPTO_BASE64_STATUS_ENCODE) { php_crypto_error(PHP_CRYPTO_ERROR_ARGS(Base64, ENCODE_FINISH_FORBIDDEN)); RETURN_FALSE; } php_crypto_base64_encode_finish(PHPC_THIS->ctx, out, &out_len); if (out_len == 0) { RETURN_EMPTY_STRING(); } out[out_len] = '\0'; PHPC_CSTRL_RETURN(out, out_len); }
/* {{{ php_crypto_get_cipher_algorithm_from_params_ex */ static const EVP_CIPHER *php_crypto_get_cipher_algorithm_from_params_ex( zval *object, char *algorithm, phpc_str_size_t algorithm_len, zval *pz_mode, zval *pz_key_size, zend_bool is_static TSRMLS_DC) { const EVP_CIPHER *cipher; phpc_smart_cstr alg_buf = {0}; /* if mode is not set, then it is already contained in the algorithm string */ if (!pz_mode || Z_TYPE_P(pz_mode) == IS_NULL) { cipher = php_crypto_get_cipher_algorithm(algorithm, algorithm_len); if (!cipher) { if (is_static) { php_crypto_error_ex(PHP_CRYPTO_ERROR_ARGS(Cipher, STATIC_METHOD_NOT_FOUND), algorithm); } else { php_crypto_error_ex(PHP_CRYPTO_ERROR_ARGS(Cipher, ALGORITHM_NOT_FOUND), algorithm); } } else if (object) { php_crypto_cipher_set_algorithm_name(object, algorithm, algorithm_len TSRMLS_CC); } return cipher; } phpc_smart_cstr_appendl(&alg_buf, algorithm, algorithm_len); phpc_smart_cstr_appendc(&alg_buf, '-'); /* copy key size if available */ if (pz_key_size && Z_TYPE_P(pz_key_size) != IS_NULL) { if (Z_TYPE_P(pz_key_size) == IS_STRING) { phpc_smart_cstr_appendl(&alg_buf, Z_STRVAL_P(pz_key_size), Z_STRLEN_P(pz_key_size)); } else { zval z_key_size = *pz_key_size; zval_copy_ctor(&z_key_size); convert_to_string(&z_key_size); phpc_smart_cstr_appendl(&alg_buf, Z_STRVAL(z_key_size), Z_STRLEN(z_key_size)); phpc_smart_cstr_appendc(&alg_buf, '-'); zval_dtor(&z_key_size); } } /* copy mode */ if (Z_TYPE_P(pz_mode) == IS_LONG) { const php_crypto_cipher_mode *mode = php_crypto_get_cipher_mode_ex(Z_LVAL_P(pz_mode)); if (!mode) { php_crypto_error_ex(PHP_CRYPTO_ERROR_ARGS(Cipher, MODE_NOT_FOUND)); phpc_smart_cstr_free(&alg_buf); return NULL; } if (mode->value == PHP_CRYPTO_CIPHER_MODE_NOT_DEFINED) { php_crypto_error_ex(PHP_CRYPTO_ERROR_ARGS(Cipher, MODE_NOT_AVAILABLE), mode->name); phpc_smart_cstr_free(&alg_buf); return NULL; } phpc_smart_cstr_appendl(&alg_buf, mode->name, PHP_CRYPTO_CIPHER_MODE_LEN); } else if (Z_TYPE_P(pz_mode) == IS_STRING) { phpc_smart_cstr_appendl(&alg_buf, Z_STRVAL_P(pz_mode), Z_STRLEN_P(pz_mode)); } else { zval z_mode = *pz_mode; zval_copy_ctor(&z_mode); convert_to_string(&z_mode); phpc_smart_cstr_appendl(&alg_buf, Z_STRVAL(z_mode), Z_STRLEN(z_mode)); zval_dtor(&z_mode); } phpc_smart_cstr_0(&alg_buf); cipher = php_crypto_get_cipher_algorithm(alg_buf.c, alg_buf.len); if (!cipher) { if (is_static) { php_crypto_error_ex(PHP_CRYPTO_ERROR_ARGS(Cipher, STATIC_METHOD_NOT_FOUND), alg_buf.c); } else { php_crypto_error_ex(PHP_CRYPTO_ERROR_ARGS(Cipher, ALGORITHM_NOT_FOUND), alg_buf.c); } } else if (object) { php_crypto_cipher_set_algorithm_name(object, alg_buf.c, alg_buf.len TSRMLS_CC); } phpc_smart_cstr_free(&alg_buf); return cipher; }