Skip to content

Commit 4923bdd

Browse files
committed
PHPC-1499: Add empty ClientEncryption class
1 parent f167da9 commit 4923bdd

File tree

10 files changed

+326
-2
lines changed

10 files changed

+326
-2
lines changed

config.m4

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ if test "$PHP_MONGODB" != "no"; then
133133
src/BSON/UTCDateTimeInterface.c \
134134
src/BSON/functions.c \
135135
src/MongoDB/BulkWrite.c \
136+
src/MongoDB/ClientEncryption.c \
136137
src/MongoDB/Command.c \
137138
src/MongoDB/Cursor.c \
138139
src/MongoDB/CursorId.c \

config.w32

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ if (PHP_MONGODB != "no") {
9090
EXTENSION("mongodb", "php_phongo.c phongo_compat.c", null, PHP_MONGODB_CFLAGS);
9191
ADD_SOURCES(configure_module_dirname + "/src", "bson.c bson-encode.c", "mongodb");
9292
ADD_SOURCES(configure_module_dirname + "/src/BSON", "Binary.c BinaryInterface.c DBPointer.c Decimal128.c Decimal128Interface.c Int64.c Javascript.c JavascriptInterface.c MaxKey.c MaxKeyInterface.c MinKey.c MinKeyInterface.c ObjectId.c ObjectIdInterface.c Persistable.c Regex.c RegexInterface.c Serializable.c Symbol.c Timestamp.c TimestampInterface.c Type.c Undefined.c Unserializable.c UTCDateTime.c UTCDateTimeInterface.c functions.c", "mongodb");
93-
ADD_SOURCES(configure_module_dirname + "/src/MongoDB", "BulkWrite.c Command.c Cursor.c CursorId.c CursorInterface.c Manager.c Query.c ReadConcern.c ReadPreference.c Server.c Session.c WriteConcern.c WriteConcernError.c WriteError.c WriteResult.c", "mongodb");
93+
ADD_SOURCES(configure_module_dirname + "/src/MongoDB", "BulkWrite.c ClientEncryption.c Command.c Cursor.c CursorId.c CursorInterface.c Manager.c Query.c ReadConcern.c ReadPreference.c Server.c Session.c WriteConcern.c WriteConcernError.c WriteError.c WriteResult.c", "mongodb");
9494
ADD_SOURCES(configure_module_dirname + "/src/MongoDB/Exception", "AuthenticationException.c BulkWriteException.c CommandException.c ConnectionException.c ConnectionTimeoutException.c Exception.c ExecutionTimeoutException.c InvalidArgumentException.c LogicException.c RuntimeException.c ServerException.c SSLConnectionException.c UnexpectedValueException.c WriteException.c", "mongodb");
9595
ADD_SOURCES(configure_module_dirname + "/src/MongoDB/Monitoring", "CommandFailedEvent.c CommandStartedEvent.c CommandSubscriber.c CommandSucceededEvent.c Subscriber.c functions.c", "mongodb");
9696
ADD_SOURCES(configure_module_dirname + "/src/libmongoc/src/common", PHP_MONGODB_COMMON_SOURCES, "mongodb");

php_phongo.c

Lines changed: 120 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2841,18 +2841,136 @@ static bool phongo_manager_set_auto_encryption_opts(php_phongo_manager_t* manage
28412841
return retval;
28422842
}
28432843
/* }}} */
2844+
2845+
static mongoc_client_encryption_opts_t* phongo_clientencryption_opts_from_zval(mongoc_client_t* defaultKeyVaultClient, zval* options TSRMLS_DC) /* {{{ */
2846+
{
2847+
mongoc_client_encryption_opts_t* opts;
2848+
2849+
opts = mongoc_client_encryption_opts_new();
2850+
2851+
if (!options || Z_TYPE_P(options) != IS_ARRAY) {
2852+
return opts;
2853+
}
2854+
2855+
if (php_array_existsc(options, "keyVaultClient")) {
2856+
zval* key_vault_client = php_array_fetch(options, "keyVaultClient");
2857+
2858+
if (Z_TYPE_P(key_vault_client) != IS_OBJECT || !instanceof_function(Z_OBJCE_P(key_vault_client), php_phongo_manager_ce TSRMLS_CC)) {
2859+
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected \"keyVaultClient\" encryption option to be %s, %s given", ZSTR_VAL(php_phongo_manager_ce->name), PHONGO_ZVAL_CLASS_OR_TYPE_NAME_P(key_vault_client));
2860+
goto cleanup;
2861+
}
2862+
2863+
mongoc_client_encryption_opts_set_keyvault_client(opts, Z_MANAGER_OBJ_P(key_vault_client)->client);
2864+
} else {
2865+
mongoc_client_encryption_opts_set_keyvault_client(opts, defaultKeyVaultClient);
2866+
}
2867+
2868+
if (php_array_existsc(options, "keyVaultNamespace")) {
2869+
char* keyvault_namespace;
2870+
char* db_name;
2871+
char* coll_name;
2872+
int plen;
2873+
zend_bool pfree;
2874+
2875+
keyvault_namespace = php_array_fetchc_string(options, "keyVaultNamespace", &plen, &pfree);
2876+
2877+
if (!phongo_split_namespace(keyvault_namespace, &db_name, &coll_name)) {
2878+
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected \"keyVaultNamespace\" encryption option to contain a full collection name");
2879+
2880+
if (pfree) {
2881+
str_efree(keyvault_namespace);
2882+
}
2883+
2884+
goto cleanup;
2885+
}
2886+
2887+
mongoc_client_encryption_opts_set_keyvault_namespace(opts, db_name, coll_name);
2888+
efree(db_name);
2889+
efree(coll_name);
2890+
2891+
if (pfree) {
2892+
str_efree(keyvault_namespace);
2893+
}
2894+
}
2895+
2896+
if (php_array_existsc(options, "kmsProviders")) {
2897+
zval* kms_providers = php_array_fetchc(options, "kmsProviders");
2898+
bson_t bson_providers = BSON_INITIALIZER;
2899+
2900+
if (Z_TYPE_P(kms_providers) != IS_ARRAY) {
2901+
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected \"kmsProviders\" encryption option to be an array");
2902+
goto cleanup;
2903+
}
2904+
2905+
php_phongo_zval_to_bson(kms_providers, PHONGO_BSON_NONE, &bson_providers, NULL TSRMLS_CC);
2906+
if (EG(exception)) {
2907+
goto cleanup;
2908+
}
2909+
2910+
mongoc_client_encryption_opts_set_kms_providers(opts, &bson_providers);
2911+
bson_destroy(&bson_providers);
2912+
}
2913+
2914+
return opts;
2915+
2916+
cleanup:
2917+
if (opts) {
2918+
mongoc_client_encryption_opts_destroy(opts);
2919+
}
2920+
2921+
return NULL;
2922+
} /* }}} */
2923+
2924+
void phongo_clientencryption_init(php_phongo_clientencryption_t* clientencryption, mongoc_client_t* client, zval* options TSRMLS_DC) /* {{{ */
2925+
{
2926+
mongoc_client_encryption_t* ce;
2927+
mongoc_client_encryption_opts_t* opts;
2928+
bson_error_t error = { 0 };
2929+
2930+
opts = phongo_clientencryption_opts_from_zval(client, options TSRMLS_CC);
2931+
if (!opts) {
2932+
/* Exception already thrown */
2933+
goto cleanup;
2934+
}
2935+
2936+
ce = mongoc_client_encryption_new(opts, &error);
2937+
if (!ce) {
2938+
phongo_throw_exception_from_bson_error_t(&error TSRMLS_CC);
2939+
2940+
goto cleanup;
2941+
}
2942+
2943+
clientencryption->client_encryption = ce;
2944+
2945+
cleanup:
2946+
if (opts) {
2947+
mongoc_client_encryption_opts_destroy(opts);
2948+
}
2949+
} /* }}} */
28442950
#else /* MONGOC_ENABLE_CLIENT_SIDE_ENCRYPTION */
2951+
static void phongo_throw_exception_no_cse(php_phongo_error_domain_t domain, const char* message TSRMLS_DC) /* {{{ */
2952+
{
2953+
phongo_throw_exception(domain TSRMLS_CC, "%s Please recompile with support for libmongocrypt using the with-mongodb-client-side-encryption configure switch.", message);
2954+
}
2955+
/* }}} */
2956+
28452957
static bool phongo_manager_set_auto_encryption_opts(php_phongo_manager_t* manager, zval* driverOptions TSRMLS_DC) /* {{{ */
28462958
{
28472959
if (!driverOptions || !php_array_existsc(driverOptions, "autoEncryption")) {
28482960
return true;
28492961
}
28502962

2851-
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Cannot enable automatic field-level encryption. Please recompile with support for libmongocrypt using the with-mongodb-client-side-encryption configure switch.");
2963+
phongo_throw_exception_no_cse(PHONGO_ERROR_INVALID_ARGUMENT, "Cannot enable automatic field-level encryption." TSRMLS_CC);
28522964

28532965
return false;
28542966
}
28552967
/* }}} */
2968+
2969+
void phongo_clientencryption_init(php_phongo_clientencryption_t* clientencryption, mongoc_client_t* client, zval* options TSRMLS_DC) /* {{{ */
2970+
{
2971+
phongo_throw_exception_no_cse(PHONGO_ERROR_RUNTIME, "Cannot configure clientEncryption object." TSRMLS_CC);
2972+
}
2973+
/* }}} */
28562974
#endif
28572975

