cvs: php4 /ext/openssl Makefile.in config.m4 openssl.c php_openssl.h
| From: | Stig Venaas | Date: | Mon, 13 Nov 2000 19:47:20 +0000 |
| Subject: | cvs: php4 /ext/openssl Makefile.in config.m4 openssl.c php_openssl.h | ||
| Groups: | php.cvs | ||
| Request: | Send a blank email to php-cvs+get-2592@lists.php.net to get a copy of this message | ||
venaas Mon Nov 13 11:47:20 2000 EDT
Added files:
/php4/ext/openssl Makefile.in config.m4 openssl.c php_openssl.h
Log:
OpenSSL extension. So far it implements assymetric encryption functions.
Index: php4/ext/openssl/Makefile.in +++ php4/ext/openssl/Makefile.in # $Id: Makefile.in,v 1.1 2000/11/13 19:47:19 venaas Exp $ LTLIBRARY_NAME = libopenssl.la LTLIBRARY_SOURCES = openssl.c LTLIBRARY_SHARED_NAME = openssl.la include $(top_srcdir)/build/dynlib.mk Index: php4/ext/openssl/config.m4 +++ php4/ext/openssl/config.m4 dnl $Id: config.m4,v 1.1 2000/11/13 19:47:19 venaas Exp $ dnl config.m4 for extension OpenSSL if test "$OPENSSL_DIR"; then PHP_EXTENSION(openssl, $ext_shared) AC_DEFINE(HAVE_OPENSSL_EXT,1,[ ]) fi Index: php4/ext/openssl/openssl.c +++ php4/ext/openssl/openssl.c /* +----------------------------------------------------------------------+ | PHP version 4.0 | +----------------------------------------------------------------------+ | Copyright (c) 1997, 1998, 1999, 2000 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 2.02 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | | available at through the world-wide-web at | | http://www.php.net/license/2_02.txt. | | If you did not receive a copy of the PHP license and are unable to | | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ | Authors: Stig Venaas <venaas@php.net> | +----------------------------------------------------------------------+ */ /* $Id: openssl.c,v 1.1 2000/11/13 19:47:19 venaas Exp $ */ #include "php.h" #include "php_openssl.h" /* PHP Includes */ #include "ext/standard/file.h" #include "ext/standard/info.h" /* OpenSSL includes */ #include <openssl/evp.h> #include <openssl/x509.h> static unsigned char second_argument_force_ref[] = { 3, BYREF_NONE, BYREF_FORCE, BYREF_NONE }; static unsigned char second_to_fourth_argument_force_ref[] = { 5, BYREF_NONE, BYREF_FORCE, BYREF_FORCE, BYREF_FORCE, BYREF_NONE }; function_entry openssl_functions[] = { PHP_FE(openssl_read_privatekey, NULL) PHP_FE(openssl_read_publickey, NULL) PHP_FE(openssl_free_key, NULL) PHP_FE(openssl_read_x509, NULL) PHP_FE(openssl_free_x509, NULL) PHP_FE(openssl_sign, second_argument_force_ref) PHP_FE(openssl_verify, NULL) PHP_FE(openssl_seal, second_to_fourth_argument_force_ref) PHP_FE(openssl_open, second_argument_force_ref) {NULL, NULL, NULL} }; zend_module_entry openssl_module_entry = { "openssl", openssl_functions, PHP_MINIT(openssl), NULL, NULL, NULL, PHP_MINFO(openssl), STANDARD_MODULE_PROPERTIES }; #ifdef COMPILE_DL_OPENSSL ZEND_GET_MODULE(openssl) #endif static void _php_pkey_free(zend_rsrc_list_entry *rsrc); static void _php_x509_free(zend_rsrc_list_entry *rsrc); static int le_key, le_x509; PHP_MINIT_FUNCTION(openssl) { le_key = zend_register_list_destructors_ex(_php_pkey_free, NULL, "OpenSSL key", module_number); le_x509 = zend_register_list_destructors_ex(_php_x509_free, NULL, "OpenSSL X.509", module_number); return SUCCESS; } PHP_MINFO_FUNCTION(openssl) { php_info_print_table_start(); php_info_print_table_row(2, "OpenSSL support", "enabled"); php_info_print_table_row(2, "OpenSSL Version", OPENSSL_VERSION_TEXT); php_info_print_table_end(); } /* {{{ proto int openssl_read_privatekey(int fp) Read private key */ PHP_FUNCTION(openssl_read_privatekey) { zval **file; EVP_PKEY *pkey; FILE *fp; if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &file) == FAILURE) { WRONG_PARAM_COUNT; } ZEND_FETCH_RESOURCE(fp, FILE *, file, -1, "File-Handle", php_file_le_fopen()); pkey = (EVP_PKEY *) PEM_read_PrivateKey(fp, NULL, NULL, NULL); if (pkey == NULL) { RETURN_FALSE; } ZEND_REGISTER_RESOURCE(return_value, pkey, le_key); } /* }}} */ /* {{{ proto int openssl_read_publickey(int x509) Read public key */ PHP_FUNCTION(openssl_read_publickey) { zval **x509; X509 *cert; EVP_PKEY *pkey; if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &x509) == FAILURE) { WRONG_PARAM_COUNT; } ZEND_FETCH_RESOURCE(cert, X509 *, x509, -1, "OpenSSL X.509", le_x509); pkey = (EVP_PKEY *) X509_get_pubkey(cert); if (pkey == NULL) { RETURN_FALSE; } ZEND_REGISTER_RESOURCE(return_value, pkey, le_key); } /* }}} */ /* {{{ proto void openssl_free_key(int key) Free key */ PHP_FUNCTION(openssl_free_key) { zval **key; EVP_PKEY *pkey; if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &key) == FAILURE) { WRONG_PARAM_COUNT; } ZEND_FETCH_RESOURCE(pkey, EVP_PKEY *, key, -1, "OpenSSL key", le_key); zend_list_delete((*key)->value.lval); } /* }}} */ /* {{{ proto int openssl_read_x509(int fp) Read X.509 certificate */ PHP_FUNCTION(openssl_read_x509) { zval **file; X509 *x509; FILE *fp; if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &file) == FAILURE) { WRONG_PARAM_COUNT; } ZEND_FETCH_RESOURCE(fp, FILE *, file, -1, "File-Handle", php_file_le_fopen()); x509 = (X509 *) PEM_read_X509(fp, NULL, NULL, NULL); if (x509 == NULL) { RETURN_FALSE; } ZEND_REGISTER_RESOURCE(return_value, x509, le_x509); } /* }}} */ /* {{{ proto void openssl_free_x509(int x509) Free X.509 certificate */ PHP_FUNCTION(openssl_free_x509) { zval **x509; X509 *cert; if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &x509) == FAILURE) { WRONG_PARAM_COUNT; } ZEND_FETCH_RESOURCE(cert, X509 *, x509, -1, "OpenSSL X.509", le_x509); zend_list_delete((*x509)->value.lval); } /* }}} */ /* {{{ proto bool openssl_sign(string data, string signature, int key) Sign data */ PHP_FUNCTION(openssl_sign) { zval **key, **data, **signature; EVP_PKEY *pkey; int siglen; unsigned char *sigbuf; EVP_MD_CTX md_ctx; if (ZEND_NUM_ARGS() != 3 || zend_get_parameters_ex(3, &data, &signature, &key) == FAILURE) { WRONG_PARAM_COUNT; } convert_to_string_ex(data); ZEND_FETCH_RESOURCE(pkey, EVP_PKEY *, key, -1, "OpenSSL key", le_key); siglen = EVP_PKEY_size(pkey); sigbuf = emalloc(siglen + 1); if (sigbuf == NULL) { RETURN_FALSE; } EVP_SignInit(&md_ctx, EVP_sha1()); EVP_SignUpdate(&md_ctx, (*data)->value.str.val, (*data)->value.str.len); if (EVP_SignFinal (&md_ctx, sigbuf, &siglen, pkey)) { zval_dtor(*signature); sigbuf[siglen] = '\0'; ZVAL_STRINGL(*signature, sigbuf, siglen, 0); RETURN_TRUE; } else { RETURN_FALSE; efree(sigbuf); } } /* }}} */ /* {{{ proto int openssl_verify(string data, string signature, int key) Verify data */ PHP_FUNCTION(openssl_verify) { zval **key, **data, **signature; EVP_PKEY *pkey; int err; EVP_MD_CTX md_ctx; if (ZEND_NUM_ARGS() != 3 || zend_get_parameters_ex(3, &data, &signature, &key) == FAILURE) { WRONG_PARAM_COUNT; } convert_to_string_ex(data); convert_to_string_ex(signature); ZEND_FETCH_RESOURCE(pkey, EVP_PKEY *, key, -1, "OpenSSL key", le_key); EVP_VerifyInit (&md_ctx, EVP_sha1()); EVP_VerifyUpdate (&md_ctx, (*data)->value.str.val, (*data)->value.str.len); err = EVP_VerifyFinal (&md_ctx, (*signature)->value.str.val, (*signature)->value.str.len, pkey); RETURN_LONG(err); } /* }}} */ /* {{{ proto int openssl_seal(string data, string sealdata, array ekeys, string ivec, array pubkeys) Seal data */ PHP_FUNCTION(openssl_seal) { zval **pubkeys, **pubkey, **data, **sealdata, **ekeys, **ivec; HashTable *pubkeysht; HashPosition pos; EVP_PKEY **pkeys; int i, len1, len2, *eksl, ivlen, nkeys; unsigned char *buf, **eks, *iv; EVP_CIPHER_CTX ctx; if (ZEND_NUM_ARGS() != 5 || zend_get_parameters_ex(5, &data, &sealdata, &ekeys, &ivec, &pubkeys) == FAILURE) { WRONG_PARAM_COUNT; } SEPARATE_ZVAL(pubkeys); pubkeysht = HASH_OF(*pubkeys); nkeys = pubkeysht ? zend_hash_num_elements(pubkeysht) : 0; if (!nkeys) { php_error(E_WARNING, "Fifth argument to openssl_seal() must be a non-empty array"); RETURN_FALSE; } pkeys = emalloc(nkeys * sizeof(*pkeys)); if (pkeys == NULL) { RETURN_FALSE; } eksl = emalloc(nkeys * sizeof(*eksl)); if (eksl == NULL) { efree(pkeys); RETURN_FALSE; } eks = emalloc(nkeys * sizeof(*eks)); if (eks == NULL) { efree(eksl); efree(pkeys); RETURN_FALSE; } convert_to_string_ex(data); zend_hash_internal_pointer_reset_ex(pubkeysht, &pos); i = 0; while (zend_hash_get_current_data_ex(pubkeysht, (void **) &pubkey, &pos) == SUCCESS) { ZEND_FETCH_RESOURCE(pkeys[i], EVP_PKEY *, pubkey, -1, "OpenSSL key", le_key); eks[i] = emalloc(EVP_PKEY_size(pkeys[i]) + 1); if (eks[i] == NULL) { while (i--) { efree(eks[i]); } efree(eks); efree(eksl); efree(pkeys); RETURN_FALSE; } zend_hash_move_forward_ex(pubkeysht, &pos); i++; } if (!EVP_EncryptInit(&ctx,EVP_rc4(),NULL,NULL)) { for (i=0; i<nkeys; i++) { efree(eks[i]); } efree(eks); efree(eksl); efree(pkeys); RETURN_FALSE; } ivlen = EVP_CIPHER_CTX_iv_length(&ctx); if (ivlen) { iv = emalloc(ivlen + 1); if (iv == NULL) { for (i=0; i<nkeys; i++) { efree(eks[i]); } efree(eks); efree(eksl); efree(pkeys); RETURN_FALSE; } } else { iv = NULL; } /* allocate one byte extra to make room for \0 */ buf = emalloc((*data)->value.str.len + EVP_CIPHER_CTX_block_size(&ctx)); if (buf == NULL) { efree(iv); for (i=0; i<nkeys; i++) { efree(eks[i]); } efree(eks); efree(eksl); efree(pkeys); RETURN_FALSE; } if (!EVP_SealInit(&ctx, EVP_rc4(), eks, eksl, iv, pkeys, nkeys) || !EVP_SealUpdate(&ctx, buf, &len1, (*data)->value.str.val, (*data)->value.str.len)) { efree(buf); efree(iv); for (i=0; i<nkeys; i++) { efree(eks[i]); } efree(eks); efree(eksl); efree(pkeys); RETURN_FALSE; } EVP_SealFinal(&ctx, buf + len1, &len2); efree(pkeys); if (len1 + len2 > 0) { zval_dtor(*sealdata); buf[len1 + len2] = '\0'; ZVAL_STRINGL(*sealdata, erealloc(buf, len1 + len2 + 1), len1 + len2, 0); zval_dtor(*ekeys); if (array_init(*ekeys) == FAILURE) { php_error(E_ERROR, "Cannot initialize return value"); efree(iv); for (i=0; i<nkeys; i++) { efree(eks[i]); } efree(eks); efree(eksl); RETURN_FALSE; } for (i=0; i<nkeys; i++) { eks[i][eksl[i]] = '\0'; add_next_index_stringl(*ekeys, erealloc(eks[i], eksl[i] + 1), eksl[i], 0); } efree(eks); efree(eksl); zval_dtor(*ivec); if (ivlen) { iv[ivlen] = '\0'; ZVAL_STRINGL(*ivec, erealloc(iv, ivlen + 1), ivlen, 0); } else { ZVAL_EMPTY_STRING(*ivec); } } else { efree(buf); efree(iv); for (i=0; i<nkeys; i++) { efree(eks[i]); } efree(eks); efree(eksl); } RETURN_LONG(len1 + len2); } /* }}} */ /* {{{ proto bool openssl_open(string data, string opendata, string ekey, string ivec, int privkey) Open data */ PHP_FUNCTION(openssl_open) { zval **privkey, **data, **opendata, **ekey, **ivec; EVP_PKEY *pkey; int len1, len2, ekl, ivlen; unsigned char *buf, *ek, *iv; EVP_CIPHER_CTX ctx; if (ZEND_NUM_ARGS() != 5 || zend_get_parameters_ex(5, &data, &opendata, &ekey, &ivec, &privkey) == FAILURE) { WRONG_PARAM_COUNT; } convert_to_string_ex(data); convert_to_string_ex(ekey); convert_to_string_ex(ivec); ZEND_FETCH_RESOURCE(pkey, EVP_PKEY *, privkey, -1, "OpenSSL key", le_key); buf = emalloc((*data)->value.str.len + 1); if (buf == NULL) { RETURN_FALSE; } if (!EVP_OpenInit(&ctx, EVP_rc4(), (*ekey)->value.str.val, (*ekey)->value.str.len, (*ivec)->value.str.val, pkey) || !EVP_OpenUpdate(&ctx, buf, &len1, (*data)->value.str.val, (*data)->value.str.len) || !EVP_OpenFinal(&ctx, buf + len1, &len2) || (len1 + len2 == 0)) { efree(buf); RETURN_FALSE; } zval_dtor(*opendata); buf[len1 + len2] = '\0'; ZVAL_STRINGL(*opendata, erealloc(buf, len1 + len2 + 1), len1 + len2, 0); RETURN_TRUE; } /* }}} */ /* {{{ _php_pkey_free() */ static void _php_pkey_free(zend_rsrc_list_entry *rsrc) { EVP_PKEY *pkey = (EVP_PKEY *)rsrc->ptr; EVP_PKEY_free(pkey); } /* }}} */ /* {{{ _php_x509_free() */ static void _php_x509_free(zend_rsrc_list_entry *rsrc) { X509 *x509 = (X509 *)rsrc->ptr; X509_free(x509); } /* }}} */ /* * Local variables: * tab-width: 8 * c-basic-offset: 8 * End: */ Index: php4/ext/openssl/php_openssl.h +++ php4/ext/openssl/php_openssl.h /* +----------------------------------------------------------------------+ | PHP version 4.0 | +----------------------------------------------------------------------+ | Copyright (c) 1997, 1998, 1999, 2000 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 2.02 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | | available at through the world-wide-web at | | http://www.php.net/license/2_02.txt. | | If you did not receive a copy of the PHP license and are unable to | | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ | Authors: Stig Venaas <venaas@php.net> | +----------------------------------------------------------------------+ */ /* $Id: php_openssl.h,v 1.1 2000/11/13 19:47:19 venaas Exp $ */ #ifndef PHP_OPENSSL_H #define PHP_OPENSSL_H /* HAVE_OPENSSL would include SSL MySQL stuff */ #if HAVE_OPENSSL_EXT extern zend_module_entry openssl_module_entry; #define phpext_openssl_ptr &openssl_module_entry PHP_MINIT_FUNCTION(openssl); PHP_MINFO_FUNCTION(openssl); PHP_FUNCTION(openssl_read_privatekey); PHP_FUNCTION(openssl_read_publickey); PHP_FUNCTION(openssl_free_key); PHP_FUNCTION(openssl_read_x509); PHP_FUNCTION(openssl_free_x509); PHP_FUNCTION(openssl_sign); PHP_FUNCTION(openssl_verify); PHP_FUNCTION(openssl_seal); PHP_FUNCTION(openssl_open); #else #define phpext_extname_ptr NULL #endif #endif /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: */
Index: php4/ext/openssl/Makefile.in +++ php4/ext/openssl/Makefile.in # $Id: Makefile.in,v 1.1 2000/11/13 19:47:19 venaas Exp $ LTLIBRARY_NAME = libopenssl.la LTLIBRARY_SOURCES = openssl.c LTLIBRARY_SHARED_NAME = openssl.la include $(top_srcdir)/build/dynlib.mk Index: php4/ext/openssl/config.m4 +++ php4/ext/openssl/config.m4 dnl $Id: config.m4,v 1.1 2000/11/13 19:47:19 venaas Exp $ dnl config.m4 for extension OpenSSL if test "$OPENSSL_DIR"; then PHP_EXTENSION(openssl, $ext_shared) AC_DEFINE(HAVE_OPENSSL_EXT,1,[ ]) fi Index: php4/ext/openssl/openssl.c +++ php4/ext/openssl/openssl.c /* +----------------------------------------------------------------------+ | PHP version 4.0 | +----------------------------------------------------------------------+ | Copyright (c) 1997, 1998, 1999, 2000 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 2.02 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | | available at through the world-wide-web at | | http://www.php.net/license/2_02.txt. | | If you did not receive a copy of the PHP license and are unable to | | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ | Authors: Stig Venaas <venaas@php.net> | +----------------------------------------------------------------------+ */ /* $Id: openssl.c,v 1.1 2000/11/13 19:47:19 venaas Exp $ */ #include "php.h" #include "php_openssl.h" /* PHP Includes */ #include "ext/standard/file.h" #include "ext/standard/info.h" /* OpenSSL includes */ #include <openssl/evp.h> #include <openssl/x509.h> static unsigned char second_argument_force_ref[] = { 3, BYREF_NONE, BYREF_FORCE, BYREF_NONE }; static unsigned char second_to_fourth_argument_force_ref[] = { 5, BYREF_NONE, BYREF_FORCE, BYREF_FORCE, BYREF_FORCE, BYREF_NONE }; function_entry openssl_functions[] = { PHP_FE(openssl_read_privatekey, NULL) PHP_FE(openssl_read_publickey, NULL) PHP_FE(openssl_free_key, NULL) PHP_FE(openssl_read_x509, NULL) PHP_FE(openssl_free_x509, NULL) PHP_FE(openssl_sign, second_argument_force_ref) PHP_FE(openssl_verify, NULL) PHP_FE(openssl_seal, second_to_fourth_argument_force_ref) PHP_FE(openssl_open, second_argument_force_ref) {NULL, NULL, NULL} }; zend_module_entry openssl_module_entry = { "openssl", openssl_functions, PHP_MINIT(openssl), NULL, NULL, NULL, PHP_MINFO(openssl), STANDARD_MODULE_PROPERTIES }; #ifdef COMPILE_DL_OPENSSL ZEND_GET_MODULE(openssl) #endif static void _php_pkey_free(zend_rsrc_list_entry *rsrc); static void _php_x509_free(zend_rsrc_list_entry *rsrc); static int le_key, le_x509; PHP_MINIT_FUNCTION(openssl) { le_key = zend_register_list_destructors_ex(_php_pkey_free, NULL, "OpenSSL key", module_number); le_x509 = zend_register_list_destructors_ex(_php_x509_free, NULL, "OpenSSL X.509", module_number); return SUCCESS; } PHP_MINFO_FUNCTION(openssl) { php_info_print_table_start(); php_info_print_table_row(2, "OpenSSL support", "enabled"); php_info_print_table_row(2, "OpenSSL Version", OPENSSL_VERSION_TEXT); php_info_print_table_end(); } /* {{{ proto int openssl_read_privatekey(int fp) Read private key */ PHP_FUNCTION(openssl_read_privatekey) { zval **file; EVP_PKEY *pkey; FILE *fp; if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &file) == FAILURE) { WRONG_PARAM_COUNT; } ZEND_FETCH_RESOURCE(fp, FILE *, file, -1, "File-Handle", php_file_le_fopen()); pkey = (EVP_PKEY *) PEM_read_PrivateKey(fp, NULL, NULL, NULL); if (pkey == NULL) { RETURN_FALSE; } ZEND_REGISTER_RESOURCE(return_value, pkey, le_key); } /* }}} */ /* {{{ proto int openssl_read_publickey(int x509) Read public key */ PHP_FUNCTION(openssl_read_publickey) { zval **x509; X509 *cert; EVP_PKEY *pkey; if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &x509) == FAILURE) { WRONG_PARAM_COUNT; } ZEND_FETCH_RESOURCE(cert, X509 *, x509, -1, "OpenSSL X.509", le_x509); pkey = (EVP_PKEY *) X509_get_pubkey(cert); if (pkey == NULL) { RETURN_FALSE; } ZEND_REGISTER_RESOURCE(return_value, pkey, le_key); } /* }}} */ /* {{{ proto void openssl_free_key(int key) Free key */ PHP_FUNCTION(openssl_free_key) { zval **key; EVP_PKEY *pkey; if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &key) == FAILURE) { WRONG_PARAM_COUNT; } ZEND_FETCH_RESOURCE(pkey, EVP_PKEY *, key, -1, "OpenSSL key", le_key); zend_list_delete((*key)->value.lval); } /* }}} */ /* {{{ proto int openssl_read_x509(int fp) Read X.509 certificate */ PHP_FUNCTION(openssl_read_x509) { zval **file; X509 *x509; FILE *fp; if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &file) == FAILURE) { WRONG_PARAM_COUNT; } ZEND_FETCH_RESOURCE(fp, FILE *, file, -1, "File-Handle", php_file_le_fopen()); x509 = (X509 *) PEM_read_X509(fp, NULL, NULL, NULL); if (x509 == NULL) { RETURN_FALSE; } ZEND_REGISTER_RESOURCE(return_value, x509, le_x509); } /* }}} */ /* {{{ proto void openssl_free_x509(int x509) Free X.509 certificate */ PHP_FUNCTION(openssl_free_x509) { zval **x509; X509 *cert; if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &x509) == FAILURE) { WRONG_PARAM_COUNT; } ZEND_FETCH_RESOURCE(cert, X509 *, x509, -1, "OpenSSL X.509", le_x509); zend_list_delete((*x509)->value.lval); } /* }}} */ /* {{{ proto bool openssl_sign(string data, string signature, int key) Sign data */ PHP_FUNCTION(openssl_sign) { zval **key, **data, **signature; EVP_PKEY *pkey; int siglen; unsigned char *sigbuf; EVP_MD_CTX md_ctx; if (ZEND_NUM_ARGS() != 3 || zend_get_parameters_ex(3, &data, &signature, &key) == FAILURE) { WRONG_PARAM_COUNT; } convert_to_string_ex(data); ZEND_FETCH_RESOURCE(pkey, EVP_PKEY *, key, -1, "OpenSSL key", le_key); siglen = EVP_PKEY_size(pkey); sigbuf = emalloc(siglen + 1); if (sigbuf == NULL) { RETURN_FALSE; } EVP_SignInit(&md_ctx, EVP_sha1()); EVP_SignUpdate(&md_ctx, (*data)->value.str.val, (*data)->value.str.len); if (EVP_SignFinal (&md_ctx, sigbuf, &siglen, pkey)) { zval_dtor(*signature); sigbuf[siglen] = '\0'; ZVAL_STRINGL(*signature, sigbuf, siglen, 0); RETURN_TRUE; } else { RETURN_FALSE; efree(sigbuf); } } /* }}} */ /* {{{ proto int openssl_verify(string data, string signature, int key) Verify data */ PHP_FUNCTION(openssl_verify) { zval **key, **data, **signature; EVP_PKEY *pkey; int err; EVP_MD_CTX md_ctx; if (ZEND_NUM_ARGS() != 3 || zend_get_parameters_ex(3, &data, &signature, &key) == FAILURE) { WRONG_PARAM_COUNT; } convert_to_string_ex(data); convert_to_string_ex(signature); ZEND_FETCH_RESOURCE(pkey, EVP_PKEY *, key, -1, "OpenSSL key", le_key); EVP_VerifyInit (&md_ctx, EVP_sha1()); EVP_VerifyUpdate (&md_ctx, (*data)->value.str.val, (*data)->value.str.len); err = EVP_VerifyFinal (&md_ctx, (*signature)->value.str.val, (*signature)->value.str.len, pkey); RETURN_LONG(err); } /* }}} */ /* {{{ proto int openssl_seal(string data, string sealdata, array ekeys, string ivec, array pubkeys) Seal data */ PHP_FUNCTION(openssl_seal) { zval **pubkeys, **pubkey, **data, **sealdata, **ekeys, **ivec; HashTable *pubkeysht; HashPosition pos; EVP_PKEY **pkeys; int i, len1, len2, *eksl, ivlen, nkeys; unsigned char *buf, **eks, *iv; EVP_CIPHER_CTX ctx; if (ZEND_NUM_ARGS() != 5 || zend_get_parameters_ex(5, &data, &sealdata, &ekeys, &ivec, &pubkeys) == FAILURE) { WRONG_PARAM_COUNT; } SEPARATE_ZVAL(pubkeys); pubkeysht = HASH_OF(*pubkeys); nkeys = pubkeysht ? zend_hash_num_elements(pubkeysht) : 0; if (!nkeys) { php_error(E_WARNING, "Fifth argument to openssl_seal() must be a non-empty array"); RETURN_FALSE; } pkeys = emalloc(nkeys * sizeof(*pkeys)); if (pkeys == NULL) { RETURN_FALSE; } eksl = emalloc(nkeys * sizeof(*eksl)); if (eksl == NULL) { efree(pkeys); RETURN_FALSE; } eks = emalloc(nkeys * sizeof(*eks)); if (eks == NULL) { efree(eksl); efree(pkeys); RETURN_FALSE; } convert_to_string_ex(data); zend_hash_internal_pointer_reset_ex(pubkeysht, &pos); i = 0; while (zend_hash_get_current_data_ex(pubkeysht, (void **) &pubkey, &pos) == SUCCESS) { ZEND_FETCH_RESOURCE(pkeys[i], EVP_PKEY *, pubkey, -1, "OpenSSL key", le_key); eks[i] = emalloc(EVP_PKEY_size(pkeys[i]) + 1); if (eks[i] == NULL) { while (i--) { efree(eks[i]); } efree(eks); efree(eksl); efree(pkeys); RETURN_FALSE; } zend_hash_move_forward_ex(pubkeysht, &pos); i++; } if (!EVP_EncryptInit(&ctx,EVP_rc4(),NULL,NULL)) { for (i=0; i<nkeys; i++) { efree(eks[i]); } efree(eks); efree(eksl); efree(pkeys); RETURN_FALSE; } ivlen = EVP_CIPHER_CTX_iv_length(&ctx); if (ivlen) { iv = emalloc(ivlen + 1); if (iv == NULL) { for (i=0; i<nkeys; i++) { efree(eks[i]); } efree(eks); efree(eksl); efree(pkeys); RETURN_FALSE; } } else { iv = NULL; } /* allocate one byte extra to make room for \0 */ buf = emalloc((*data)->value.str.len + EVP_CIPHER_CTX_block_size(&ctx)); if (buf == NULL) { efree(iv); for (i=0; i<nkeys; i++) { efree(eks[i]); } efree(eks); efree(eksl); efree(pkeys); RETURN_FALSE; } if (!EVP_SealInit(&ctx, EVP_rc4(), eks, eksl, iv, pkeys, nkeys) || !EVP_SealUpdate(&ctx, buf, &len1, (*data)->value.str.val, (*data)->value.str.len)) { efree(buf); efree(iv); for (i=0; i<nkeys; i++) { efree(eks[i]); } efree(eks); efree(eksl); efree(pkeys); RETURN_FALSE; } EVP_SealFinal(&ctx, buf + len1, &len2); efree(pkeys); if (len1 + len2 > 0) { zval_dtor(*sealdata); buf[len1 + len2] = '\0'; ZVAL_STRINGL(*sealdata, erealloc(buf, len1 + len2 + 1), len1 + len2, 0); zval_dtor(*ekeys); if (array_init(*ekeys) == FAILURE) { php_error(E_ERROR, "Cannot initialize return value"); efree(iv); for (i=0; i<nkeys; i++) { efree(eks[i]); } efree(eks); efree(eksl); RETURN_FALSE; } for (i=0; i<nkeys; i++) { eks[i][eksl[i]] = '\0'; add_next_index_stringl(*ekeys, erealloc(eks[i], eksl[i] + 1), eksl[i], 0); } efree(eks); efree(eksl); zval_dtor(*ivec); if (ivlen) { iv[ivlen] = '\0'; ZVAL_STRINGL(*ivec, erealloc(iv, ivlen + 1), ivlen, 0); } else { ZVAL_EMPTY_STRING(*ivec); } } else { efree(buf); efree(iv); for (i=0; i<nkeys; i++) { efree(eks[i]); } efree(eks); efree(eksl); } RETURN_LONG(len1 + len2); } /* }}} */ /* {{{ proto bool openssl_open(string data, string opendata, string ekey, string ivec, int privkey) Open data */ PHP_FUNCTION(openssl_open) { zval **privkey, **data, **opendata, **ekey, **ivec; EVP_PKEY *pkey; int len1, len2, ekl, ivlen; unsigned char *buf, *ek, *iv; EVP_CIPHER_CTX ctx; if (ZEND_NUM_ARGS() != 5 || zend_get_parameters_ex(5, &data, &opendata, &ekey, &ivec, &privkey) == FAILURE) { WRONG_PARAM_COUNT; } convert_to_string_ex(data); convert_to_string_ex(ekey); convert_to_string_ex(ivec); ZEND_FETCH_RESOURCE(pkey, EVP_PKEY *, privkey, -1, "OpenSSL key", le_key); buf = emalloc((*data)->value.str.len + 1); if (buf == NULL) { RETURN_FALSE; } if (!EVP_OpenInit(&ctx, EVP_rc4(), (*ekey)->value.str.val, (*ekey)->value.str.len, (*ivec)->value.str.val, pkey) || !EVP_OpenUpdate(&ctx, buf, &len1, (*data)->value.str.val, (*data)->value.str.len) || !EVP_OpenFinal(&ctx, buf + len1, &len2) || (len1 + len2 == 0)) { efree(buf); RETURN_FALSE; } zval_dtor(*opendata); buf[len1 + len2] = '\0'; ZVAL_STRINGL(*opendata, erealloc(buf, len1 + len2 + 1), len1 + len2, 0); RETURN_TRUE; } /* }}} */ /* {{{ _php_pkey_free() */ static void _php_pkey_free(zend_rsrc_list_entry *rsrc) { EVP_PKEY *pkey = (EVP_PKEY *)rsrc->ptr; EVP_PKEY_free(pkey); } /* }}} */ /* {{{ _php_x509_free() */ static void _php_x509_free(zend_rsrc_list_entry *rsrc) { X509 *x509 = (X509 *)rsrc->ptr; X509_free(x509); } /* }}} */ /* * Local variables: * tab-width: 8 * c-basic-offset: 8 * End: */ Index: php4/ext/openssl/php_openssl.h +++ php4/ext/openssl/php_openssl.h /* +----------------------------------------------------------------------+ | PHP version 4.0 | +----------------------------------------------------------------------+ | Copyright (c) 1997, 1998, 1999, 2000 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 2.02 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | | available at through the world-wide-web at | | http://www.php.net/license/2_02.txt. | | If you did not receive a copy of the PHP license and are unable to | | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ | Authors: Stig Venaas <venaas@php.net> | +----------------------------------------------------------------------+ */ /* $Id: php_openssl.h,v 1.1 2000/11/13 19:47:19 venaas Exp $ */ #ifndef PHP_OPENSSL_H #define PHP_OPENSSL_H /* HAVE_OPENSSL would include SSL MySQL stuff */ #if HAVE_OPENSSL_EXT extern zend_module_entry openssl_module_entry; #define phpext_openssl_ptr &openssl_module_entry PHP_MINIT_FUNCTION(openssl); PHP_MINFO_FUNCTION(openssl); PHP_FUNCTION(openssl_read_privatekey); PHP_FUNCTION(openssl_read_publickey); PHP_FUNCTION(openssl_free_key); PHP_FUNCTION(openssl_read_x509); PHP_FUNCTION(openssl_free_x509); PHP_FUNCTION(openssl_sign); PHP_FUNCTION(openssl_verify); PHP_FUNCTION(openssl_seal); PHP_FUNCTION(openssl_open); #else #define phpext_extname_ptr NULL #endif #endif /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: */