mirror of
https://github.com/php-gnupg/php-gnupg.git
synced 2024-11-25 07:37:08 +00:00
various memory optimizations
This commit is contained in:
parent
95ed1d656f
commit
1bf61c6980
3 changed files with 127 additions and 48 deletions
96
gnupg.c
96
gnupg.c
|
@ -67,7 +67,7 @@ static zend_object_handlers gnupg_object_handlers;
|
|||
}else{ \
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, (char*)error); \
|
||||
} \
|
||||
RETURN_FALSE;
|
||||
RETVAL_FALSE;
|
||||
/* }}} */
|
||||
|
||||
/* {{{ free encryptkeys */
|
||||
|
@ -554,6 +554,7 @@ PHP_FUNCTION(gnupg_keyinfo)
|
|||
}
|
||||
if((intern->err = gpgme_op_keylist_start(intern->ctx, searchkey, 0)) != GPG_ERR_NO_ERROR){
|
||||
GNUPG_ERR("could not init keylist");
|
||||
return;
|
||||
}
|
||||
|
||||
array_init(return_value);
|
||||
|
@ -652,6 +653,7 @@ PHP_FUNCTION(gnupg_addsignkey){
|
|||
}
|
||||
if((intern->err = gpgme_get_key(intern->ctx, key_id, &gpgme_key, 1)) != GPG_ERR_NO_ERROR){
|
||||
GNUPG_ERR("get_key failed");
|
||||
return;
|
||||
}
|
||||
if(passphrase){
|
||||
gpgme_subkey = gpgme_key->subkeys;
|
||||
|
@ -664,10 +666,10 @@ PHP_FUNCTION(gnupg_addsignkey){
|
|||
}
|
||||
if((intern->err = gpgme_signers_add(intern->ctx, gpgme_key))!=GPG_ERR_NO_ERROR){
|
||||
GNUPG_ERR("could not add signer");
|
||||
}else{
|
||||
RETVAL_TRUE;
|
||||
}
|
||||
/* dont need the keyref anymore */
|
||||
gpgme_key_unref(gpgme_key);
|
||||
RETURN_TRUE;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
@ -695,6 +697,7 @@ PHP_FUNCTION(gnupg_adddecryptkey){
|
|||
}
|
||||
if((intern->err = gpgme_get_key(intern->ctx, key_id, &gpgme_key, 1)) != GPG_ERR_NO_ERROR){
|
||||
GNUPG_ERR("get_key failed");
|
||||
return;
|
||||
}
|
||||
gpgme_subkey = gpgme_key->subkeys;
|
||||
while(gpgme_subkey){
|
||||
|
@ -730,6 +733,7 @@ PHP_FUNCTION(gnupg_addencryptkey){
|
|||
|
||||
if((intern->err = gpgme_get_key(intern->ctx, key_id, &gpgme_key, 0)) != GPG_ERR_NO_ERROR){
|
||||
GNUPG_ERR("get_key failed");
|
||||
return;
|
||||
}
|
||||
intern->encryptkeys = erealloc(intern->encryptkeys, sizeof(intern->encryptkeys) * (intern->encrypt_size + 1));
|
||||
intern->encryptkeys[intern->encrypt_size] = gpgme_key;
|
||||
|
@ -825,19 +829,31 @@ PHP_FUNCTION(gnupg_sign){
|
|||
gpgme_set_passphrase_cb (intern->ctx, (void*) passphrase_cb, intern);
|
||||
if((intern->err = gpgme_data_new_from_mem (&in, value, value_len, 0))!=GPG_ERR_NO_ERROR){
|
||||
GNUPG_ERR("could not create in-data buffer");
|
||||
return;
|
||||
}
|
||||
if((intern->err = gpgme_data_new(&out))!=GPG_ERR_NO_ERROR){
|
||||
GNUPG_ERR("could not create out-data buffer");
|
||||
gpgme_data_release(in);
|
||||
return;
|
||||
}
|
||||
if((intern->err = gpgme_op_sign(intern->ctx, in, out, intern->signmode))!=GPG_ERR_NO_ERROR){
|
||||
GNUPG_ERR("data signing failed");
|
||||
gpgme_data_release(in);
|
||||
gpgme_data_release(out);
|
||||
return;
|
||||
}
|
||||
result = gpgme_op_sign_result (intern->ctx);
|
||||
if(result->invalid_signers){
|
||||
GNUPG_ERR("invalid signers found");
|
||||
gpgme_data_release(in);
|
||||
gpgme_data_release(out);
|
||||
return;
|
||||
}
|
||||
if(!result->signatures){
|
||||
GNUPG_ERR("no signature in result");
|
||||
gpgme_data_release(in);
|
||||
gpgme_data_release(out);
|
||||
return;
|
||||
}
|
||||
userret = gpgme_data_release_and_get_mem(out,&ret_size);
|
||||
if(ret_size < 1){
|
||||
|
@ -879,19 +895,29 @@ PHP_FUNCTION(gnupg_encrypt){
|
|||
}
|
||||
if(!intern->encryptkeys){
|
||||
GNUPG_ERR("no key for encryption set");
|
||||
return;
|
||||
}
|
||||
if((intern->err = gpgme_data_new_from_mem (&in, value, value_len, 0))!=GPG_ERR_NO_ERROR){
|
||||
GNUPG_ERR("could no create in-data buffer");
|
||||
return;
|
||||
}
|
||||
if((intern->err = gpgme_data_new(&out))!=GPG_ERR_NO_ERROR){
|
||||
GNUPG_ERR("could not create out-data buffer");
|
||||
gpgme_data_release(in);
|
||||
return;
|
||||
}
|
||||
if((intern->err = gpgme_op_encrypt(intern->ctx, intern->encryptkeys, GPGME_ENCRYPT_ALWAYS_TRUST, in, out))!=GPG_ERR_NO_ERROR){
|
||||
GNUPG_ERR("encrypt failed");
|
||||
gpgme_data_release(in);
|
||||
gpgme_data_release(out);
|
||||
return;
|
||||
}
|
||||
result = gpgme_op_encrypt_result (intern->ctx);
|
||||
if (result->invalid_recipients){
|
||||
GNUPG_ERR("Invalid recipient encountered");
|
||||
gpgme_data_release(in);
|
||||
gpgme_data_release(out);
|
||||
return;
|
||||
}
|
||||
userret = gpgme_data_release_and_get_mem(out,&ret_size);
|
||||
gpgme_data_release (in);
|
||||
|
@ -933,29 +959,45 @@ PHP_FUNCTION(gnupg_encryptsign){
|
|||
|
||||
if(!intern->encryptkeys){
|
||||
GNUPG_ERR("no key for encryption set");
|
||||
return;
|
||||
}
|
||||
gpgme_set_passphrase_cb (intern->ctx, (void*) passphrase_cb, intern);
|
||||
if((intern->err = gpgme_data_new_from_mem (&in, value, value_len, 0))!=GPG_ERR_NO_ERROR){
|
||||
GNUPG_ERR("could not create in-data buffer");
|
||||
return;
|
||||
}
|
||||
if((intern->err = gpgme_data_new(&out))!=GPG_ERR_NO_ERROR){
|
||||
GNUPG_ERR("could not create out-data buffer");
|
||||
gpgme_data_release(in);
|
||||
return;
|
||||
}
|
||||
if((intern->err = gpgme_op_encrypt_sign(intern->ctx, intern->encryptkeys, GPGME_ENCRYPT_ALWAYS_TRUST, in, out))!=GPG_ERR_NO_ERROR){
|
||||
GNUPG_ERR("encrypt-sign failed");
|
||||
gpgme_data_release(in);
|
||||
gpgme_data_release(out);
|
||||
return;
|
||||
}
|
||||
|
||||
result = gpgme_op_encrypt_result (intern->ctx);
|
||||
if (result->invalid_recipients){
|
||||
GNUPG_ERR("Invalid recipient encountered");
|
||||
gpgme_data_release(in);
|
||||
gpgme_data_release(out);
|
||||
return;
|
||||
}
|
||||
|
||||
sign_result = gpgme_op_sign_result (intern->ctx);
|
||||
if(sign_result->invalid_signers){
|
||||
GNUPG_ERR("invalid signers found");
|
||||
gpgme_data_release(in);
|
||||
gpgme_data_release(out);
|
||||
return;
|
||||
}
|
||||
if(!sign_result->signatures){
|
||||
GNUPG_ERR("could not find a signature");
|
||||
gpgme_data_release(in);
|
||||
gpgme_data_release(out);
|
||||
return;
|
||||
}
|
||||
|
||||
userret = gpgme_data_release_and_get_mem(out,&ret_size);
|
||||
|
@ -1001,9 +1043,12 @@ PHP_FUNCTION(gnupg_verify){
|
|||
if(Z_STRVAL_P(signature)){
|
||||
if((intern->err = gpgme_data_new_from_mem (&gpgme_sig, Z_STRVAL_P(signature), Z_STRLEN_P(signature), 0))!=GPG_ERR_NO_ERROR){
|
||||
GNUPG_ERR("could not create signature-databuffer");
|
||||
return;
|
||||
}
|
||||
if((intern->err = gpgme_data_new (&gpgme_text))!=GPG_ERR_NO_ERROR){
|
||||
GNUPG_ERR("could not create text-databuffer");
|
||||
gpgme_data_release(gpgme_sig);
|
||||
return;
|
||||
}
|
||||
}else{
|
||||
/* no separate signature was passed
|
||||
|
@ -1013,23 +1058,31 @@ PHP_FUNCTION(gnupg_verify){
|
|||
*/
|
||||
if((intern->err = gpgme_data_new_from_mem (&gpgme_sig, text, text_len, 0))!=GPG_ERR_NO_ERROR){
|
||||
GNUPG_ERR("could not create signature-databuffer");
|
||||
return;
|
||||
}
|
||||
if((intern->err = gpgme_data_new_from_mem (&gpgme_text, NULL, 0, 0))!=GPG_ERR_NO_ERROR){
|
||||
GNUPG_ERR("could not create text-databuffer");
|
||||
gpgme_data_release(gpgme_sig);
|
||||
gpgme_data_release(gpgme_text);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if((intern->err = gpgme_op_verify (intern->ctx, gpgme_sig, NULL, gpgme_text))!=GPG_ERR_NO_ERROR){
|
||||
GNUPG_ERR("verify failed");
|
||||
gpgme_data_release(gpgme_sig);
|
||||
gpgme_data_release(gpgme_text);
|
||||
return;
|
||||
}
|
||||
gpgme_result = gpgme_op_verify_result (intern->ctx);
|
||||
if(!gpgme_result->signatures){
|
||||
GNUPG_ERR ("no signature found");
|
||||
}
|
||||
}else{
|
||||
gnupg_fetchsignatures (gpgme_result->signatures,sig_arr,return_value);
|
||||
gpg_plain = gpgme_data_release_and_get_mem(gpgme_text,&gpg_plain_len);
|
||||
if(plaintext){
|
||||
ZVAL_STRINGL (plaintext,gpg_plain,gpg_plain_len,1);
|
||||
}
|
||||
}
|
||||
gpgme_data_release (gpgme_sig);
|
||||
free (gpgme_text);
|
||||
free (gpg_plain);
|
||||
|
@ -1069,13 +1122,21 @@ PHP_FUNCTION(gnupg_decrypt){
|
|||
}
|
||||
if((intern->err = gpgme_data_new (&out))!=GPG_ERR_NO_ERROR){
|
||||
GNUPG_ERR("could not create out-data buffer");
|
||||
gpgme_data_release(in);
|
||||
return;
|
||||
}
|
||||
if((intern->err = gpgme_op_decrypt (intern->ctx, in, out))!=GPG_ERR_NO_ERROR){
|
||||
GNUPG_ERR("decrypt failed");
|
||||
gpgme_data_release(in);
|
||||
gpgme_data_release(out);
|
||||
return;
|
||||
}
|
||||
result = gpgme_op_decrypt_result (intern->ctx);
|
||||
if (result->unsupported_algorithm){
|
||||
GNUPG_ERR("unsupported algorithm");
|
||||
gpgme_data_release(in);
|
||||
gpgme_data_release(out);
|
||||
return;
|
||||
}
|
||||
userret = gpgme_data_release_and_get_mem(out,&ret_size);
|
||||
gpgme_data_release (in);
|
||||
|
@ -1125,9 +1186,14 @@ PHP_FUNCTION(gnupg_decryptverify){
|
|||
}
|
||||
if((intern->err = gpgme_data_new (&out))!=GPG_ERR_NO_ERROR){
|
||||
GNUPG_ERR("could not create out-data buffer");
|
||||
gpgme_data_release(in);
|
||||
return;
|
||||
}
|
||||
if((intern->err = gpgme_op_decrypt_verify (intern->ctx, in, out))!=GPG_ERR_NO_ERROR){
|
||||
GNUPG_ERR("decrypt-verify failed");
|
||||
gpgme_data_release(in);
|
||||
gpgme_data_release(out);
|
||||
return;
|
||||
}
|
||||
userret = gpgme_data_release_and_get_mem(out,&ret_size);
|
||||
ZVAL_STRINGL (plaintext,userret,ret_size,1);
|
||||
|
@ -1135,10 +1201,16 @@ PHP_FUNCTION(gnupg_decryptverify){
|
|||
decrypt_result = gpgme_op_decrypt_result (intern->ctx);
|
||||
if (decrypt_result->unsupported_algorithm){
|
||||
GNUPG_ERR ("unsupported algorithm");
|
||||
gpgme_data_release(in);
|
||||
free(out);
|
||||
return;
|
||||
}
|
||||
verify_result = gpgme_op_verify_result (intern->ctx);
|
||||
if(!verify_result->signatures){
|
||||
GNUPG_ERR ("no signature found");
|
||||
gpgme_data_release(in);
|
||||
free(out);
|
||||
return;
|
||||
}
|
||||
gnupg_fetchsignatures (verify_result->signatures,sig_arr,return_value);
|
||||
gpgme_data_release (in);
|
||||
|
@ -1171,9 +1243,12 @@ PHP_FUNCTION(gnupg_export){
|
|||
}
|
||||
if((intern->err = gpgme_data_new (&out))!=GPG_ERR_NO_ERROR){
|
||||
GNUPG_ERR("could not create data buffer");
|
||||
return;
|
||||
}
|
||||
if((intern->err = gpgme_op_export (intern->ctx, searchkey, 0, out))!=GPG_ERR_NO_ERROR){
|
||||
GNUPG_ERR("export failed");
|
||||
gpgme_data_release(out);
|
||||
return;
|
||||
}
|
||||
userret = gpgme_data_release_and_get_mem(out,&ret_size);
|
||||
RETVAL_STRINGL (userret,ret_size,1);
|
||||
|
@ -1209,9 +1284,12 @@ PHP_FUNCTION(gnupg_import){
|
|||
}
|
||||
if((intern->err = gpgme_data_new_from_mem (&in, importkey, importkey_len, 0))!=GPG_ERR_NO_ERROR){
|
||||
GNUPG_ERR("could not create in-data buffer");
|
||||
return;
|
||||
}
|
||||
if((intern->err = gpgme_op_import(intern->ctx,in))!=GPG_ERR_NO_ERROR){
|
||||
GNUPG_ERR("import failed");
|
||||
gpgme_data_release(in);
|
||||
return;
|
||||
}
|
||||
gpgme_data_release(in);
|
||||
result = gpgme_op_import_result (intern->ctx);
|
||||
|
@ -1254,12 +1332,15 @@ PHP_FUNCTION(gnupg_deletekey){
|
|||
|
||||
if((intern->err = gpgme_get_key(intern->ctx, key, &gpgme_key, 0)) != GPG_ERR_NO_ERROR){
|
||||
GNUPG_ERR("get_key failed");
|
||||
return;
|
||||
}
|
||||
if((intern->err = gpgme_op_delete(intern->ctx,gpgme_key,allow_secret))!=GPG_ERR_NO_ERROR){
|
||||
GNUPG_ERR("delete failed");
|
||||
RETVAL_FALSE;
|
||||
}else{
|
||||
RETVAL_TRUE;
|
||||
}
|
||||
gpgme_key_unref(gpgme_key);
|
||||
RETURN_TRUE;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
@ -1287,6 +1368,7 @@ PHP_FUNCTION(gnupg_gettrustlist){
|
|||
}
|
||||
if((intern->err = gpgme_op_trustlist_start (intern->ctx, pattern, 0))!=GPG_ERR_NO_ERROR){
|
||||
GNUPG_ERR("could not start trustlist");
|
||||
return;
|
||||
}
|
||||
array_init(return_value);
|
||||
while (!(intern->err = gpgme_op_trustlist_next (intern->ctx, &item))){
|
||||
|
@ -1332,12 +1414,16 @@ PHP_FUNCTION(gnupg_listsignatures){
|
|||
}
|
||||
if((intern->err = gpgme_set_keylist_mode(intern->ctx,GPGME_KEYLIST_MODE_SIGS))!=GPG_ERR_NO_ERROR){
|
||||
GNUPG_ERR("could not switch to sigmode");
|
||||
return;
|
||||
}
|
||||
if((intern->err = gpgme_get_key(intern->ctx, keyid, &gpgme_key, 0)) != GPG_ERR_NO_ERROR){
|
||||
GNUPG_ERR("get_key failed. given key not unique?");
|
||||
return;
|
||||
}
|
||||
if(!gpgme_key->uids){
|
||||
GNUPG_ERR("no uids found");
|
||||
gpgme_key_unref(gpgme_key);
|
||||
return;
|
||||
}
|
||||
array_init(return_value);
|
||||
gpgme_userid = gpgme_key->uids;
|
||||
|
|
|
@ -37,31 +37,29 @@ static int le_gnupg_keylistiterator;
|
|||
static zend_object_handlers gnupg_keylistiterator_object_handlers;
|
||||
|
||||
/* {{{ defs */
|
||||
|
||||
#define GNUPG_GET_ITERATOR() \
|
||||
zval *this = getThis(); \
|
||||
gnupg_keylistiterator_object *intern; \
|
||||
ze_gnupg_keylistiterator_object *obj = (ze_gnupg_keylistiterator_object*) zend_object_store_get_object(getThis() TSRMLS_CC); \
|
||||
intern = obj->gnupg_keylistiterator_ptr; \
|
||||
if(this){ \
|
||||
intern = (gnupg_keylistiterator_object*) zend_object_store_get_object(getThis() TSRMLS_CC); \
|
||||
if(!intern){ \
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid or unitialized gnupg iterator object"); \
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid or unitialized gnupg object"); \
|
||||
RETURN_FALSE; \
|
||||
} \
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ free_iterator_storage */
|
||||
static void gnupg_keylistiterator_object_free_storage(void *object TSRMLS_DC){
|
||||
ze_gnupg_keylistiterator_object *intern = (ze_gnupg_keylistiterator_object *) object;
|
||||
static void gnupg_keylistiterator_dtor(gnupg_keylistiterator_object *intern TSRMLS_DC){
|
||||
if(!intern){
|
||||
return;
|
||||
}
|
||||
if(intern->gnupg_keylistiterator_ptr){
|
||||
gpgme_op_keylist_end(intern->gnupg_keylistiterator_ptr->ctx);
|
||||
gpgme_key_release(intern->gnupg_keylistiterator_ptr->gpgkey);
|
||||
gpgme_release(intern->gnupg_keylistiterator_ptr->ctx);
|
||||
zval_dtor(&intern->gnupg_keylistiterator_ptr->pattern);
|
||||
efree(intern->gnupg_keylistiterator_ptr);
|
||||
}
|
||||
gpgme_op_keylist_end(intern->ctx);
|
||||
gpgme_key_release(intern->gpgkey);
|
||||
gpgme_release(intern->ctx);
|
||||
/*
|
||||
zval_dtor(&intern->pattern);
|
||||
*/
|
||||
if(intern->zo.properties){
|
||||
zend_hash_destroy(intern->zo.properties);
|
||||
FREE_HASHTABLE(intern->zo.properties);
|
||||
|
@ -72,25 +70,20 @@ static void gnupg_keylistiterator_object_free_storage(void *object TSRMLS_DC){
|
|||
|
||||
/* {{{ keylistiterator_objects_new */
|
||||
zend_object_value gnupg_keylistiterator_objects_new(zend_class_entry *class_type TSRMLS_DC){
|
||||
ze_gnupg_keylistiterator_object *intern;
|
||||
gnupg_keylistiterator_object *intern;
|
||||
zend_object_value retval;
|
||||
gnupg_keylistiterator_object *gnupg_keylistiterator_ptr;
|
||||
gpgme_ctx_t ctx;
|
||||
|
||||
intern = emalloc(sizeof(ze_gnupg_keylistiterator_object));
|
||||
intern = emalloc(sizeof(gnupg_keylistiterator_object));
|
||||
intern->zo.ce = class_type;
|
||||
intern->zo.in_get = 0;
|
||||
intern->zo.in_set = 0;
|
||||
intern->zo.properties = NULL;
|
||||
retval.handle = zend_objects_store_put(intern,NULL,(zend_objects_free_object_storage_t) gnupg_keylistiterator_object_free_storage,NULL TSRMLS_CC);
|
||||
retval.handle = zend_objects_store_put(intern,NULL,(zend_objects_free_object_storage_t) gnupg_keylistiterator_dtor,NULL TSRMLS_CC);
|
||||
retval.handlers = (zend_object_handlers *) & gnupg_keylistiterator_object_handlers;
|
||||
|
||||
gpgme_new(&ctx);
|
||||
gnupg_keylistiterator_ptr = emalloc(sizeof(gnupg_keylistiterator_object));
|
||||
gnupg_keylistiterator_ptr->ctx = ctx;
|
||||
|
||||
intern->gnupg_keylistiterator_ptr = gnupg_keylistiterator_ptr;
|
||||
|
||||
intern->ctx = ctx;
|
||||
return retval;
|
||||
}
|
||||
/* }}} */
|
||||
|
@ -141,7 +134,7 @@ PHP_FUNCTION(gnupg_keylistiterator___construct){
|
|||
intern->pattern = *pattern;
|
||||
zval_copy_ctor(&intern->pattern);
|
||||
}else{
|
||||
convert_to_string(&intern->pattern);
|
||||
ZVAL_EMPTY_STRING(&intern->pattern);
|
||||
}
|
||||
}
|
||||
PHP_FUNCTION(gnupg_keylistiterator_current){
|
||||
|
@ -159,6 +152,10 @@ PHP_FUNCTION(gnupg_keylistiterator_key){
|
|||
PHP_FUNCTION(gnupg_keylistiterator_next){
|
||||
GNUPG_GET_ITERATOR();
|
||||
|
||||
if(intern->gpgkey){
|
||||
gpgme_key_release(intern->gpgkey);
|
||||
}
|
||||
|
||||
if(intern->err = gpgme_op_keylist_next(intern->ctx, &intern->gpgkey)){
|
||||
gpgme_key_release(intern->gpgkey);
|
||||
intern->gpgkey = NULL;
|
||||
|
|
|
@ -39,17 +39,13 @@ extern zend_module_entry gnupg_keyiterator_module_entry;
|
|||
extern int _gnupg_keylistiterator_init(INIT_FUNC_ARGS);
|
||||
|
||||
typedef struct _gnupg_keylistiterator_object{
|
||||
zend_object zo;
|
||||
gpgme_ctx_t ctx;
|
||||
gpgme_error_t err;
|
||||
gpgme_key_t gpgkey;
|
||||
zval pattern;
|
||||
} gnupg_keylistiterator_object;
|
||||
|
||||
typedef struct _ze_gnupg_keylistiterator_object{
|
||||
zend_object zo;
|
||||
gnupg_keylistiterator_object *gnupg_keylistiterator_ptr;
|
||||
} ze_gnupg_keylistiterator_object;
|
||||
|
||||
zend_class_entry *gnupg_keylistiterator_class_entry;
|
||||
|
||||
PHP_FUNCTION(gnupg_keylistiterator___construct);
|
||||
|
|
Loading…
Reference in a new issue