From: Stig Venaas Date: Mon, 13 Nov 2000 19:47:20 +0000 (+0000) Subject: OpenSSL extension. So far it implements assymetric encryption functions. X-Git-Tag: php-4.0.4RC3~215 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=86b7cd0572cb61a2009c4118f643fe23cbd4f092;p=php OpenSSL extension. So far it implements assymetric encryption functions. --- diff --git a/ext/openssl/Makefile.in b/ext/openssl/Makefile.in new file mode 100644 index 0000000000..306e6c6890 --- /dev/null +++ b/ext/openssl/Makefile.in @@ -0,0 +1,7 @@ +# $Id$ + +LTLIBRARY_NAME = libopenssl.la +LTLIBRARY_SOURCES = openssl.c +LTLIBRARY_SHARED_NAME = openssl.la + +include $(top_srcdir)/build/dynlib.mk diff --git a/ext/openssl/config.m4 b/ext/openssl/config.m4 new file mode 100644 index 0000000000..cc8421111c --- /dev/null +++ b/ext/openssl/config.m4 @@ -0,0 +1,7 @@ +dnl $Id$ +dnl config.m4 for extension OpenSSL + +if test "$OPENSSL_DIR"; then + PHP_EXTENSION(openssl, $ext_shared) + AC_DEFINE(HAVE_OPENSSL_EXT,1,[ ]) +fi diff --git a/ext/openssl/openssl.c b/ext/openssl/openssl.c new file mode 100644 index 0000000000..c4ca7d40c5 --- /dev/null +++ b/ext/openssl/openssl.c @@ -0,0 +1,496 @@ +/* + +----------------------------------------------------------------------+ + | 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 | + +----------------------------------------------------------------------+ + */ + +/* $Id$ */ + +#include "php.h" +#include "php_openssl.h" + +/* PHP Includes */ +#include "ext/standard/file.h" +#include "ext/standard/info.h" + +/* OpenSSL includes */ +#include +#include + +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; ivalue.str.len + EVP_CIPHER_CTX_block_size(&ctx)); + if (buf == NULL) { + efree(iv); + for (i=0; ivalue.str.val, + (*data)->value.str.len)) { + efree(buf); + efree(iv); + for (i=0; i 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; ivalue.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: + */ diff --git a/ext/openssl/php_openssl.h b/ext/openssl/php_openssl.h new file mode 100644 index 0000000000..5512c248ad --- /dev/null +++ b/ext/openssl/php_openssl.h @@ -0,0 +1,53 @@ +/* + +----------------------------------------------------------------------+ + | 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 | + +----------------------------------------------------------------------+ + */ + +/* $Id$ */ + +#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: + */