⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 openssl.c

📁 php-4.4.7学习linux时下载的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
/* {{{ proto bool openssl_csr_export(resource csr, string &out [, bool notext=true])   Exports a CSR to file or a var */PHP_FUNCTION(openssl_csr_export){	X509_REQ * csr;	zval * zcsr = NULL, *zout=NULL;	zend_bool notext = 1;	BIO * bio_out;	long csr_resource;	char * bio_mem_ptr;	long bio_mem_len;	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rz|b", &zcsr, &zout, &notext) == FAILURE)		return;	RETVAL_FALSE;	csr = php_openssl_csr_from_zval(&zcsr, 0, &csr_resource TSRMLS_CC);	if (csr == NULL) {		php_error_docref(NULL TSRMLS_CC, E_WARNING, "cannot get CSR from parameter 1");		return;	}	/* export to a var */	bio_out = BIO_new(BIO_s_mem());	if (!notext)		X509_REQ_print(bio_out, csr);	PEM_write_bio_X509_REQ(bio_out, csr);	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 (csr_resource == -1 && csr)		X509_REQ_free(csr);	BIO_free(bio_out);}/* }}} *//* {{{ proto resource openssl_csr_sign(mixed csr, mixed x509, mixed priv_key, long days [, array config_args [, long serial]])   Signs a cert with another CERT */PHP_FUNCTION(openssl_csr_sign){	zval * zcert = NULL, *zcsr, *zpkey, *args = NULL;	long num_days;	long serial = 0L;	X509 * cert = NULL, *new_cert = NULL;	X509_REQ * csr;	EVP_PKEY * key = NULL, *priv_key = NULL;	long csr_resource, certresource, keyresource;	int i;	struct php_x509_request req;		if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz!zl|a!l", &zcsr, &zcert, &zpkey, &num_days, &args, &serial) == FAILURE)		return;	RETVAL_FALSE;	PHP_SSL_REQ_INIT(&req);		csr = php_openssl_csr_from_zval(&zcsr, 0, &csr_resource TSRMLS_CC);	if (csr == NULL) {		php_error_docref(NULL TSRMLS_CC, E_WARNING, "cannot get CSR from parameter 1");		return;	}	if (zcert) {		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 2");			goto cleanup;		}	}	priv_key = php_openssl_evp_from_zval(&zpkey, 0, "", 1, &keyresource TSRMLS_CC);	if (priv_key == NULL) {		php_error_docref(NULL TSRMLS_CC, E_WARNING, "cannot get private key from parameter 3");		goto cleanup;	}	if (cert && !X509_check_private_key(cert, priv_key)) {		php_error_docref(NULL TSRMLS_CC, E_WARNING, "private key does not correspond to signing cert");		goto cleanup;	}		if (PHP_SSL_REQ_PARSE(&req, args) == FAILURE)		goto cleanup;	/* Check that the request matches the signature */	key = X509_REQ_get_pubkey(csr);	if (key == NULL) {		php_error_docref(NULL TSRMLS_CC, E_WARNING, "error unpacking public key");		goto cleanup;	}	i = X509_REQ_verify(csr, key);	if (i < 0) {		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Signature verification problems");		goto cleanup;	}	else if (i==0) {		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Signature did not match the certificate request");		goto cleanup;	}		/* Now we can get on with it */		new_cert = X509_new();	if (new_cert == NULL) {		php_error_docref(NULL TSRMLS_CC, E_WARNING, "No memory");		goto cleanup;	}	/* Version 3 cert */	if (!X509_set_version(new_cert, 2))		goto cleanup;	ASN1_INTEGER_set(X509_get_serialNumber(new_cert), serial);		X509_set_subject_name(new_cert, X509_REQ_get_subject_name(csr));	if (cert == NULL)		cert = new_cert;	if (!X509_set_issuer_name(new_cert, X509_get_subject_name(cert)))		goto cleanup;	X509_gmtime_adj(X509_get_notBefore(new_cert), 0);	X509_gmtime_adj(X509_get_notAfter(new_cert), (long)60*60*24*num_days);	i = X509_set_pubkey(new_cert, key);	if (!i)		goto cleanup;	if (req.request_extensions_section) {		X509V3_CTX ctx;				X509V3_set_ctx(&ctx, cert, new_cert, csr, NULL, 0);		X509V3_set_conf_lhash(&ctx, req.req_config);		if (!X509V3_EXT_add_conf(req.req_config, &ctx, req.request_extensions_section, new_cert))			goto cleanup;	}	/* Now sign it */	if (!X509_sign(new_cert, priv_key, req.digest)) {		php_error_docref(NULL TSRMLS_CC, E_WARNING, "failed to sign it");		goto cleanup;	}		/* Succeeded; lets return the cert */	RETVAL_RESOURCE(zend_list_insert(new_cert, le_x509));	new_cert = NULL;	cleanup:	if (cert == new_cert)		cert = NULL;		PHP_SSL_REQ_DISPOSE(&req);	if (keyresource == -1 && priv_key)		EVP_PKEY_free(priv_key);	if (key)		EVP_PKEY_free(key);	if (csr_resource == -1 && csr)		X509_REQ_free(csr);	if (certresource == -1 && cert)		X509_free(cert);	if (new_cert)		X509_free(new_cert);}/* }}} *//* {{{ proto bool openssl_csr_new(array dn, resource &privkey [, array configargs, array extraattribs])   Generates a privkey and CSR */PHP_FUNCTION(openssl_csr_new){	struct php_x509_request req;	zval * args = NULL, * dn, *attribs = NULL;	zval * out_pkey;	X509_REQ * csr = NULL;	int we_made_the_key = 1;	long key_resource;		if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "az|a!a!", &dn, &out_pkey, &args, &attribs) == FAILURE)		return;	RETVAL_FALSE;		PHP_SSL_REQ_INIT(&req);	if (PHP_SSL_REQ_PARSE(&req, args) == SUCCESS)	{		/* Generate or use a private key */		if (Z_TYPE_P(out_pkey) != IS_NULL) {			req.priv_key = php_openssl_evp_from_zval(&out_pkey, 0, NULL, 0, &key_resource TSRMLS_CC);			if (req.priv_key != NULL)				we_made_the_key = 0;		}		if (req.priv_key == NULL)				php_openssl_generate_private_key(&req TSRMLS_CC);		if (req.priv_key == NULL)				php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to generate a private key");		else	{			csr = X509_REQ_new();			if (csr) {				if (php_openssl_make_REQ(&req, csr, dn, attribs TSRMLS_CC) == SUCCESS) {					X509V3_CTX ext_ctx;					X509V3_set_ctx(&ext_ctx, NULL, NULL, csr, NULL, 0);					X509V3_set_conf_lhash(&ext_ctx, req.req_config);					/* Add extensions */					if (req.request_extensions_section && !X509V3_EXT_REQ_add_conf(req.req_config,								&ext_ctx, req.request_extensions_section, csr))					{						php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error loading extension section %s", req.request_extensions_section);					}					else	{						RETVAL_TRUE;												if (X509_REQ_sign(csr, req.priv_key, req.digest)) {							RETVAL_RESOURCE(zend_list_insert(csr, le_csr));							csr = NULL;									} else {							php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error signing request");						}						if (we_made_the_key) {							/* and a resource for the private key */							ZVAL_RESOURCE(out_pkey, zend_list_insert(req.priv_key, le_key));							req.priv_key = NULL; /* make sure the cleanup code doesn't zap it! */						}						else if (key_resource != -1)								req.priv_key = NULL; /* make sure the cleanup code doesn't zap it! */					}				}				else {					if (!we_made_the_key) {						/* if we have not made the key we are not supposed to zap it by calling dispose! */						req.priv_key = NULL;					}				}			}		}	}	if (csr)		X509_REQ_free(csr);	PHP_SSL_REQ_DISPOSE(&req);}/* }}} *//* }}} *//* {{{ EVP Public/Private key functions *//* {{{ php_openssl_evp_from_zval   Given a zval, coerce it into a EVP_PKEY object.	It can be:		1. private key resource from openssl_get_privatekey()		2. X509 resource -> public key will be extracted from it		3. if it starts with file:// interpreted as path to key file		4. interpreted as the data from the cert/key file and interpreted in same way as openssl_get_privatekey()		5. an array(0 => [items 2..4], 1 => passphrase)		6. if val is a string (possibly starting with file:///) and it is not an X509 certificate, then interpret as public key	NOTE: If you are requesting a private key but have not specified a passphrase, you should use an	empty string rather than NULL for the passphrase - NULL causes a passphrase prompt to be emitted in	the Apache error log!*/static EVP_PKEY * php_openssl_evp_from_zval(zval ** val, int public_key, char * passphrase, int makeresource, long * resourceval TSRMLS_DC){	EVP_PKEY * key = NULL;	X509 * cert = NULL;	int free_cert = 0;	long cert_res = -1;	char * filename = NULL;		if (resourceval)		*resourceval = -1;	if (Z_TYPE_PP(val) == IS_ARRAY) {		zval ** zphrase;				/* get passphrase */		if (zend_hash_index_find(HASH_OF(*val), 1, (void **)&zphrase) == FAILURE) {			php_error_docref(NULL TSRMLS_CC, E_WARNING, "key array must be of the form array(0 => key, 1 => phrase)");			return NULL;		}		convert_to_string_ex(zphrase);		passphrase = Z_STRVAL_PP(zphrase);		/* now set val to be the key param and continue */		if (zend_hash_index_find(HASH_OF(*val), 0, (void **)&val) == FAILURE) {			php_error_docref(NULL TSRMLS_CC, E_WARNING, "key array must be of the form array(0 => key, 1 => phrase)");			return NULL;		}	}	if (Z_TYPE_PP(val) == IS_RESOURCE) {		void * what;		int type;		what = zend_fetch_resource(val TSRMLS_CC, -1, "OpenSSL X.509/key", &type, 2, le_x509, le_key);		if (!what)			return NULL;		if (resourceval)			*resourceval = Z_LVAL_PP(val);		if (type == le_x509) {			/* extract key from cert, depending on public_key param */			cert = (X509*)what;			free_cert = 0;		}		else if (type == le_key) {			int is_priv;			is_priv = php_openssl_is_private_key((EVP_PKEY*)what TSRMLS_CC);			/* check whether it is actually a private key if requested */			if (!public_key && !is_priv) {				php_error_docref(NULL TSRMLS_CC, E_WARNING, "supplied key param is a public key");				return NULL;			}			if (public_key && is_priv) {				php_error_docref(NULL TSRMLS_CC, E_WARNING, "Don't know how to get public key from this private key (the documentation lied)");				return NULL;			} else {				/* got the key - return it */				return (EVP_PKEY*)what;			}		}		/* other types could be used here - eg: file pointers and read in the data from them */		return NULL;	}	else	{		/* 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)			filename = Z_STRVAL_PP(val) + 7;		/* it's an X509 file/cert of some kind, and we need to extract the data from that */		if (public_key) {			cert = php_openssl_x509_from_zval(val, 0, &cert_res TSRMLS_CC);			free_cert = (cert_res == -1);			/* actual extraction done later */			if (!cert) {				/* not a X509 certificate, try to retrieve public key */				BIO* in;				if (filename)					in = BIO_new_file(filename, "r");				else					in = BIO_new_mem_buf(Z_STRVAL_PP(val), Z_STRLEN_PP(val));				if (in == NULL)					return NULL;				key = PEM_read_bio_PUBKEY(in, NULL,NULL, NULL);				BIO_free(in);			}		}		else	{			/* we want the private key */			BIO *in;			if (filename) {				if (php_openssl_safe_mode_chk(filename TSRMLS_CC)) {					return NULL;				}				in = BIO_new_file(filename, "r");			} else {				in = BIO_new_mem_buf(Z_STRVAL_PP(val), Z_STRLEN_PP(val));			}			if (in == NULL) {				return NULL;			}			key = PEM_read_bio_PrivateKey(in, NULL,NULL, passphrase);			BIO_free(in);		}	}	if (public_key && cert && key == NULL) {		/* extract public key from X509 cert */		key = (EVP_PKEY *) X509_get_pubkey(cert);	}	if (free_cert && cert)		X509_free(cert);	if (key && makeresource && resourceval) {		*resourceval = ZEND_REGISTER_RESOURCE(NULL, key, le_key);	}	return key;}/* }}} *//* {{{ php_openssl_generate_private_key */static EVP_PKEY * php_openssl_generate_private_key(struct php_x509_request * req TSRMLS_DC){	char * randfile = NULL;	int egdsocket, seeded;	EVP_PKEY * return_val = NULL;		if (req->priv_key_bits < MIN_KEY_LENGTH) {		php_error_docref(NULL TSRMLS_CC, E_WARNING, "private key length is too short; it needs to be at least %d bits, not %d",				MIN_KEY_LENGTH, req->priv_key_bits);		return NULL;	}	randfile = CONF_get_string(req->req_config, req->section_name, "RANDFILE");	php_openssl_load_rand_file(randfile, &egdsocket, &seeded);		if ((req->priv_key = EVP_PKEY_new()) != NULL) {		switch(req->priv_key_type) {			case OPENSSL_KEYTYPE_RSA:				if (EVP_PKEY_assign_RSA(req->priv_key, RSA_generate_key(req->priv_key_bits, 0x10001, NULL, NULL)))					return_val = req->priv_key;				break;			default:				php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unsupported private key type");		}	}	php_openssl_write_rand_file(randfile, egdsocket, seeded TSRMLS_CC);		if (return_val == NULL) {		EVP_PKEY_free(req->priv_key);		req->priv_key = NULL;		return NULL;	}		return return_val;}/* }}} *//* {{{ php_openssl_is_private_key	Check whether the supplied key is a private key by checking if the secret prime factors are set */static int php_openssl_is_private_key(EVP_PKEY* pkey TSRMLS_DC){	assert(pkey != NULL);	switch (pkey->type) {#ifndef NO_RSA		case EVP_PKEY_RSA:		case EVP_PKEY_RSA2:			assert(pkey->pkey.rsa != NULL);			if (NULL == pkey->pkey.rsa->p || NULL == pkey->pkey.rsa->q)				return 0;			break;#endif#ifndef NO_DSA		case EVP_PKEY_DSA:		case EVP_PKEY_DSA1:		case EVP_PKEY_DSA2:		case EVP_PKEY_DSA3:		case EVP_PKEY_DSA4:			assert(pkey->pkey.dsa != NULL);			if (NULL == pkey->pkey.dsa->p || NULL == pkey->pkey.dsa->q || NULL == pkey->pkey.dsa->priv_key)				return 0;			break;#endif#ifndef NO_DH		case EVP_PKEY_DH:			assert(pkey->pkey.dh != NULL);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -