Skip to content

Commit f0372a5

Browse files
committed
PHPC-1499: Implement ClientEncryption::decrypt
1 parent 4d7b35e commit f0372a5

File tree

4 files changed

+79
-0
lines changed

4 files changed

+79
-0
lines changed

php_phongo.c

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3191,6 +3191,25 @@ void phongo_clientencryption_encrypt(php_phongo_clientencryption_t* clientencryp
31913191
mongoc_client_encryption_encrypt_opts_destroy(opts);
31923192
}
31933193
} /* }}} */
3194+
3195+
void phongo_clientencryption_decrypt(php_phongo_clientencryption_t* clientencryption, zval* zciphertext, zval* zvalue TSRMLS_DC) /* {{{ */
3196+
{
3197+
bson_value_t ciphertext, value;
3198+
bson_error_t error = { 0 };
3199+
3200+
php_phongo_zval_to_bson_value(zciphertext, PHONGO_BSON_NONE, &ciphertext TSRMLS_CC);
3201+
3202+
if (!mongoc_client_encryption_decrypt(clientencryption->client_encryption, &ciphertext, &value, &error)) {
3203+
phongo_throw_exception_from_bson_error_t(&error TSRMLS_CC);
3204+
return;
3205+
}
3206+
3207+
if (!php_phongo_bson_value_to_zval(&value, zvalue)) {
3208+
/* Exception already thrown */
3209+
return;
3210+
}
3211+
}
3212+
/* }}} */
31943213
#else /* MONGOC_ENABLE_CLIENT_SIDE_ENCRYPTION */
31953214
static void phongo_throw_exception_no_cse(php_phongo_error_domain_t domain, const char* message TSRMLS_DC) /* {{{ */
31963215
{
@@ -3227,6 +3246,12 @@ void phongo_clientencryption_encrypt(php_phongo_clientencryption_t* clientencryp
32273246
phongo_throw_exception_no_cse(PHONGO_ERROR_RUNTIME, "Cannot encrypt value." TSRMLS_CC);
32283247
}
32293248
/* }}} */
3249+
3250+
void phongo_clientencryption_decrypt(php_phongo_clientencryption_t* clientencryption, zval* zciphertext, zval* zvalue TSRMLS_DC) /* {{{ */
3251+
{
3252+
phongo_throw_exception_no_cse(PHONGO_ERROR_RUNTIME, "Cannot decrypt value." TSRMLS_CC);
3253+
}
3254+
/* }}} */
32303255
#endif
32313256

32323257
void phongo_manager_init(php_phongo_manager_t* manager, const char* uri_string, zval* options, zval* driverOptions TSRMLS_DC) /* {{{ */

php_phongo.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,7 @@ bool php_phongo_parse_int64(int64_t* retval, const char* data, phongo_zpp_char_l
169169

170170
void phongo_clientencryption_create_datakey(php_phongo_clientencryption_t* clientencryption, zval* return_value, char* kms_provider, zval* options TSRMLS_DC);
171171
void phongo_clientencryption_encrypt(php_phongo_clientencryption_t* clientencryption, zval* zvalue, zval* zciphertext, zval* options TSRMLS_DC);
172+
void phongo_clientencryption_decrypt(php_phongo_clientencryption_t* clientencryption, zval* zciphertext, zval* zvalue TSRMLS_DC);
172173

173174
zend_bool phongo_writeerror_init(zval* return_value, bson_t* bson TSRMLS_DC);
174175
zend_bool phongo_writeconcernerror_init(zval* return_value, bson_t* bson TSRMLS_DC);

src/MongoDB/ClientEncryption.c

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,27 @@ static PHP_METHOD(ClientEncryption, encrypt)
7171
phongo_clientencryption_encrypt(intern, value, return_value, options TSRMLS_CC);
7272
} /* }}} */
7373

74+
/* {{{ proto mixed MongoDB\Driver\ClientEncryption::decrypt(MongoDB\BSON\BinaryInterface $value)
75+
Decrypts an encrypted value (BSON binary of subtype 6). Returns the original BSON value */
76+
static PHP_METHOD(ClientEncryption, decrypt)
77+
{
78+
zval* ciphertext;
79+
zend_error_handling error_handling;
80+
php_phongo_clientencryption_t* intern;
81+
82+
intern = Z_CLIENTENCRYPTION_OBJ_P(getThis());
83+
zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling TSRMLS_CC);
84+
85+
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &ciphertext, php_phongo_binary_interface_ce) == FAILURE) {
86+
zend_restore_error_handling(&error_handling TSRMLS_CC);
87+
return;
88+
}
89+
90+
zend_restore_error_handling(&error_handling TSRMLS_CC);
91+
92+
phongo_clientencryption_decrypt(intern, ciphertext, return_value TSRMLS_CC);
93+
} /* }}} */
94+
7495
ZEND_BEGIN_ARG_INFO_EX(ai_ClientEncryption_createDataKey, 0, 0, 1)
7596
ZEND_ARG_INFO(0, kmsProvider)
7697
ZEND_ARG_ARRAY_INFO(0, options, 1)
@@ -81,13 +102,18 @@ ZEND_BEGIN_ARG_INFO_EX(ai_ClientEncryption_encrypt, 0, 0, 1)
81102
ZEND_ARG_ARRAY_INFO(0, options, 1)
82103
ZEND_END_ARG_INFO()
83104

