📄 openssl.c
字号:
/* set the string mask */ str = CONF_get_string(req->req_config, req->section_name, "string_mask"); if (str && !ASN1_STRING_set_default_mask_asc(str)) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid global string mask setting %s", str); return FAILURE; } if (req->request_extensions_section == NULL) req->request_extensions_section = CONF_get_string(req->req_config, req->section_name, "req_extensions"); PHP_SSL_CONFIG_SYNTAX_CHECK(request_extensions_section); return SUCCESS;}static void php_openssl_dispose_config(struct php_x509_request * req TSRMLS_DC){ if (req->priv_key) { EVP_PKEY_free(req->priv_key); req->priv_key = NULL; } if (req->global_config) { CONF_free(req->global_config); req->global_config = NULL; } if (req->req_config) { CONF_free(req->req_config); req->req_config = NULL; }}static int php_openssl_load_rand_file(const char * file, int *egdsocket, int *seeded){ char buffer[MAXPATHLEN]; TSRMLS_FETCH(); *egdsocket = 0; *seeded = 0; #ifdef WINDOWS RAND_screen();#endif if (file == NULL) file = RAND_file_name(buffer, sizeof(buffer)); else if (RAND_egd(file) > 0) { /* if the given filename is an EGD socket, don't * write anything back to it */ *egdsocket = 1; return SUCCESS; } if (file == NULL || !RAND_load_file(file, -1)) { if (RAND_status() == 0) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to load random state; not enough random data!"); return FAILURE; } return FAILURE; } *seeded = 1; return SUCCESS;}static int php_openssl_write_rand_file(const char * file, int egdsocket, int seeded TSRMLS_DC){ char buffer[MAXPATHLEN]; if (egdsocket || !seeded) { /* if we did not manage to read the seed file, we should not write * a low-entropy seed file back */ return FAILURE; } if (file == NULL) file = RAND_file_name(buffer, sizeof(buffer)); if (file == NULL || !RAND_write_file(file)) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to write random state"); return FAILURE; } return SUCCESS;}/* }}} *//* {{{ PHP_MINIT_FUNCTION */PHP_MINIT_FUNCTION(openssl){ char * config_filename; 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); OpenSSL_add_all_ciphers(); OpenSSL_add_all_digests(); OpenSSL_add_all_algorithms(); ERR_load_ERR_strings(); ERR_load_SSL_strings(); ERR_load_crypto_strings(); ERR_load_EVP_strings(); /* register a resource id number with openSSL so that we can map SSL -> stream structures in * openSSL callbacks */ ssl_stream_data_index = SSL_get_ex_new_index(0, "PHP stream index", NULL, NULL, NULL); /* purposes for cert purpose checking */ REGISTER_LONG_CONSTANT("X509_PURPOSE_SSL_CLIENT", X509_PURPOSE_SSL_CLIENT, CONST_CS|CONST_PERSISTENT); REGISTER_LONG_CONSTANT("X509_PURPOSE_SSL_SERVER", X509_PURPOSE_SSL_SERVER, CONST_CS|CONST_PERSISTENT); REGISTER_LONG_CONSTANT("X509_PURPOSE_NS_SSL_SERVER", X509_PURPOSE_NS_SSL_SERVER, CONST_CS|CONST_PERSISTENT); REGISTER_LONG_CONSTANT("X509_PURPOSE_SMIME_SIGN", X509_PURPOSE_SMIME_SIGN, CONST_CS|CONST_PERSISTENT); REGISTER_LONG_CONSTANT("X509_PURPOSE_SMIME_ENCRYPT", X509_PURPOSE_SMIME_ENCRYPT, CONST_CS|CONST_PERSISTENT); REGISTER_LONG_CONSTANT("X509_PURPOSE_CRL_SIGN", X509_PURPOSE_CRL_SIGN, CONST_CS|CONST_PERSISTENT);#ifdef X509_PURPOSE_ANY REGISTER_LONG_CONSTANT("X509_PURPOSE_ANY", X509_PURPOSE_ANY, CONST_CS|CONST_PERSISTENT);#endif /* flags for S/MIME */ REGISTER_LONG_CONSTANT("PKCS7_DETACHED", PKCS7_DETACHED, CONST_CS|CONST_PERSISTENT); REGISTER_LONG_CONSTANT("PKCS7_TEXT", PKCS7_TEXT, CONST_CS|CONST_PERSISTENT); REGISTER_LONG_CONSTANT("PKCS7_NOINTERN", PKCS7_NOINTERN, CONST_CS|CONST_PERSISTENT); REGISTER_LONG_CONSTANT("PKCS7_NOVERIFY", PKCS7_NOVERIFY, CONST_CS|CONST_PERSISTENT); REGISTER_LONG_CONSTANT("PKCS7_NOCHAIN", PKCS7_NOCHAIN, CONST_CS|CONST_PERSISTENT); REGISTER_LONG_CONSTANT("PKCS7_NOCERTS", PKCS7_NOCERTS, CONST_CS|CONST_PERSISTENT); REGISTER_LONG_CONSTANT("PKCS7_NOATTR", PKCS7_NOATTR, CONST_CS|CONST_PERSISTENT); REGISTER_LONG_CONSTANT("PKCS7_BINARY", PKCS7_BINARY, CONST_CS|CONST_PERSISTENT); REGISTER_LONG_CONSTANT("PKCS7_NOSIGS", PKCS7_NOSIGS, CONST_CS|CONST_PERSISTENT); REGISTER_LONG_CONSTANT("OPENSSL_PKCS1_PADDING", RSA_PKCS1_PADDING, CONST_CS|CONST_PERSISTENT); REGISTER_LONG_CONSTANT("OPENSSL_SSLV23_PADDING", RSA_SSLV23_PADDING, CONST_CS|CONST_PERSISTENT); REGISTER_LONG_CONSTANT("OPENSSL_NO_PADDING", RSA_NO_PADDING, CONST_CS|CONST_PERSISTENT); REGISTER_LONG_CONSTANT("OPENSSL_PKCS1_OAEP_PADDING", RSA_PKCS1_OAEP_PADDING, CONST_CS|CONST_PERSISTENT); /* Values for key types */ REGISTER_LONG_CONSTANT("OPENSSL_KEYTYPE_RSA", OPENSSL_KEYTYPE_RSA, CONST_CS | CONST_PERSISTENT);#ifndef NO_DSA REGISTER_LONG_CONSTANT("OPENSSL_KEYTYPE_DSA", OPENSSL_KEYTYPE_DSA, CONST_CS | CONST_PERSISTENT);#endif REGISTER_LONG_CONSTANT("OPENSSL_KEYTYPE_DH", OPENSSL_KEYTYPE_DH, CONST_CS | CONST_PERSISTENT); /* Determine default SSL configuration file */ config_filename = getenv("OPENSSL_CONF"); if (config_filename == NULL) config_filename = getenv("SSLEAY_CONF"); /* default to 'openssl.cnf' if no environment variable is set */ if (config_filename == NULL) { snprintf(default_ssl_conf_filename, sizeof(default_ssl_conf_filename), "%s/%s", X509_get_default_cert_area(), "openssl.cnf"); } else strncpy(default_ssl_conf_filename, config_filename, sizeof(default_ssl_conf_filename)); return SUCCESS;}/* }}} *//* {{{ PHP_MINFO_FUNCTION */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();}/* }}} *//* {{{ PHP_MSHUTDOWN_FUNCTION */PHP_MSHUTDOWN_FUNCTION(openssl){ EVP_cleanup(); return SUCCESS;}/* }}} *//* {{{ x509 cert functions *//* {{{ php_openssl_x509_from_zval Given a zval, coerce it into an X509 object. The zval can be: . X509 resource created using openssl_read_x509() . if it starts with file:// then it will be interpreted as the path to that cert . it will be interpreted as the cert data If you supply makeresource, the result will be registered as an x509 resource and it's value returned in makeresource.*/static X509 * php_openssl_x509_from_zval(zval ** val, int makeresource, long * resourceval TSRMLS_DC){ X509 *cert = NULL; if (resourceval) *resourceval = -1; if (Z_TYPE_PP(val) == IS_RESOURCE) { /* is it an x509 resource ? */ void * what; int type; what = zend_fetch_resource(val TSRMLS_CC, -1, "OpenSSL X.509", &type, 1, le_x509); if (!what) return NULL; /* this is so callers can decide if they should free the X509 */ if (resourceval) *resourceval = Z_LVAL_PP(val); if (type == le_x509) return (X509*)what; /* other types could be used here - eg: file pointers and read in the data from them */ return NULL; } /* force it to be a string and check if it refers to a file */ convert_to_string_ex(val); if (Z_STRLEN_PP(val) > 7 && memcmp(Z_STRVAL_PP(val), "file://", 7) == 0) { /* read cert from the named file */ BIO *in; if (php_openssl_safe_mode_chk(Z_STRVAL_PP(val) + 7 TSRMLS_CC)) { return NULL; } in = BIO_new_file(Z_STRVAL_PP(val) + 7, "r"); if (in == NULL) return NULL; cert = PEM_read_bio_X509(in, NULL, NULL, NULL); BIO_free(in); } else { BIO *in; in = BIO_new_mem_buf(Z_STRVAL_PP(val), Z_STRLEN_PP(val)); if (in == NULL) return NULL; cert = (X509 *) PEM_ASN1_read_bio((char *(*)())d2i_X509, PEM_STRING_X509, in, NULL, NULL, NULL); BIO_free(in); } if (cert && makeresource && resourceval) { *resourceval = zend_list_insert(cert, le_x509); } return cert;}/* }}} *//* {{{ proto bool openssl_x509_export_to_file(mixed x509, string outfilename [, bool notext = true]) Exports a CERT to file or a var */PHP_FUNCTION(openssl_x509_export_to_file){ X509 * cert; zval * zcert = NULL; zend_bool notext = 1; BIO * bio_out; long certresource; char * filename; int filename_len; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs|b", &zcert, &filename, &filename_len, ¬ext) == FAILURE) return; RETVAL_FALSE; cert = php_openssl_x509_from_zval(&zcert, 0, &certresource TSRMLS_CC); if (cert == NULL) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "cannot get cert from parameter 1"); return; } if (php_openssl_safe_mode_chk(filename TSRMLS_CC)) { return; } bio_out = BIO_new_file(filename, "w"); if (bio_out) { if (!notext) X509_print(bio_out, cert); PEM_write_bio_X509(bio_out, cert); RETVAL_TRUE; } else php_error_docref(NULL TSRMLS_CC, E_WARNING, "error opening file %s", filename); if (certresource == -1 && cert) X509_free(cert); BIO_free(bio_out);}/* }}} *//* {{{ proto bool openssl_x509_export(mixed x509, string &out [, bool notext = true]) Exports a CERT to file or a var */PHP_FUNCTION(openssl_x509_export){ X509 * cert; zval * zcert = NULL, *zout=NULL; zend_bool notext = 1; BIO * bio_out; long certresource; char * bio_mem_ptr; long bio_mem_len; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rz|b", &zcert, &zout, ¬ext) == FAILURE) return; RETVAL_FALSE; cert = php_openssl_x509_from_zval(&zcert, 0, &certresource TSRMLS_CC); if (cert == NULL) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "cannot get cert from parameter 1"); return; } bio_out = BIO_new(BIO_s_mem()); if (!notext) X509_print(bio_out, cert); PEM_write_bio_X509(bio_out, cert); bio_mem_len = BIO_get_mem_data(bio_out, &bio_mem_ptr); ZVAL_STRINGL(zout, bio_mem_ptr, bio_mem_len, 1); RETVAL_TRUE; if (certresource == -1 && cert) X509_free(cert); BIO_free(bio_out);}/* }}} *//* {{{ proto bool openssl_x509_check_private_key(mixed cert, mixed key) Checks if a private key corresponds to a CERT */PHP_FUNCTION(openssl_x509_check_private_key){ zval * zcert, *zkey; X509 * cert = NULL; EVP_PKEY * key = NULL; long certresource = -1, keyresource = -1; RETVAL_FALSE; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz", &zcert, &zkey) == FAILURE) return; cert = php_openssl_x509_from_zval(&zcert, 0, &certresource TSRMLS_CC); if (cert == NULL) RETURN_FALSE; key = php_openssl_evp_from_zval(&zkey, 0, "", 1, &keyresource TSRMLS_CC); if (key) { RETVAL_BOOL(X509_check_private_key(cert, key)); } if (keyresource == -1 && key) EVP_PKEY_free(key); if (certresource == -1 && cert) X509_free(cert);}/* }}} *//* {{{ proto array openssl_x509_parse(mixed x509 [, bool shortnames=true]) Returns an array of the fields/values of the CERT */PHP_FUNCTION(openssl_x509_parse){ zval * zcert; X509 * cert = NULL; long certresource = -1; int i; zend_bool useshortnames = 1; char * tmpstr; zval * subitem; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|b", &zcert, &useshortnames) == FAILURE) return; cert = php_openssl_x509_from_zval(&zcert, 0, &certresource TSRMLS_CC); if (cert == NULL) RETURN_FALSE; array_init(return_value); if (cert->name) add_assoc_string(return_value, "name", cert->name, 1);/* add_assoc_bool(return_value, "valid", cert->valid); */ add_assoc_name_entry(return_value, "subject", X509_get_subject_name(cert), useshortnames TSRMLS_CC); /* hash as used in CA directories to lookup cert by subject name */ { char buf[32]; snprintf(buf, sizeof(buf), "%08lx", X509_subject_name_hash(cert)); add_assoc_string(return_value, "hash", buf, 1); } add_assoc_name_entry(return_value, "issuer", X509_get_issuer_name(cert), useshortnames TSRMLS_CC); add_assoc_long(return_value, "version", X509_get_version(cert)); add_assoc_long(return_value, "serialNumber", ASN1_INTEGER_get(X509_get_serialNumber(cert))); add_assoc_asn1_string(return_value, "validFrom", X509_get_notBefore(cert)); add_assoc_asn1_string(return_value, "validTo", X509_get_notAfter(cert)); add_assoc_long(return_value, "validFrom_time_t", asn1_time_to_time_t(X509_get_notBefore(cert) TSRMLS_CC)); add_assoc_long(return_value, "validTo_time_t", asn1_time_to_time_t(X509_get_notAfter(cert) TSRMLS_CC)); tmpstr = X509_alias_get0(cert, NULL); if (tmpstr) add_assoc_string(return_value, "alias", tmpstr, 1);/* add_assoc_long(return_value, "signaturetypeLONG", X509_get_signature_type(cert)); add_assoc_string(return_value, "signaturetype", OBJ_nid2sn(X509_get_signature_type(cert)), 1); add_assoc_string(return_value, "signaturetypeLN", OBJ_nid2ln(X509_get_signature_type(cert)), 1);*/ MAKE_STD_ZVAL(subitem); array_init(subitem); /* NOTE: the purposes are added as integer keys - the keys match up to the X509_PURPOSE_SSL_XXX defines in x509v3.h */ for (i = 0; i < X509_PURPOSE_get_count(); i++) { int id, purpset; char * pname; X509_PURPOSE * purp; zval * subsub; MAKE_STD_ZVAL(subsub); array_init(subsub); purp = X509_PURPOSE_get0(i); id = X509_PURPOSE_get_id(purp); purpset = X509_check_purpose(cert, id, 0); add_index_bool(subsub, 0, purpset); purpset = X509_check_purpose(cert, id, 1); add_index_bool(subsub, 1, purpset); pname = useshortnames ? X509_PURPOSE_get0_sname(purp) : X509_PURPOSE_get0_name(purp); add_index_string(subsub, 2, pname, 1); /* NOTE: if purpset > 1 then it's a warning - we should mention it ? */ add_index_zval(subitem, id, subsub); } add_assoc_zval(return_value, "purposes", subitem); if (certresource == -1 && cert) X509_free(cert);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -