summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xext/openssl/openssl.c66
-rw-r--r--ext/openssl/tests/027.phpt52
-rw-r--r--ext/openssl/tests/028.phpt28
-rw-r--r--ext/openssl/tests/private_ec.key5
-rw-r--r--ext/openssl/tests/public_ec.key4
5 files changed, 153 insertions, 2 deletions
diff --git a/ext/openssl/openssl.c b/ext/openssl/openssl.c
index c4b155b478..147a9ec919 100755
--- a/ext/openssl/openssl.c
+++ b/ext/openssl/openssl.c
@@ -3595,6 +3595,7 @@ PHP_FUNCTION(openssl_pkey_export_to_file)
char * filename = NULL;
size_t filename_len = 0;
zend_resource *key_resource = NULL;
+ int pem_write = 0;
EVP_PKEY * key;
BIO * bio_out = NULL;
const EVP_CIPHER * cipher;
@@ -3629,7 +3630,19 @@ PHP_FUNCTION(openssl_pkey_export_to_file)
} else {
cipher = NULL;
}
- if (PEM_write_bio_PrivateKey(bio_out, key, cipher, (unsigned char *)passphrase, passphrase_len, NULL, NULL)) {
+
+ switch (EVP_PKEY_type(key->type)) {
+#ifdef HAVE_EVP_PKEY_EC
+ case EVP_PKEY_EC:
+ pem_write = PEM_write_bio_ECPrivateKey(bio_out, EVP_PKEY_get1_EC_KEY(key), cipher, (unsigned char *)passphrase, passphrase_len, NULL, NULL);
+ break;
+#endif
+ default:
+ pem_write = PEM_write_bio_PrivateKey(bio_out, key, cipher, (unsigned char *)passphrase, passphrase_len, NULL, NULL);
+ break;
+ }
+
+ if (pem_write) {
/* Success!
* If returning the output as a string, do so now */
RETVAL_TRUE;
@@ -3653,6 +3666,7 @@ PHP_FUNCTION(openssl_pkey_export)
struct php_x509_request req;
zval * zpkey, * args = NULL, *out;
char * passphrase = NULL; size_t passphrase_len = 0;
+ int pem_write = 0;
zend_resource *key_resource = NULL;
EVP_PKEY * key;
BIO * bio_out = NULL;
@@ -3684,7 +3698,19 @@ PHP_FUNCTION(openssl_pkey_export)
} else {
cipher = NULL;
}
- if (PEM_write_bio_PrivateKey(bio_out, key, cipher, (unsigned char *)passphrase, passphrase_len, NULL, NULL)) {
+
+ switch (EVP_PKEY_type(key->type)) {
+#ifdef HAVE_EVP_PKEY_EC
+ case EVP_PKEY_EC:
+ pem_write = PEM_write_bio_ECPrivateKey(bio_out, EVP_PKEY_get1_EC_KEY(key), cipher, (unsigned char *)passphrase, passphrase_len, NULL, NULL);
+ break;
+#endif
+ default:
+ pem_write = PEM_write_bio_PrivateKey(bio_out, key, cipher, (unsigned char *)passphrase, passphrase_len, NULL, NULL);
+ break;
+ }
+
+ if (pem_write) {
/* Success!
* If returning the output as a string, do so now */
@@ -3853,6 +3879,42 @@ PHP_FUNCTION(openssl_pkey_get_details)
#ifdef HAVE_EVP_PKEY_EC
case EVP_PKEY_EC:
ktype = OPENSSL_KEYTYPE_EC;
+ if (pkey->pkey.ec == NULL) {
+ break;
+ }
+
+ zval ec;
+ const EC_GROUP *ec_group;
+ int nid;
+ char *crv_sn;
+ ASN1_OBJECT *obj;
+ // openssl recommends a buffer length of 80
+ char oir_buf[80];
+
+ ec_group = EC_KEY_get0_group(EVP_PKEY_get1_EC_KEY(pkey));
+
+ // Curve nid (numerical identifier) used for ASN1 mapping
+ nid = EC_GROUP_get_curve_name(ec_group);
+ if (nid == NID_undef) {
+ break;
+ }
+
+ array_init(&ec);
+
+ // Short object name
+ crv_sn = (char*) OBJ_nid2sn(nid);
+ if (crv_sn != NULL) {
+ add_assoc_string(&ec, "curve_name", crv_sn);
+ }
+
+ obj = OBJ_nid2obj(nid);
+ if (obj != NULL) {
+ int oir_len = OBJ_obj2txt(oir_buf, sizeof(oir_buf), obj, 1);
+ add_assoc_stringl(&ec, "curve_oid", (char*)oir_buf, oir_len);
+ ASN1_OBJECT_free(obj);
+ }
+
+ add_assoc_zval(return_value, "ec", &ec);
break;
#endif
default:
diff --git a/ext/openssl/tests/027.phpt b/ext/openssl/tests/027.phpt
new file mode 100644
index 0000000000..8311ab1bd9
--- /dev/null
+++ b/ext/openssl/tests/027.phpt
@@ -0,0 +1,52 @@
+--TEST--
+openssl_pkey_export() with EC key
+--SKIPIF--
+<?php
+if (!extension_loaded("openssl")) die("skip");
+if (!defined('OPENSSL_KEYTYPE_EC')) die("skip no EC available");
+?>
+--FILE--
+<?php
+$key = openssl_pkey_get_private('file://' . dirname(__FILE__) . '/private_ec.key');
+var_dump($key);
+
+var_dump(openssl_pkey_export($key, $output));
+echo $output;
+
+// Load the private key from the exported pem string
+$details = openssl_pkey_get_details(openssl_pkey_get_private($output));
+var_dump(OPENSSL_KEYTYPE_EC === $details['type']);
+
+// Export key with passphrase
+openssl_pkey_export($key, $output, 'passphrase');
+
+$details = openssl_pkey_get_details(openssl_pkey_get_private($output, 'passphrase'));
+var_dump(OPENSSL_KEYTYPE_EC === $details['type']);
+
+// Read public key
+$pKey = openssl_pkey_get_public('file://' . dirname(__FILE__) . '/public_ec.key');
+var_dump($pKey);
+// The details are the same for a public or private key
+var_dump($details === openssl_pkey_get_details($pKey));
+
+
+// Export to file
+$tempname = tempnam(sys_get_temp_dir(), 'openssl_ec');
+var_dump(openssl_pkey_export_to_file($key, $tempname));
+$details = openssl_pkey_get_details(openssl_pkey_get_private('file://' . $tempname));
+var_dump(OPENSSL_KEYTYPE_EC === $details['type']);
+
+// Clean the temporary file
+@unlink($tempname);
+
+?>
+--EXPECTF--
+resource(%d) of type (OpenSSL key)
+bool(true)
+-----BEGIN EC PRIVATE KEY-----%a-----END EC PRIVATE KEY-----
+bool(true)
+bool(true)
+resource(%d) of type (OpenSSL key)
+bool(true)
+bool(true)
+bool(true)
diff --git a/ext/openssl/tests/028.phpt b/ext/openssl/tests/028.phpt
new file mode 100644
index 0000000000..8e0cef46c0
--- /dev/null
+++ b/ext/openssl/tests/028.phpt
@@ -0,0 +1,28 @@
+--TEST--
+openssl_pkey_get_details() with EC key
+--SKIPIF--
+<?php
+if (!extension_loaded("openssl")) die("skip");
+if (!defined('OPENSSL_KEYTYPE_EC')) die("skip no EC available");
+?>
+--FILE--
+<?php
+$key = openssl_pkey_get_private('file://' . dirname(__FILE__) . '/private_ec.key');
+
+print_r(openssl_pkey_get_details($key));
+?>
+--EXPECTF--
+Array
+(
+ [bits] => 256
+ [key] => -----BEGIN PUBLIC KEY-----%a
+-----END PUBLIC KEY-----
+
+ [ec] => Array
+ (
+ [curve_name] => prime256v1
+ [curve_oid] => 1.2.840.10045.3.1.7
+ )
+
+ [type] => 3
+)
diff --git a/ext/openssl/tests/private_ec.key b/ext/openssl/tests/private_ec.key
new file mode 100644
index 0000000000..51cdcb728b
--- /dev/null
+++ b/ext/openssl/tests/private_ec.key
@@ -0,0 +1,5 @@
+-----BEGIN EC PRIVATE KEY-----
+MHcCAQEEILPkqoeyM7XgwYkuSj3077lrsrfWJK5LqMolv+m2oOjZoAoGCCqGSM49
+AwEHoUQDQgAEPq4hbIWHvB51rdWr8ejrjWo4qVNWVugYFtPg/xLQw0mHkIPZ4DvK
+sqOTOnMoezkbSmVVMuwz9flvnqHGmQvmug==
+-----END EC PRIVATE KEY-----
diff --git a/ext/openssl/tests/public_ec.key b/ext/openssl/tests/public_ec.key
new file mode 100644
index 0000000000..a93b2c8ab4
--- /dev/null
+++ b/ext/openssl/tests/public_ec.key
@@ -0,0 +1,4 @@
+-----BEGIN PUBLIC KEY-----
+MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEPq4hbIWHvB51rdWr8ejrjWo4qVNW
+VugYFtPg/xLQw0mHkIPZ4DvKsqOTOnMoezkbSmVVMuwz9flvnqHGmQvmug==
+-----END PUBLIC KEY-----