105+
ZEND_BEGIN_ARG_INFO_EX(ai_ClientEncryption_decrypt, 0, 0, 1)
106+
ZEND_ARG_OBJ_INFO(0, keyVaultClient, MongoDB\\BSON\\BinaryInterface, 0)
107+
ZEND_END_ARG_INFO()
108+
84109
ZEND_BEGIN_ARG_INFO_EX(ai_ClientEncryption_void, 0, 0, 0)
85110
ZEND_END_ARG_INFO()
86111

87112
static zend_function_entry php_phongo_clientencryption_me[] = {
88113
/* clang-format off */
89114
PHP_ME(ClientEncryption, createDataKey, ai_ClientEncryption_createDataKey, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
90115
PHP_ME(ClientEncryption, encrypt, ai_ClientEncryption_encrypt, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
116+
PHP_ME(ClientEncryption, decrypt, ai_ClientEncryption_decrypt, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
91117
ZEND_NAMED_ME(__construct, PHP_FN(MongoDB_disabled___construct), ai_ClientEncryption_void, ZEND_ACC_PRIVATE | ZEND_ACC_FINAL)
92118
ZEND_NAMED_ME(__wakeup, PHP_FN(MongoDB_disabled___wakeup), ai_ClientEncryption_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
93119
PHP_FE_END
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
--TEST--
2+
MongoDB\Driver\ClientEncryption::decrypt()
3+
--SKIPIF--
4+
<?php require __DIR__ . "/../utils/basic-skipif.inc"; ?>
5+
<?php skip_if_not_libmongocrypt(); ?>
6+
<?php skip_if_not_live(); ?>
7+
<?php skip_if_server_version('<', '3.6'); ?>
8+
--FILE--
9+
<?php
10+
require_once __DIR__ . "/../utils/basic.inc";
11+
12+
$key = base64_decode('Mng0NCt4ZHVUYUJCa1kxNkVyNUR1QURhZ2h2UzR2d2RrZzh0cFBwM3R6NmdWMDFBMUN3YkQ5aXRRMkhGRGdQV09wOGVNYUMxT2k3NjZKelhaQmRCZGJkTXVyZG9uSjFk');
13+
14+
$manager = new MongoDB\Driver\Manager(URI);
15+
$clientEncryption = $manager->createClientEncryption(['keyVaultNamespace' => 'default.keys', 'kmsProviders' => ['local' => ['key' => new MongoDB\BSON\Binary($key, 0)]]]);
16+
17+
$key = $clientEncryption->createDataKey('local');
18+
19+
$encrypted = $clientEncryption->encrypt('top-secret', ['keyId' => $key, 'algorithm' => 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic']);
20+
var_dump($clientEncryption->decrypt($encrypted));
21+
22+
?>
23+
===DONE===
24+
<?php exit(0); ?>
25+
--EXPECTF--
26+
string(10) "top-secret"
27+
===DONE===

0 commit comments

Comments
 (0)