forked from Lainports/opnsense-ports
security/php70-openssl: add crl patches
Porting that stuff to PHP 7 has been quite the adventure. Needs proper testing as soon as we can roll out a first test build.
This commit is contained in:
parent
cf3b1a4eca
commit
c6db9d8a7a
2 changed files with 744 additions and 0 deletions
721
security/php70-openssl/files/patch-openssl.c
Normal file
721
security/php70-openssl/files/patch-openssl.c
Normal file
|
|
@ -0,0 +1,721 @@
|
|||
--- openssl.c.orig 2016-01-06 10:05:22 UTC
|
||||
+++ openssl.c
|
||||
@@ -17,6 +17,7 @@
|
||||
| Sascha Kettler <kettler@gmx.net> |
|
||||
| Pierre-Alain Joye <pierre@php.net> |
|
||||
| Marc Delling <delling@silpion.de> (PKCS12 functions) |
|
||||
+ | Moritz Bechler <mbechler@eenterphace.org> (CRL support) |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
@@ -55,6 +56,7 @@
|
||||
#include <openssl/rand.h>
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/pkcs12.h>
|
||||
+#include <openssl/ocsp.h>
|
||||
|
||||
/* Common */
|
||||
#include <time.h>
|
||||
@@ -126,6 +128,56 @@ PHP_FUNCTION(openssl_dh_compute_key);
|
||||
PHP_FUNCTION(openssl_random_pseudo_bytes);
|
||||
|
||||
/* {{{ arginfo */
|
||||
+ZEND_BEGIN_ARG_INFO_EX(arginfo_openssl_crl_export_file, 0, 0, 3)
|
||||
+ ZEND_ARG_INFO(0, crl)
|
||||
+ ZEND_ARG_INFO(0, filename)
|
||||
+ ZEND_ARG_INFO(0, capkey)
|
||||
+ ZEND_ARG_INFO(0, crlv2)
|
||||
+ ZEND_ARG_INFO(0, notext)
|
||||
+ ZEND_ARG_INFO(0, capass)
|
||||
+ZEND_END_ARG_INFO()
|
||||
+
|
||||
+ZEND_BEGIN_ARG_INFO_EX(arginfo_openssl_crl_export, 0, 0, 3)
|
||||
+ ZEND_ARG_INFO(0, crl)
|
||||
+ ZEND_ARG_INFO(1, data)
|
||||
+ ZEND_ARG_INFO(0, capkey)
|
||||
+ ZEND_ARG_INFO(0, crlv2)
|
||||
+ ZEND_ARG_INFO(0, notext)
|
||||
+ ZEND_ARG_INFO(0, capass)
|
||||
+ZEND_END_ARG_INFO()
|
||||
+
|
||||
+ZEND_BEGIN_ARG_INFO_EX(arginfo_openssl_crl_revoke_cert, 0, 0, 3)
|
||||
+ ZEND_ARG_INFO(0, crl)
|
||||
+ ZEND_ARG_INFO(0, certficate)
|
||||
+ ZEND_ARG_INFO(0, revokation_date)
|
||||
+ ZEND_ARG_INFO(0, reason)
|
||||
+ ZEND_ARG_INFO(0, compromise_date)
|
||||
+ ZEND_ARG_INFO(0, hold_instruction)
|
||||
+ZEND_END_ARG_INFO()
|
||||
+
|
||||
+ZEND_BEGIN_ARG_INFO_EX(arginfo_openssl_crl_revoke_cert_by_serial, 0, 0, 3)
|
||||
+ ZEND_ARG_INFO(0, crl)
|
||||
+ ZEND_ARG_INFO(0, revoke_serial)
|
||||
+ ZEND_ARG_INFO(0, revokation_date)
|
||||
+ ZEND_ARG_INFO(0, reason)
|
||||
+ ZEND_ARG_INFO(0, compromise_date)
|
||||
+ ZEND_ARG_INFO(0, hold_instruction)
|
||||
+ZEND_END_ARG_INFO()
|
||||
+
|
||||
+ZEND_BEGIN_ARG_INFO_EX(arginfo_openssl_crl_new, 0, 0, 1)
|
||||
+ ZEND_ARG_INFO(0, cacert)
|
||||
+ ZEND_ARG_INFO(0, crlserial)
|
||||
+ ZEND_ARG_INFO(0, lifetime)
|
||||
+ZEND_END_ARG_INFO()
|
||||
+
|
||||
+ZEND_BEGIN_ARG_INFO_EX(arginfo_openssl_x509_check, 0, 0, 4)
|
||||
+ ZEND_ARG_INFO(0, x509cert)
|
||||
+ ZEND_ARG_INFO(0, purpose)
|
||||
+ ZEND_ARG_INFO(0, flags)
|
||||
+ ZEND_ARG_INFO(0, cainfo)
|
||||
+ ZEND_ARG_INFO(0, untrustedfile)
|
||||
+ZEND_END_ARG_INFO()
|
||||
+
|
||||
ZEND_BEGIN_ARG_INFO_EX(arginfo_openssl_x509_export_to_file, 0, 0, 2)
|
||||
ZEND_ARG_INFO(0, x509)
|
||||
ZEND_ARG_INFO(0, outfilename)
|
||||
@@ -468,12 +520,20 @@ const zend_function_entry openssl_functi
|
||||
PHP_FE(openssl_x509_export, arginfo_openssl_x509_export)
|
||||
PHP_FE(openssl_x509_fingerprint, arginfo_openssl_x509_fingerprint)
|
||||
PHP_FE(openssl_x509_export_to_file, arginfo_openssl_x509_export_to_file)
|
||||
+ PHP_FE(openssl_x509_check, arginfo_openssl_x509_check)
|
||||
|
||||
/* PKCS12 funcs */
|
||||
PHP_FE(openssl_pkcs12_export, arginfo_openssl_pkcs12_export)
|
||||
PHP_FE(openssl_pkcs12_export_to_file, arginfo_openssl_pkcs12_export_to_file)
|
||||
PHP_FE(openssl_pkcs12_read, arginfo_openssl_pkcs12_read)
|
||||
|
||||
+/* for CRL creation */
|
||||
+ PHP_FE(openssl_crl_new, arginfo_openssl_crl_new)
|
||||
+ PHP_FE(openssl_crl_revoke_cert_by_serial, arginfo_openssl_crl_revoke_cert_by_serial)
|
||||
+ PHP_FE(openssl_crl_revoke_cert, arginfo_openssl_crl_revoke_cert)
|
||||
+ PHP_FE(openssl_crl_export, arginfo_openssl_crl_export)
|
||||
+ PHP_FE(openssl_crl_export_file, arginfo_openssl_crl_export_file)
|
||||
+
|
||||
/* CSR funcs */
|
||||
PHP_FE(openssl_csr_new, arginfo_openssl_csr_new)
|
||||
PHP_FE(openssl_csr_export, arginfo_openssl_csr_export)
|
||||
@@ -559,6 +619,7 @@ ZEND_GET_MODULE(openssl)
|
||||
static int le_key;
|
||||
static int le_x509;
|
||||
static int le_csr;
|
||||
+static int le_crl;
|
||||
static int ssl_stream_data_index;
|
||||
|
||||
int php_openssl_get_x509_list_id(void) /* {{{ */
|
||||
@@ -567,6 +628,16 @@ int php_openssl_get_x509_list_id(void) /
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
+/* {{{ */
|
||||
+struct php_x509_crl {
|
||||
+ X509_CRL *crl;
|
||||
+ X509 *cacert;
|
||||
+ long lifetime;
|
||||
+ int forcev2;
|
||||
+};
|
||||
+/* }}} */
|
||||
+
|
||||
+
|
||||
/* {{{ resource destructors */
|
||||
static void php_pkey_free(zend_resource *rsrc)
|
||||
{
|
||||
@@ -588,6 +659,21 @@ static void php_csr_free(zend_resource *
|
||||
X509_REQ * csr = (X509_REQ*)rsrc->ptr;
|
||||
X509_REQ_free(csr);
|
||||
}
|
||||
+
|
||||
+static void php_crl_free(zend_resource *rsrc TSRMLS_DC)
|
||||
+{
|
||||
+ struct php_x509_crl *res = (struct php_x509_crl*)rsrc->ptr;
|
||||
+
|
||||
+ if(res) {
|
||||
+ if(res->crl != NULL) {
|
||||
+ X509_CRL_free(res->crl);
|
||||
+ }
|
||||
+
|
||||
+ efree(res);
|
||||
+ }
|
||||
+
|
||||
+}
|
||||
+
|
||||
/* }}} */
|
||||
|
||||
/* {{{ openssl open_basedir check */
|
||||
@@ -1161,6 +1247,7 @@ 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);
|
||||
le_csr = zend_register_list_destructors_ex(php_csr_free, NULL, "OpenSSL X.509 CSR", module_number);
|
||||
+ le_crl = zend_register_list_destructors_ex(php_crl_free, NULL, "OpenSSL X.509 CRL", module_number);
|
||||
|
||||
SSL_library_init();
|
||||
OpenSSL_add_all_ciphers();
|
||||
@@ -1251,6 +1338,36 @@ PHP_MINIT_FUNCTION(openssl)
|
||||
REGISTER_LONG_CONSTANT("OPENSSL_RAW_DATA", OPENSSL_RAW_DATA, CONST_CS|CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("OPENSSL_ZERO_PADDING", OPENSSL_ZERO_PADDING, CONST_CS|CONST_PERSISTENT);
|
||||
|
||||
+ /* OCSP revokation states */
|
||||
+ REGISTER_LONG_CONSTANT("OCSP_REVOKED_STATUS_NOSTATUS", OCSP_REVOKED_STATUS_NOSTATUS, CONST_CS | CONST_PERSISTENT);
|
||||
+ REGISTER_LONG_CONSTANT("OCSP_REVOKED_STATUS_UNSPECIFIED", OCSP_REVOKED_STATUS_UNSPECIFIED, CONST_CS | CONST_PERSISTENT);
|
||||
+ REGISTER_LONG_CONSTANT("OCSP_REVOKED_STATUS_KEYCOMPROMISE", OCSP_REVOKED_STATUS_KEYCOMPROMISE, CONST_CS | CONST_PERSISTENT);
|
||||
+ REGISTER_LONG_CONSTANT("OCSP_REVOKED_STATUS_CACOMPROMISE", OCSP_REVOKED_STATUS_CACOMPROMISE, CONST_CS | CONST_PERSISTENT);
|
||||
+ REGISTER_LONG_CONSTANT("OCSP_REVOKED_STATUS_AFFILIATIONCHANGED", OCSP_REVOKED_STATUS_AFFILIATIONCHANGED, CONST_CS | CONST_PERSISTENT);
|
||||
+ REGISTER_LONG_CONSTANT("OCSP_REVOKED_STATUS_SUPERSEDED", OCSP_REVOKED_STATUS_SUPERSEDED, CONST_CS | CONST_PERSISTENT);
|
||||
+ REGISTER_LONG_CONSTANT("OCSP_REVOKED_STATUS_CESSATIONOFOPERATION", OCSP_REVOKED_STATUS_CESSATIONOFOPERATION, CONST_CS | CONST_PERSISTENT);
|
||||
+ REGISTER_LONG_CONSTANT("OCSP_REVOKED_STATUS_CERTIFICATEHOLD", OCSP_REVOKED_STATUS_CERTIFICATEHOLD, CONST_CS | CONST_PERSISTENT);
|
||||
+ REGISTER_LONG_CONSTANT("OCSP_REVOKED_STATUS_REMOVEFROMCRL", OCSP_REVOKED_STATUS_REMOVEFROMCRL, CONST_CS | CONST_PERSISTENT);
|
||||
+
|
||||
+ /* X509 Hold instruction NIDs */
|
||||
+ REGISTER_LONG_CONSTANT("OPENSSL_HOLDINSTRUCTION_NONE", NID_hold_instruction_none, CONST_CS | CONST_PERSISTENT);
|
||||
+ REGISTER_LONG_CONSTANT("OPENSSL_HOLDINSTRUCTION_CALL_ISSUER", NID_hold_instruction_call_issuer, CONST_CS | CONST_PERSISTENT);
|
||||
+ REGISTER_LONG_CONSTANT("OPENSSL_HOLDINSTRUCTION_REJECT", NID_hold_instruction_reject, CONST_CS | CONST_PERSISTENT);
|
||||
+
|
||||
+ /* openssl_verify flags */
|
||||
+ REGISTER_LONG_CONSTANT("X509_V_FLAG_CB_ISSUER_CHECK", X509_V_FLAG_CB_ISSUER_CHECK, CONST_CS | CONST_PERSISTENT);
|
||||
+ REGISTER_LONG_CONSTANT("X509_V_FLAG_USE_CHECK_TIME", X509_V_FLAG_USE_CHECK_TIME, CONST_CS | CONST_PERSISTENT);
|
||||
+ REGISTER_LONG_CONSTANT("X509_V_FLAG_CRL_CHECK", X509_V_FLAG_CRL_CHECK, CONST_CS | CONST_PERSISTENT);
|
||||
+ REGISTER_LONG_CONSTANT("X509_V_FLAG_CRL_CHECK_ALL", X509_V_FLAG_CRL_CHECK_ALL, CONST_CS | CONST_PERSISTENT);
|
||||
+ REGISTER_LONG_CONSTANT("X509_V_FLAG_IGNORE_CRITICAL", X509_V_FLAG_IGNORE_CRITICAL, CONST_CS | CONST_PERSISTENT);
|
||||
+ REGISTER_LONG_CONSTANT("X509_V_FLAG_X509_STRICT", X509_V_FLAG_X509_STRICT, CONST_CS | CONST_PERSISTENT);
|
||||
+ REGISTER_LONG_CONSTANT("X509_V_FLAG_ALLOW_PROXY_CERTS", X509_V_FLAG_ALLOW_PROXY_CERTS, CONST_CS | CONST_PERSISTENT);
|
||||
+ REGISTER_LONG_CONSTANT("X509_V_FLAG_POLICY_CHECK", X509_V_FLAG_POLICY_CHECK, CONST_CS | CONST_PERSISTENT);
|
||||
+ REGISTER_LONG_CONSTANT("X509_V_FLAG_EXPLICIT_POLICY", X509_V_FLAG_EXPLICIT_POLICY, CONST_CS | CONST_PERSISTENT);
|
||||
+ REGISTER_LONG_CONSTANT("X509_V_FLAG_INHIBIT_ANY", X509_V_FLAG_INHIBIT_ANY, CONST_CS | CONST_PERSISTENT);
|
||||
+ REGISTER_LONG_CONSTANT("X509_V_FLAG_INHIBIT_MAP", X509_V_FLAG_INHIBIT_MAP, CONST_CS | CONST_PERSISTENT);
|
||||
+ REGISTER_LONG_CONSTANT("X509_V_FLAG_NOTIFY_POLICY", X509_V_FLAG_NOTIFY_POLICY, CONST_CS | CONST_PERSISTENT);
|
||||
+
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x0090806fL && !defined(OPENSSL_NO_TLSEXT)
|
||||
/* SNI support included in OpenSSL >= 0.9.8j */
|
||||
REGISTER_LONG_CONSTANT("OPENSSL_TLSEXT_SERVER_NAME", 1, CONST_CS|CONST_PERSISTENT);
|
||||
@@ -2152,7 +2269,7 @@ end:
|
||||
/* }}} */
|
||||
|
||||
/* {{{ check_cert */
|
||||
-static int check_cert(X509_STORE *ctx, X509 *x, STACK_OF(X509) *untrustedchain, int purpose)
|
||||
+static int check_cert(X509_STORE *ctx, X509 *x, STACK_OF(X509) *untrustedchain, int purpose, long flags)
|
||||
{
|
||||
int ret=0;
|
||||
X509_STORE_CTX *csc;
|
||||
@@ -2163,6 +2280,11 @@ static int check_cert(X509_STORE *ctx, X
|
||||
return 0;
|
||||
}
|
||||
X509_STORE_CTX_init(csc, ctx, x, untrustedchain);
|
||||
+
|
||||
+ if(flags) {
|
||||
+ X509_STORE_CTX_set_flags(csc, flags);
|
||||
+ }
|
||||
+
|
||||
if(purpose >= 0) {
|
||||
X509_STORE_CTX_set_purpose(csc, purpose);
|
||||
}
|
||||
@@ -2173,6 +2295,59 @@ static int check_cert(X509_STORE *ctx, X
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
+/* {{{ proto int openssl_x509_check(mixed x509cert, int purpose, int flags, array cainfo [, string untrustedfile])
|
||||
+ Checks the CERT to see if it can be used for the purpose in purpose. cainfo holds information about trusted CAs.
|
||||
+ Flags should be one of the X509_V_FLAG_* constants and controls the behaviour of the check.
|
||||
+ */
|
||||
+PHP_FUNCTION(openssl_x509_check)
|
||||
+{
|
||||
+ zval * zcert, * zcainfo = NULL;
|
||||
+ X509_STORE * cainfo = NULL;
|
||||
+ X509 * cert = NULL;
|
||||
+ zend_resource * certresource = NULL;
|
||||
+ STACK_OF(X509) * untrustedchain = NULL;
|
||||
+ long purpose;
|
||||
+ char * untrusted = NULL;
|
||||
+ int untrusted_len;
|
||||
+ long flags = 0;
|
||||
+
|
||||
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zll|a!s", &zcert, &purpose, &flags, &zcainfo, &untrusted, &untrusted_len) == FAILURE) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ RETVAL_LONG(-1);
|
||||
+
|
||||
+ if (untrusted) {
|
||||
+ untrustedchain = load_all_certs_from_file(untrusted);
|
||||
+ if (untrustedchain == NULL) {
|
||||
+ goto clean_exit;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ cainfo = setup_verify(zcainfo TSRMLS_CC);
|
||||
+ if (cainfo == NULL) {
|
||||
+ goto clean_exit;
|
||||
+ }
|
||||
+ cert = php_openssl_x509_from_zval(zcert, 0, &certresource TSRMLS_CC);
|
||||
+ if (cert == NULL) {
|
||||
+ goto clean_exit;
|
||||
+ }
|
||||
+ RETVAL_LONG(check_cert(cainfo, cert, untrustedchain, purpose, flags));
|
||||
+
|
||||
+clean_exit:
|
||||
+ if (certresource == NULL && cert) {
|
||||
+ X509_free(cert);
|
||||
+ }
|
||||
+ if (cainfo) {
|
||||
+ X509_STORE_free(cainfo);
|
||||
+ }
|
||||
+ if (untrustedchain) {
|
||||
+ sk_X509_pop_free(untrustedchain, X509_free);
|
||||
+ }
|
||||
+}
|
||||
+/* }}} */
|
||||
+
|
||||
+
|
||||
/* {{{ proto int openssl_x509_checkpurpose(mixed x509cert, int purpose, array cainfo [, string untrustedfile])
|
||||
Checks the CERT to see if it can be used for the purpose in purpose. cainfo holds information about trusted CAs */
|
||||
PHP_FUNCTION(openssl_x509_checkpurpose)
|
||||
@@ -2209,7 +2384,7 @@ PHP_FUNCTION(openssl_x509_checkpurpose)
|
||||
goto clean_exit;
|
||||
}
|
||||
|
||||
- ret = check_cert(cainfo, cert, untrustedchain, (int)purpose);
|
||||
+ ret = check_cert(cainfo, cert, untrustedchain, (int)purpose, 0);
|
||||
if (ret != 0 && ret != 1) {
|
||||
RETVAL_LONG(ret);
|
||||
} else {
|
||||
@@ -5517,6 +5692,442 @@ PHP_FUNCTION(openssl_random_pseudo_bytes
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
+/* CRL creation functions */
|
||||
+
|
||||
+/* {{{ proto resource openssl_crl_new(mixed cacert[, int crlserial[, string int lifetime]])
|
||||
+ Creates a new CRL */
|
||||
+PHP_FUNCTION(openssl_crl_new)
|
||||
+{
|
||||
+ struct php_x509_crl *res = NULL;
|
||||
+ long serial = 0;
|
||||
+ ASN1_INTEGER *crl_number;
|
||||
+ long lifetime_days = 80;
|
||||
+ zend_resource *certresource;
|
||||
+ zval* zcacert;
|
||||
+
|
||||
+ if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|ll", &zcacert, &serial, &lifetime_days) == FAILURE) {
|
||||
+ RETURN_NULL();
|
||||
+ }
|
||||
+
|
||||
+ res = emalloc(sizeof(struct php_x509_crl));
|
||||
+ memset(res, 0, sizeof(struct php_x509_crl));
|
||||
+ res->lifetime = 60*60*24*lifetime_days;
|
||||
+
|
||||
+ /* Initialize CRL */
|
||||
+ res->crl = X509_CRL_new();
|
||||
+ if(res->crl == NULL) {
|
||||
+ php_error_docref(NULL TSRMLS_CC, E_WARNING,
|
||||
+ "Failed to create CRL");
|
||||
+ efree(res);
|
||||
+ RETURN_NULL();
|
||||
+ }
|
||||
+
|
||||
+ res->cacert = php_openssl_x509_from_zval(zcacert, 0, &certresource TSRMLS_CC);
|
||||
+
|
||||
+ if(!res->cacert) {
|
||||
+ X509_CRL_free(res->crl);
|
||||
+ efree(res);
|
||||
+
|
||||
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to load CA Certificate");
|
||||
+ RETURN_NULL();
|
||||
+ }
|
||||
+
|
||||
+ if (!X509_CRL_set_issuer_name(res->crl, X509_get_subject_name(res->cacert))) {
|
||||
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid ca certificate");
|
||||
+ X509_free(res->cacert);
|
||||
+ X509_CRL_free(res->crl);
|
||||
+ efree(res);
|
||||
+ RETURN_NULL();
|
||||
+ }
|
||||
+
|
||||
+ /* set CRL number (serial) (forces the crl to be version 2) */
|
||||
+ if(serial) {
|
||||
+ crl_number = ASN1_INTEGER_new();
|
||||
+ ASN1_INTEGER_set(crl_number, serial);
|
||||
+
|
||||
+ if(!X509_CRL_add1_ext_i2d(res->crl,NID_crl_number,crl_number,0,0)) {
|
||||
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to set CRL serial");
|
||||
+ ASN1_INTEGER_free(crl_number);
|
||||
+ X509_free(res->cacert);
|
||||
+ X509_CRL_free(res->crl);
|
||||
+ efree(res);
|
||||
+ RETURN_NULL();
|
||||
+ }
|
||||
+ res->forcev2 = 1;
|
||||
+
|
||||
+ ASN1_INTEGER_free(crl_number);
|
||||
+ }
|
||||
+
|
||||
+ RETURN_RES(zend_register_resource(res, le_crl));
|
||||
+}
|
||||
+/* }}} */
|
||||
+
|
||||
+/* {{{ Adds an entry to the CRL */
|
||||
+static int php_crl_revoke_serial(struct php_x509_crl *res, ASN1_INTEGER *serial, time_t rev_timestamp, long reason_code, time_t comp_timestamp, int hold TSRMLS_DC)
|
||||
+{
|
||||
+ X509_REVOKED *revoke;
|
||||
+
|
||||
+ ASN1_TIME *rev_date;
|
||||
+ ASN1_GENERALIZEDTIME *comp_date;
|
||||
+
|
||||
+ ASN1_ENUMERATED *rtmp;
|
||||
+
|
||||
+ ASN1_OBJECT *hold_instruction;
|
||||
+
|
||||
+ if(!res) {
|
||||
+ return FAILURE;
|
||||
+ }
|
||||
+
|
||||
+ revoke = X509_REVOKED_new();
|
||||
+
|
||||
+ if(!revoke) {
|
||||
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to revoke cert");
|
||||
+ X509_REVOKED_free(revoke);
|
||||
+ return FAILURE;
|
||||
+ }
|
||||
+
|
||||
+ /* Add serial to the CRL */
|
||||
+ if(!X509_REVOKED_set_serialNumber(revoke, serial)) {
|
||||
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to set serial number");
|
||||
+ X509_REVOKED_free(revoke);
|
||||
+ return FAILURE;
|
||||
+ }
|
||||
+
|
||||
+ /* Revokation date */
|
||||
+ rev_date = ASN1_UTCTIME_new();
|
||||
+ if (!ASN1_UTCTIME_set(rev_date, rev_timestamp) || !X509_REVOKED_set_revocationDate(revoke,rev_date)) {
|
||||
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to set revokation time");
|
||||
+ ASN1_UTCTIME_free(rev_date);
|
||||
+ X509_REVOKED_free(revoke);
|
||||
+ return FAILURE;
|
||||
+ }
|
||||
+ ASN1_UTCTIME_free(rev_date);
|
||||
+
|
||||
+
|
||||
+ if(reason_code && reason_code != OCSP_REVOKED_STATUS_UNSPECIFIED) {
|
||||
+ rtmp = ASN1_ENUMERATED_new();
|
||||
+ ASN1_ENUMERATED_set(rtmp, reason_code);
|
||||
+
|
||||
+ if(!X509_REVOKED_add1_ext_i2d(revoke, NID_crl_reason, rtmp, 0, 0)) {
|
||||
+ ASN1_ENUMERATED_free(rtmp);
|
||||
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to set revokation reason");
|
||||
+ return FAILURE;
|
||||
+ }
|
||||
+ res->forcev2 = 1;
|
||||
+ ASN1_ENUMERATED_free(rtmp);
|
||||
+ }
|
||||
+
|
||||
+ /* Add compromise timestamp if reason is key or ca compromise */
|
||||
+ if(comp_timestamp && (reason_code == OCSP_REVOKED_STATUS_KEYCOMPROMISE || reason_code == OCSP_REVOKED_STATUS_CACOMPROMISE)) {
|
||||
+ comp_date = ASN1_GENERALIZEDTIME_new();
|
||||
+ if (!ASN1_GENERALIZEDTIME_set(comp_date, comp_timestamp) ||
|
||||
+ !X509_REVOKED_add1_ext_i2d(revoke, NID_invalidity_date, comp_date, 0, 0)) {
|
||||
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to set compromise time");
|
||||
+ ASN1_GENERALIZEDTIME_free(comp_date);
|
||||
+ return FAILURE;
|
||||
+ }
|
||||
+ ASN1_GENERALIZEDTIME_free(comp_date);
|
||||
+ }
|
||||
+
|
||||
+ /* Add hold instruction if reason is certificateHold */
|
||||
+ if(reason_code == OCSP_REVOKED_STATUS_CERTIFICATEHOLD) {
|
||||
+ hold_instruction = OBJ_nid2obj(hold);
|
||||
+
|
||||
+ if (!X509_REVOKED_add1_ext_i2d(revoke, NID_hold_instruction_code, hold_instruction, 0, 0)) {
|
||||
+ ASN1_OBJECT_free(hold_instruction);
|
||||
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to set hold instruction");
|
||||
+ return FAILURE;
|
||||
+ }
|
||||
+
|
||||
+
|
||||
+ ASN1_OBJECT_free(hold_instruction);
|
||||
+ }
|
||||
+
|
||||
+ X509_CRL_add0_revoked(res->crl,revoke);
|
||||
+
|
||||
+ return SUCCESS;
|
||||
+}
|
||||
+/* }}} */
|
||||
+
|
||||
+/* {{{ proto bool openssl_crl_revoke_cert_by_serial(resource crl, string revoke_serial, int revokation_date[, int reason[, int compromise_date[, int hold_instruction]]])
|
||||
+ Adds a certificate to the revokation list using its serial */
|
||||
+PHP_FUNCTION(openssl_crl_revoke_cert_by_serial)
|
||||
+{
|
||||
+
|
||||
+ time_t rev_timestamp;
|
||||
+ time_t comp_timestamp;
|
||||
+
|
||||
+ zval *crl_res;
|
||||
+ struct php_x509_crl *res = NULL;
|
||||
+
|
||||
+ long reason_code = OCSP_REVOKED_STATUS_UNSPECIFIED;
|
||||
+ zval *serial_num;
|
||||
+
|
||||
+ long hold = NID_hold_instruction_reject;
|
||||
+
|
||||
+ ASN1_INTEGER *serial;
|
||||
+
|
||||
+ if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rzl|lll",
|
||||
+ &crl_res, &serial_num, &rev_timestamp, &reason_code, &comp_timestamp, &hold) == FAILURE) {
|
||||
+ RETURN_FALSE;
|
||||
+ }
|
||||
+
|
||||
+ if ((res = (struct php_x509_crl*) zend_fetch_resource(Z_RES_P(crl_res), "OpenSSL X.509 CRL", le_crl)) == NULL) {
|
||||
+ RETURN_FALSE;
|
||||
+ }
|
||||
+
|
||||
+ convert_to_string(serial_num);
|
||||
+
|
||||
+ serial = ASN1_INTEGER_new();
|
||||
+ serial = s2i_ASN1_INTEGER(NULL, Z_STRVAL_P(serial_num));
|
||||
+
|
||||
+ if(php_crl_revoke_serial(res, serial, rev_timestamp, reason_code, comp_timestamp, hold TSRMLS_CC) != SUCCESS) {
|
||||
+ ASN1_INTEGER_free(serial);
|
||||
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to revoke certificate");
|
||||
+ RETURN_FALSE;
|
||||
+ }
|
||||
+ ASN1_INTEGER_free(serial);
|
||||
+
|
||||
+ RETURN_TRUE;
|
||||
+}
|
||||
+
|
||||
+/* {{{ proto bool openssl_revoke_cert(resource crl, mixed certficate, int revokation_date[, int reason[, int compromise_date[, int hold_instruction]]])
|
||||
+ Adds a certificate to the revokation list using a certificate resource */
|
||||
+PHP_FUNCTION(openssl_crl_revoke_cert)
|
||||
+{
|
||||
+ time_t rev_timestamp;
|
||||
+ time_t comp_timestamp;
|
||||
+
|
||||
+ zval *crl_res;
|
||||
+ struct php_x509_crl *res = NULL;
|
||||
+
|
||||
+ long reason_code = OCSP_REVOKED_STATUS_UNSPECIFIED;
|
||||
+
|
||||
+ X509 *cert;
|
||||
+ zval *zcert;
|
||||
+ zend_resource *certresource;
|
||||
+
|
||||
+ long hold = NID_hold_instruction_reject;
|
||||
+
|
||||
+ ASN1_INTEGER *serial;
|
||||
+
|
||||
+ if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rzl|lll",
|
||||
+ &crl_res, &zcert, &rev_timestamp, &reason_code, &comp_timestamp, &hold) == FAILURE) {
|
||||
+ RETURN_FALSE;
|
||||
+ }
|
||||
+
|
||||
+ if ((res = (struct php_x509_crl *)zend_fetch_resource(Z_RES_P(crl_res), "OpenSSL X.509 CRL", le_crl)) == NULL) {
|
||||
+ RETURN_FALSE;
|
||||
+ }
|
||||
+
|
||||
+
|
||||
+ cert = php_openssl_x509_from_zval(zcert, 0, &certresource TSRMLS_CC);
|
||||
+ serial = X509_get_serialNumber(cert);
|
||||
+
|
||||
+ if(php_crl_revoke_serial(res, serial, rev_timestamp, reason_code, comp_timestamp, hold TSRMLS_CC) != SUCCESS) {
|
||||
+ ASN1_INTEGER_free(serial);
|
||||
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to revoke certificate");
|
||||
+ RETURN_FALSE;
|
||||
+ }
|
||||
+ ASN1_INTEGER_free(serial);
|
||||
+
|
||||
+ RETURN_TRUE;
|
||||
+}
|
||||
+
|
||||
+/* Generates the CRL */
|
||||
+static int php_crl_generate(struct php_x509_crl *res, zval* zcapkey, int crlv2, char* capass, long capass_len, long digest_alg TSRMLS_DC)
|
||||
+{
|
||||
+ zend_resource *capkeyres;
|
||||
+ EVP_PKEY *capkey;
|
||||
+ EVP_MD *digest;
|
||||
+ ASN1_TIME *tmptm;
|
||||
+
|
||||
+
|
||||
+ /* Prepare last updated and next update timestamps */
|
||||
+ tmptm = ASN1_TIME_new();
|
||||
+ if (!tmptm) {
|
||||
+ return FAILURE;
|
||||
+ }
|
||||
+ X509_gmtime_adj(tmptm,0);
|
||||
+ X509_CRL_set_lastUpdate(res->crl, tmptm);
|
||||
+ X509_gmtime_adj(tmptm,res->lifetime);
|
||||
+ X509_CRL_set_nextUpdate(res->crl, tmptm);
|
||||
+ ASN1_TIME_free(tmptm);
|
||||
+
|
||||
+ /* Initialize message digest */
|
||||
+
|
||||
+
|
||||
+ digest = php_openssl_get_evp_md_from_algo(digest_alg);
|
||||
+ if (digest == NULL)
|
||||
+ {
|
||||
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid message digest");
|
||||
+ return FAILURE;
|
||||
+ }
|
||||
+
|
||||
+ /* Sorts the CRL */
|
||||
+ X509_CRL_sort(res->crl);
|
||||
+
|
||||
+ /* Check whether to use version 2 crls */
|
||||
+ if(crlv2 || res->forcev2) {
|
||||
+ if (!X509_CRL_set_version(res->crl, 1)) {
|
||||
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to use v2 CRLs");
|
||||
+ return FAILURE;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+
|
||||
+ if(!crlv2 && res->forcev2) {
|
||||
+ php_error_docref(NULL TSRMLS_CC, E_NOTICE, "The CRL contains extensions which need a V2 CRL, creating a V2 CRL");
|
||||
+ }
|
||||
+
|
||||
+ capkey = php_openssl_evp_from_zval(zcapkey, 0, capass, 0, &capkeyres TSRMLS_CC);
|
||||
+
|
||||
+ if(!capkey) {
|
||||
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to read CA private key");
|
||||
+ return FAILURE;
|
||||
+ }
|
||||
+
|
||||
+ /* verify private key */
|
||||
+ if (!X509_check_private_key(res->cacert,capkey)) {
|
||||
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "CA Cert does not match private key");
|
||||
+ return FAILURE;
|
||||
+ }
|
||||
+
|
||||
+ /* sign CRL */
|
||||
+ if (!X509_CRL_sign(res->crl,capkey,digest)) {
|
||||
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to sign CRL");
|
||||
+ return FAILURE;
|
||||
+ }
|
||||
+
|
||||
+ return SUCCESS;
|
||||
+}
|
||||
+
|
||||
+/* {{{ proto bool openssl_crl_export(resource crl, string &data, mixed capkey[, bool crlv2[, bool notext[, string capass]]])
|
||||
+ Exports a CRL to a string */
|
||||
+PHP_FUNCTION(openssl_crl_export)
|
||||
+{
|
||||
+ BIO *out;
|
||||
+ BUF_MEM *buf;
|
||||
+
|
||||
+ zval *crl_res;
|
||||
+ struct php_x509_crl *res = NULL;
|
||||
+
|
||||
+ zval *zcapkey;
|
||||
+
|
||||
+ char *capass;
|
||||
+ long capass_len;
|
||||
+
|
||||
+ int crlv2 = 1;
|
||||
+ int notext = 1;
|
||||
+
|
||||
+ long digest_alg = OPENSSL_ALGO_SHA1;
|
||||
+
|
||||
+ zval *output;
|
||||
+
|
||||
+ if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rzz|bbsl",
|
||||
+ &crl_res, &output,
|
||||
+ &zcapkey,
|
||||
+ &crlv2, ¬ext,
|
||||
+ &capass, &capass_len,
|
||||
+ &digest_alg) == FAILURE) {
|
||||
+ RETURN_NULL();
|
||||
+ }
|
||||
+
|
||||
+ if ((res = (struct php_x509_crl *)zend_fetch_resource(Z_RES_P(crl_res), "OpenSSL X.509 CRL", le_crl)) == NULL) {
|
||||
+ RETURN_FALSE;
|
||||
+ }
|
||||
+
|
||||
+ if(php_crl_generate(res, zcapkey, crlv2, capass, capass_len, digest_alg TSRMLS_CC) != SUCCESS) {
|
||||
+ RETURN_FALSE;
|
||||
+ }
|
||||
+
|
||||
+
|
||||
+ out = BIO_new(BIO_s_mem());
|
||||
+ if (!notext) {
|
||||
+ X509_CRL_print(out, res->crl);
|
||||
+ }
|
||||
+
|
||||
+ if (!PEM_write_bio_X509_CRL(out, res->crl)) {
|
||||
+ BIO_free(out);
|
||||
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to export CRL");
|
||||
+ RETURN_FALSE;
|
||||
+ }
|
||||
+
|
||||
+ zval_dtor(output);
|
||||
+ BIO_get_mem_ptr(out, &buf);
|
||||
+ ZVAL_STRINGL(output, buf->data, buf->length);
|
||||
+
|
||||
+ BIO_free(out);
|
||||
+
|
||||
+ RETURN_TRUE;
|
||||
+
|
||||
+}
|
||||
+/* }}} */
|
||||
+
|
||||
+/* {{{ proto bool openssl_crl_export_file(resource crl, string filename, mixed capkey[, bool crlv2[, bool notext[, string capass]]])
|
||||
+ Exports a CRL to a file */
|
||||
+PHP_FUNCTION(openssl_crl_export_file)
|
||||
+{
|
||||
+ BIO *out;
|
||||
+
|
||||
+ zval *crl_res;
|
||||
+ struct php_x509_crl *res = NULL;
|
||||
+
|
||||
+ char *export_filename;
|
||||
+ long export_filename_len;
|
||||
+
|
||||
+ zval *zcapkey;
|
||||
+
|
||||
+ char *capass;
|
||||
+ long capass_len;
|
||||
+
|
||||
+ int crlv2 = 0;
|
||||
+ int notext = 1;
|
||||
+
|
||||
+ long digest_alg = OPENSSL_ALGO_SHA1;
|
||||
+
|
||||
+ if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rsz|bbsl",
|
||||
+ &crl_res,
|
||||
+ &export_filename, &export_filename_len,
|
||||
+ &zcapkey,
|
||||
+ &crlv2, ¬ext,
|
||||
+ &capass, &capass_len,
|
||||
+ &digest_alg) == FAILURE) {
|
||||
+ RETURN_NULL();
|
||||
+ }
|
||||
+
|
||||
+ if ((res = (struct php_x509_crl *)zend_fetch_resource(Z_RES_P(crl_res), "OpenSSL X.509 CRL", le_crl)) == NULL) {
|
||||
+ RETURN_FALSE;
|
||||
+ }
|
||||
+
|
||||
+ if(php_crl_generate(res, zcapkey, crlv2, capass, capass_len, digest_alg TSRMLS_CC) != SUCCESS) {
|
||||
+ RETURN_FALSE;
|
||||
+ }
|
||||
+
|
||||
+
|
||||
+ /* write CRL */
|
||||
+ if(php_openssl_open_base_dir_chk(export_filename TSRMLS_CC) != 0) {
|
||||
+ RETURN_FALSE;
|
||||
+ }
|
||||
+
|
||||
+ out = BIO_new(BIO_s_file());
|
||||
+
|
||||
+ if(BIO_write_filename(out, export_filename) <= 0) {
|
||||
+ BIO_free(out);
|
||||
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to write CRL");
|
||||
+ RETURN_FALSE;
|
||||
+ }
|
||||
+ if (!notext) {
|
||||
+ X509_CRL_print(out, res->crl);
|
||||
+ }
|
||||
+
|
||||
+ PEM_write_bio_X509_CRL(out,res->crl);
|
||||
+ BIO_free(out);
|
||||
+
|
||||
+ RETURN_TRUE;
|
||||
+}
|
||||
+/* }}} */
|
||||
+
|
||||
/*
|
||||
* Local variables:
|
||||
* tab-width: 8
|
||||
23
security/php70-openssl/files/patch-php__openssl.h
Normal file
23
security/php70-openssl/files/patch-php__openssl.h
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
--- php_openssl.h.orig 2016-01-06 10:05:22 UTC
|
||||
+++ php_openssl.h
|
||||
@@ -86,6 +86,7 @@ PHP_FUNCTION(openssl_x509_export);
|
||||
PHP_FUNCTION(openssl_x509_fingerprint);
|
||||
PHP_FUNCTION(openssl_x509_export_to_file);
|
||||
PHP_FUNCTION(openssl_x509_check_private_key);
|
||||
+PHP_FUNCTION(openssl_x509_check);
|
||||
|
||||
PHP_FUNCTION(openssl_pkcs12_export);
|
||||
PHP_FUNCTION(openssl_pkcs12_export_to_file);
|
||||
@@ -98,6 +99,12 @@ PHP_FUNCTION(openssl_csr_sign);
|
||||
PHP_FUNCTION(openssl_csr_get_subject);
|
||||
PHP_FUNCTION(openssl_csr_get_public_key);
|
||||
|
||||
+PHP_FUNCTION(openssl_crl_new);
|
||||
+PHP_FUNCTION(openssl_crl_revoke_cert);
|
||||
+PHP_FUNCTION(openssl_crl_revoke_cert_by_serial);
|
||||
+PHP_FUNCTION(openssl_crl_export);
|
||||
+PHP_FUNCTION(openssl_crl_export_file);
|
||||
+
|
||||
PHP_FUNCTION(openssl_spki_new);
|
||||
PHP_FUNCTION(openssl_spki_verify);
|
||||
PHP_FUNCTION(openssl_spki_export);
|
||||
Loading…
Add table
Reference in a new issue