mirror of
https://github.com/php/php-src.git
synced 2024-11-30 21:35:36 +08:00
Patch for #20936 (openssl: public key handling was broken).
Thanks to <jeroen@derks.it> for the patch.
This commit is contained in:
parent
75c180f242
commit
1ef74a4f79
@ -60,8 +60,8 @@ encrypted a passphrase is needed. This can be supplied as second argument.
|
||||
|
||||
resource openssl_get_publickey(mixed cert)
|
||||
|
||||
Extracts the public key from the given certificate and returns a key
|
||||
resource identifier.
|
||||
Extracts the public key from the given certificate or public key and returns
|
||||
a key resource identifier.
|
||||
|
||||
|
||||
void openssl_free_key(resource key)
|
||||
|
@ -197,6 +197,7 @@ struct php_x509_request {
|
||||
|
||||
static X509 * php_openssl_x509_from_zval(zval ** val, int makeresource, long * resourceval TSRMLS_DC);
|
||||
static EVP_PKEY * php_openssl_evp_from_zval(zval ** val, int public_key, char * passphrase, int makeresource, long * resourceval TSRMLS_DC);
|
||||
static int php_openssl_is_private_key(EVP_PKEY* pkey TSRMLS_DC);
|
||||
static X509_STORE * setup_verify(zval * calist TSRMLS_DC);
|
||||
static STACK_OF(X509) * load_all_certs_from_file(char *certfile);
|
||||
static X509_REQ * php_openssl_csr_from_zval(zval ** val, int makeresource, long * resourceval TSRMLS_DC);
|
||||
@ -1631,6 +1632,7 @@ PHP_FUNCTION(openssl_csr_new)
|
||||
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!
|
||||
@ -1682,6 +1684,13 @@ static EVP_PKEY * php_openssl_evp_from_zval(zval ** val, int public_key, char *
|
||||
free_cert = 0;
|
||||
}
|
||||
else if (type == le_key) {
|
||||
/* check whether it is actually a private key if requested */
|
||||
if (!public_key && !php_openssl_is_private_key((EVP_PKEY*)what))
|
||||
{
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "supplied key param is a public key");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* got the key - return it */
|
||||
return (EVP_PKEY*)what;
|
||||
}
|
||||
@ -1702,6 +1711,20 @@ static EVP_PKEY * php_openssl_evp_from_zval(zval ** val, int public_key, char *
|
||||
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 */
|
||||
@ -1783,6 +1806,50 @@ static EVP_PKEY * php_openssl_generate_private_key(struct php_x509_request * req
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ 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);
|
||||
|
||||
if (NULL == pkey->pkey.dh->p || NULL == pkey->pkey.dh->priv_key)
|
||||
return 0;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "key type not supported in this PHP build!");
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto resource openssl_pkey_new([array configargs])
|
||||
Generates a new private key */
|
||||
PHP_FUNCTION(openssl_pkey_new)
|
||||
|
Loading…
Reference in New Issue
Block a user