28582976
void phongo_manager_init(php_phongo_manager_t* manager, const char* uri_string, zval* options, zval* driverOptions TSRMLS_DC) /* {{{ */
@@ -3303,6 +3421,7 @@ PHP_MINIT_FUNCTION(mongodb)
33033421
php_phongo_cursor_interface_init_ce(INIT_FUNC_ARGS_PASSTHRU);
33043422

33053423
php_phongo_bulkwrite_init_ce(INIT_FUNC_ARGS_PASSTHRU);
3424+
php_phongo_clientencryption_init_ce(INIT_FUNC_ARGS_PASSTHRU);
33063425
php_phongo_command_init_ce(INIT_FUNC_ARGS_PASSTHRU);
33073426
php_phongo_cursor_init_ce(INIT_FUNC_ARGS_PASSTHRU);
33083427
php_phongo_cursorid_init_ce(INIT_FUNC_ARGS_PASSTHRU);

php_phongo.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ typedef enum {
130130

131131
zend_object_handlers* phongo_get_std_object_handlers(void);
132132

133+
void phongo_clientencryption_init(php_phongo_clientencryption_t* ce_obj, mongoc_client_t* client, zval* options TSRMLS_DC);
133134
void phongo_server_init(zval* return_value, mongoc_client_t* client, uint32_t server_id TSRMLS_DC);
134135
void phongo_session_init(zval* return_value, mongoc_client_session_t* client_session TSRMLS_DC);
135136
void phongo_readconcern_init(zval* return_value, const mongoc_read_concern_t* read_concern TSRMLS_DC);

php_phongo_classes.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@ static inline php_phongo_bulkwrite_t* php_bulkwrite_fetch_object(zend_object* ob
2929
{
3030
return (php_phongo_bulkwrite_t*) ((char*) obj - XtOffsetOf(php_phongo_bulkwrite_t, std));
3131
}
32+
static inline php_phongo_clientencryption_t* php_clientencryption_fetch_object(zend_object* obj)
33+
{
34+
return (php_phongo_clientencryption_t*) ((char*) obj - XtOffsetOf(php_phongo_clientencryption_t, std));
35+
}
3236
static inline php_phongo_command_t* php_command_fetch_object(zend_object* obj)
3337
{
3438
return (php_phongo_command_t*) ((char*) obj - XtOffsetOf(php_phongo_command_t, std));
@@ -146,6 +150,7 @@ static inline php_phongo_commandsucceededevent_t* php_commandsucceededevent_fetc
146150
return (php_phongo_commandsucceededevent_t*) ((char*) obj - XtOffsetOf(php_phongo_commandsucceededevent_t, std));
147151
}
148152

153+
#define Z_CLIENTENCRYPTION_OBJ_P(zv) (php_clientencryption_fetch_object(Z_OBJ_P(zv)))
149154
#define Z_COMMAND_OBJ_P(zv) (php_command_fetch_object(Z_OBJ_P(zv)))
150155
#define Z_CURSOR_OBJ_P(zv) (php_cursor_fetch_object(Z_OBJ_P(zv)))
151156
#define Z_CURSORID_OBJ_P(zv) (php_cursorid_fetch_object(Z_OBJ_P(zv)))
@@ -177,6 +182,7 @@ static inline php_phongo_commandsucceededevent_t* php_commandsucceededevent_fetc
177182
#define Z_COMMANDSTARTEDEVENT_OBJ_P(zv) (php_commandstartedevent_fetch_object(Z_OBJ_P(zv)))
178183
#define Z_COMMANDSUCCEEDEDEVENT_OBJ_P(zv) (php_commandsucceededevent_fetch_object(Z_OBJ_P(zv)))
179184

185+
#define Z_OBJ_CLIENTENCRYPTION(zo) (php_clientencryption_fetch_object(zo))
180186
#define Z_OBJ_COMMAND(zo) (php_command_fetch_object(zo))
181187
#define Z_OBJ_CURSOR(zo) (php_cursor_fetch_object(zo))
182188
#define Z_OBJ_CURSORID(zo) (php_cursorid_fetch_object(zo))
@@ -210,6 +216,7 @@ static inline php_phongo_commandsucceededevent_t* php_commandsucceededevent_fetc
210216

211217
#else /* PHP_VERSION_ID >= 70000 */
212218

219+
#define Z_CLIENTENCRYPTION_OBJ_P(zv) ((php_phongo_clientencryption_t*) zend_object_store_get_object(zv TSRMLS_CC))
213220
#define Z_COMMAND_OBJ_P(zv) ((php_phongo_command_t*) zend_object_store_get_object(zv TSRMLS_CC))
214221
#define Z_CURSOR_OBJ_P(zv) ((php_phongo_cursor_t*) zend_object_store_get_object(zv TSRMLS_CC))
215222
#define Z_CURSORID_OBJ_P(zv) ((php_phongo_cursorid_t*) zend_object_store_get_object(zv TSRMLS_CC))
@@ -241,6 +248,7 @@ static inline php_phongo_commandsucceededevent_t* php_commandsucceededevent_fetc
241248
#define Z_COMMANDSTARTEDEVENT_OBJ_P(zv) ((php_phongo_commandstartedevent_t*) zend_object_store_get_object(zv TSRMLS_CC))
242249
#define Z_COMMANDSUCCEEDEDEVENT_OBJ_P(zv) ((php_phongo_commandsucceededevent_t*) zend_object_store_get_object(zv TSRMLS_CC))
243250

251+
#define Z_OBJ_CLIENTENCRYPTION(zo) ((php_phongo_clientencryption_t*) zo)
244252
#define Z_OBJ_COMMAND(zo) ((php_phongo_command_t*) zo)
245253
#define Z_OBJ_CURSOR(zo) ((php_phongo_cursor_t*) zo)
246254
#define Z_OBJ_CURSORID(zo) ((php_phongo_cursorid_t*) zo)
@@ -279,6 +287,7 @@ typedef struct {
279287
php_phongo_cursor_t* cursor;
280288
} php_phongo_cursor_iterator;
281289

290+
extern zend_class_entry* php_phongo_clientencryption_ce;
282291
extern zend_class_entry* php_phongo_command_ce;
283292
extern zend_class_entry* php_phongo_cursor_ce;
284293
extern zend_class_entry* php_phongo_cursorid_ce;
@@ -374,6 +383,7 @@ extern void php_phongo_timestamp_interface_init_ce(INIT_FUNC_ARGS);
374383
extern void php_phongo_utcdatetime_interface_init_ce(INIT_FUNC_ARGS);
375384

376385
extern void php_phongo_bulkwrite_init_ce(INIT_FUNC_ARGS);
386+
extern void php_phongo_clientencryption_init_ce(INIT_FUNC_ARGS);
377387
extern void php_phongo_command_init_ce(INIT_FUNC_ARGS);
378388
extern void php_phongo_cursor_init_ce(INIT_FUNC_ARGS);
379389
extern void php_phongo_cursorid_init_ce(INIT_FUNC_ARGS);

php_phongo_structs.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,12 @@ typedef struct {
4343
PHONGO_ZEND_OBJECT_POST
4444
} php_phongo_bulkwrite_t;
4545

46+
typedef struct {
47+
PHONGO_ZEND_OBJECT_PRE
48+
mongoc_client_encryption_t* client_encryption;
49+
PHONGO_ZEND_OBJECT_POST
50+
} php_phongo_clientencryption_t;
51+
4652
typedef struct {
4753
PHONGO_ZEND_OBJECT_PRE
4854
bson_t* bson;

src/MongoDB/ClientEncryption.c

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
/*
2+
* Copyright 2019 MongoDB, Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
#include <php.h>
18+
#include <Zend/zend_interfaces.h>
19+
20+
#ifdef HAVE_CONFIG_H
21+
#include "config.h"
22+
#endif
23+
24+
#include "phongo_compat.h"
25+
#include "php_phongo.h"
26+
27+
zend_class_entry* php_phongo_clientencryption_ce;
28+
29+
ZEND_BEGIN_ARG_INFO_EX(ai_ClientEncryption_void, 0, 0, 0)
30+
ZEND_END_ARG_INFO()
31+
32+
static zend_function_entry php_phongo_clientencryption_me[] = {
33+
/* clang-format off */
34+
ZEND_NAMED_ME(__construct, PHP_FN(MongoDB_disabled___construct), ai_ClientEncryption_void, ZEND_ACC_PRIVATE | ZEND_ACC_FINAL)
35+
ZEND_NAMED_ME(__wakeup, PHP_FN(MongoDB_disabled___wakeup), ai_ClientEncryption_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
36+
PHP_FE_END
37+
/* clang-format on */
38+
};
39+
/* }}} */
40+
41+
/* {{{ MongoDB\Driver\ClientEncryption object handlers */
42+
static zend_object_handlers php_phongo_handler_clientencryption;
43+
44+
static void php_phongo_clientencryption_free_object(phongo_free_object_arg* object TSRMLS_DC) /* {{{ */
45+
{
46+
php_phongo_clientencryption_t* intern = Z_OBJ_CLIENTENCRYPTION(object);
47+
48+
zend_object_std_dtor(&intern->std TSRMLS_CC);
49+
50+
if (intern->client_encryption) {
51+
mongoc_client_encryption_destroy(intern->client_encryption);
52+
}
53+
54+
#if PHP_VERSION_ID < 70000
55+
efree(intern);
56+
#endif
57+
} /* }}} */
58+
59+
static phongo_create_object_retval php_phongo_clientencryption_create_object(zend_class_entry* class_type TSRMLS_DC) /* {{{ */
60+
{
61+
php_phongo_clientencryption_t* intern = NULL;
62+
63+
intern = PHONGO_ALLOC_OBJECT_T(php_phongo_clientencryption_t, class_type);
64+
65+
zend_object_std_init(&intern->std, class_type TSRMLS_CC);
66+
object_properties_init(&intern->std, class_type);
67+
68+
#if PHP_VERSION_ID >= 70000
69+
intern->std.handlers = &php_phongo_handler_clientencryption;
70+
71+
return &intern->std;
72+
#else
73+
{
74+
zend_object_value retval;
75+
retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t) zend_objects_destroy_object, php_phongo_clientencryption_free_object, NULL TSRMLS_CC);
76+
retval.handlers = &php_phongo_handler_clientencryption;
77+
78+
return retval;
79+
}
80+
#endif
81+
} /* }}} */
82+
83+
static HashTable* php_phongo_clientencryption_get_debug_info(zval* object, int* is_temp TSRMLS_DC) /* {{{ */
84+
{
85+
php_phongo_clientencryption_t* intern = NULL;
86+
zval retval = ZVAL_STATIC_INIT;
87+
88+
*is_temp = 1;
89+
intern = Z_CLIENTENCRYPTION_OBJ_P(object);
90+
91+
array_init(&retval);
92+
93+
return Z_ARRVAL(retval);
94+
} /* }}} */
95+
/* }}} */
96+
97+
void php_phongo_clientencryption_init_ce(INIT_FUNC_ARGS) /* {{{ */
98+
{
99+
zend_class_entry ce;
100+
101+
INIT_NS_CLASS_ENTRY(ce, "MongoDB\\Driver", "ClientEncryption", php_phongo_clientencryption_me);
102+
php_phongo_clientencryption_ce = zend_register_internal_class(&ce TSRMLS_CC);
103+
php_phongo_clientencryption_ce->create_object = php_phongo_clientencryption_create_object;
104+
PHONGO_CE_FINAL(php_phongo_clientencryption_ce);
105+
PHONGO_CE_DISABLE_SERIALIZATION(php_phongo_clientencryption_ce);
106+
107+
memcpy(&php_phongo_handler_clientencryption, phongo_get_std_object_handlers(), sizeof(zend_object_handlers));
108+
php_phongo_handler_clientencryption.get_debug_info = php_phongo_clientencryption_get_debug_info;
109+
#if PHP_VERSION_ID >= 70000
110+
php_phongo_handler_clientencryption.free_obj = php_phongo_clientencryption_free_object;
111+
php_phongo_handler_clientencryption.offset = XtOffsetOf(php_phongo_clientencryption_t, std);
112+
#endif
113+
} /* }}} */
114+
115+
/*
116+
* Local variables:
117+
* tab-width: 4
118+
* c-basic-offset: 4
119+
* End:
120+
* vim600: noet sw=4 ts=4 fdm=marker
121+
* vim<600: noet sw=4 ts=4
122+
*/

0 commit comments

Comments
 (0)