Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow optional newline in OpenSSL output #9289

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
105 changes: 70 additions & 35 deletions hphp/runtime/ext/openssl/ext_openssl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@
#include <openssl/conf.h>
#include <openssl/pem.h>
#include <openssl/pkcs12.h>
#if defined(OPENSSL_VERSION_MAJOR) && (OPENSSL_VERSION_MAJOR >= 3)
#include <openssl/provider.h>
#endif
#include <openssl/rand.h>
#include <vector>

Expand Down Expand Up @@ -66,6 +69,12 @@ struct OpenSSLInitializer {
ERR_load_crypto_strings();
ERR_load_EVP_strings();

// RC4 is only available in legacy providers
#if defined(OPENSSL_VERSION_MAJOR) && (OPENSSL_VERSION_MAJOR >= 3)
OSSL_PROVIDER_load(nullptr, "default");
OSSL_PROVIDER_load(nullptr, "legacy");
#endif

/* Determine default SSL configuration file */
char *config_filename = getenv("OPENSSL_CONF");
if (config_filename == nullptr) {
Expand Down Expand Up @@ -998,25 +1007,27 @@ bool HHVM_FUNCTION(openssl_csr_export, const Variant& csr, Variant& out,
return false;
}

static EVP_PKEY *duplicate_public_key(EVP_PKEY *priv_key) {
/* Extract public key portion by round-tripping through PEM. */
BIO *bio = BIO_new(BIO_s_mem());
SCOPE_EXIT { BIO_free(bio); };
if (!bio || !PEM_write_bio_PUBKEY(bio, priv_key)) {
return nullptr;
}

EVP_PKEY *pub_key = PEM_read_bio_PUBKEY(bio, nullptr, nullptr, nullptr);
return pub_key;
}

Variant HHVM_FUNCTION(openssl_csr_get_public_key, const Variant& csr) {
auto pcsr = CSRequest::Get(csr);
if (!pcsr) return false;

auto input_csr = pcsr->csr();

#if OPENSSL_VERSION_NUMBER >= 0x10100000
/* Due to changes in OpenSSL 1.1 related to locking when decoding CSR,
* the pub key is not changed after assigning. It means if we pass
* a private key, it will be returned including the private part.
* If we duplicate it, then we get just the public part which is
* the same behavior as for OpenSSL 1.0 */
input_csr = X509_REQ_dup(input_csr);
/* We need to free the CSR as it was duplicated */
SCOPE_EXIT { X509_REQ_free(input_csr); };
#endif
auto pubkey = X509_REQ_get_pubkey(input_csr);
auto pubkey = X509_REQ_get0_pubkey(input_csr);
if (!pubkey) return false;
return Variant(req::make<Key>(pubkey));
return Variant(req::make<Key>(duplicate_public_key(pubkey)));
}

Variant HHVM_FUNCTION(openssl_csr_get_subject, const Variant& csr,
Expand Down Expand Up @@ -1907,7 +1918,7 @@ Array HHVM_FUNCTION(openssl_pkey_get_details, const Resource& key) {
case EVP_PKEY_RSA2:
{
ktype = OPENSSL_KEYTYPE_RSA;
RSA *rsa = EVP_PKEY_get0_RSA(pkey);
auto rsa = EVP_PKEY_get0_RSA(pkey);
assertx(rsa);
const BIGNUM *n, *e, *d, *p, *q, *dmp1, *dmq1, *iqmp;
RSA_get0_key(rsa, &n, &e, &d);
Expand All @@ -1930,7 +1941,7 @@ Array HHVM_FUNCTION(openssl_pkey_get_details, const Resource& key) {
case EVP_PKEY_DSA4:
{
ktype = OPENSSL_KEYTYPE_DSA;
DSA *dsa = EVP_PKEY_get0_DSA(pkey);
auto dsa = EVP_PKEY_get0_DSA(pkey);
assertx(dsa);
const BIGNUM *p, *q, *g, *pub_key, *priv_key;
DSA_get0_pqg(dsa, &p, &q, &g);
Expand All @@ -1946,7 +1957,7 @@ Array HHVM_FUNCTION(openssl_pkey_get_details, const Resource& key) {
case EVP_PKEY_DH:
{
ktype = OPENSSL_KEYTYPE_DH;
DH *dh = EVP_PKEY_get0_DH(pkey);
auto dh = EVP_PKEY_get0_DH(pkey);
assertx(dh);
const BIGNUM *p, *q, *g, *pub_key, *priv_key;
DH_get0_pqg(dh, &p, &q, &g);
Expand Down Expand Up @@ -2060,11 +2071,17 @@ bool HHVM_FUNCTION(openssl_private_decrypt, const String& data,
switch (EVP_PKEY_id(pkey)) {
case EVP_PKEY_RSA:
case EVP_PKEY_RSA2:
cryptedlen = RSA_private_decrypt(data.size(),
(unsigned char *)data.data(),
cryptedbuf,
EVP_PKEY_get0_RSA(pkey),
padding);
{
auto rsa = EVP_PKEY_get1_RSA(pkey);
SCOPE_EXIT {
RSA_free(rsa);
};
cryptedlen = RSA_private_decrypt(data.size(),
(unsigned char *)data.data(),
cryptedbuf,
rsa,
padding);
}
if (cryptedlen != -1) {
successful = 1;
}
Expand Down Expand Up @@ -2100,11 +2117,17 @@ bool HHVM_FUNCTION(openssl_private_encrypt, const String& data,
switch (EVP_PKEY_id(pkey)) {
case EVP_PKEY_RSA:
case EVP_PKEY_RSA2:
successful = (RSA_private_encrypt(data.size(),
(unsigned char *)data.data(),
cryptedbuf,
EVP_PKEY_get0_RSA(pkey),
padding) == cryptedlen);
{
auto rsa = EVP_PKEY_get1_RSA(pkey);
SCOPE_EXIT {
RSA_free(rsa);
};
successful = (RSA_private_encrypt(data.size(),
(unsigned char *)data.data(),
cryptedbuf,
rsa,
padding) == cryptedlen);
}
break;
default:
raise_warning("key type not supported");
Expand Down Expand Up @@ -2136,11 +2159,17 @@ bool HHVM_FUNCTION(openssl_public_decrypt, const String& data,
switch (EVP_PKEY_id(pkey)) {
case EVP_PKEY_RSA:
case EVP_PKEY_RSA2:
cryptedlen = RSA_public_decrypt(data.size(),
(unsigned char *)data.data(),
cryptedbuf,
EVP_PKEY_get0_RSA(pkey),
padding);
{
auto rsa = EVP_PKEY_get1_RSA(pkey);
SCOPE_EXIT {
RSA_free(rsa);
};
cryptedlen = RSA_public_decrypt(data.size(),
(unsigned char *)data.data(),
cryptedbuf,
rsa,
padding);
}
if (cryptedlen != -1) {
successful = 1;
}
Expand Down Expand Up @@ -2176,11 +2205,17 @@ bool HHVM_FUNCTION(openssl_public_encrypt, const String& data,
switch (EVP_PKEY_id(pkey)) {
case EVP_PKEY_RSA:
case EVP_PKEY_RSA2:
successful = (RSA_public_encrypt(data.size(),
(unsigned char *)data.data(),
cryptedbuf,
EVP_PKEY_get0_RSA(pkey),
padding) == cryptedlen);
{
auto rsa = EVP_PKEY_get1_RSA(pkey);
SCOPE_EXIT {
RSA_free(rsa);
};
successful = (RSA_public_encrypt(data.size(),
(unsigned char *)data.data(),
cryptedbuf,
rsa,
padding) == cryptedlen);
}
break;
default:
raise_warning("key type not supported");
Expand Down
10 changes: 4 additions & 6 deletions hphp/test/slow/ext_openssl/openssl_x509_parse_basic.php.expectf
Original file line number Diff line number Diff line change
Expand Up @@ -105,10 +105,9 @@ dict(13) {
["subjectKeyIdentifier"]=>
string(59) "DB:7E:40:72:BD:5C:35:85:EC:29:29:81:12:E8:62:68:6A:B7:3F:7D"
["authorityKeyIdentifier"]=>
string(202) "keyid:DB:7E:40:72:BD:5C:35:85:EC:29:29:81:12:E8:62:68:6A:B7:3F:7D
string(%d) "keyid:DB:7E:40:72:BD:5C:35:85:EC:29:29:81:12:E8:62:68:6A:B7:3F:7D
DirName:/C=BR/ST=Rio Grande do Sul/L=Porto Alegre/CN=Henrique do N. Angelo/emailAddress=hnangelo@php.net
serial:AE:C5:56:CC:72:37:50:A2
"
serial:AE:C5:56:CC:72:37:50:A2%w"
["basicConstraints"]=>
string(7) "CA:TRUE"
}
Expand Down Expand Up @@ -220,10 +219,9 @@ dict(13) {
["subjectKeyIdentifier"]=>
string(59) "DB:7E:40:72:BD:5C:35:85:EC:29:29:81:12:E8:62:68:6A:B7:3F:7D"
["authorityKeyIdentifier"]=>
string(202) "keyid:DB:7E:40:72:BD:5C:35:85:EC:29:29:81:12:E8:62:68:6A:B7:3F:7D
string(%d) "keyid:DB:7E:40:72:BD:5C:35:85:EC:29:29:81:12:E8:62:68:6A:B7:3F:7D
DirName:/C=BR/ST=Rio Grande do Sul/L=Porto Alegre/CN=Henrique do N. Angelo/emailAddress=hnangelo@php.net
serial:AE:C5:56:CC:72:37:50:A2
"
serial:AE:C5:56:CC:72:37:50:A2%w"
["basicConstraints"]=>
string(7) "CA:TRUE"
}
Expand Down
8 changes: 3 additions & 5 deletions hphp/test/zend/good/ext/openssl/tests/bug28382.php.expectf
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,16 @@ dict(11) {
["nsCertType"]=>
string(30) "SSL Client, SSL Server, S/MIME"
["crlDistributionPoints"]=>
string(%d) "%AURI:http://mobile.blue-software.ro:90/ca/crl.shtml
"
string(%d) "%AURI:http://mobile.blue-software.ro:90/ca/crl.shtml%w"
["nsCaPolicyUrl"]=>
string(38) "http://mobile.blue-software.ro:90/pub/"
["subjectAltName"]=>
string(28) "email:sergiu@bluesoftware.ro"
["subjectKeyIdentifier"]=>
string(59) "B0:A7:FF:F9:41:15:DE:23:39:BD:DD:31:0F:97:A0:B2:A2:74:E0:FC"
["authorityKeyIdentifier"]=>
string(115) "DirName:/C=RO/ST=Romania/L=Craiova/O=Sergiu/OU=Sergiu SRL/CN=Sergiu CA/emailAddress=n_sergiu@hotmail.com
serial:00
"
string(%d) "DirName:/C=RO/ST=Romania/L=Craiova/O=Sergiu/OU=Sergiu SRL/CN=Sergiu CA/emailAddress=n_sergiu@hotmail.com
serial:00%w"
["keyUsage"]=>
string(71) "Digital Signature, Non Repudiation, Key Encipherment, Data Encipherment"
["nsBaseUrl"]=>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,5 @@ dict [
'basicConstraints' => 'CA:FALSE',
'subjectKeyIdentifier' => '88:5A:55:C0:52:FF:61:CD:52:A3:35:0F:EA:5A:9C:24:38:22:F7:5C',
'keyUsage' => 'Digital Signature, Non Repudiation, Key Encipherment',
'subjectAltName' => 'DNS:altnull.python.org' . "\0" . 'example.com, email:null@python.org' . "\0" . 'user@example.org, URI:http://null.python.org' . "\0" . 'http://example.org, IP Address:192.0.2.1, IP Address:2001:DB8:0:0:0:0:0:1
',
'subjectAltName' => 'DNS:altnull.python.org' . "\0" . 'example.com, email:null@python.org' . "\0" . 'user@example.org, URI:http://null.python.org' . "\0" . 'http://example.org, IP Address:192.0.2.1, IP Address:2001:DB8:0:0:0:0:0:1%w',
]