diff --git a/CHANGELOG.txt b/CHANGELOG.txt
index 07b30595..2c935589 100644
--- a/CHANGELOG.txt
+++ b/CHANGELOG.txt
@@ -1,6 +1,15 @@
xmlseclibs.php
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
-??, ??? 2018, 3.0.5-dev
+22, Apr 2020, 3.1.0
+Features:
+- Support AES-GCM. Requires PHP 7.1. (François Kooman)
+
+Improvements:
+- Fix Travis tests for older PHP versions.
+- Use DOMElement interface to fix some IDEs reporting documentation errors
+
+Bug Fixes:
+- FIX missing InclusiveNamespaces PrefixList from Java + Apache WSS4J. (njake)
06, Nov 2019, 3.0.4
Security Improvements:
diff --git a/src/XMLSecurityKey.php b/src/XMLSecurityKey.php
index d53baa19..90665c95 100644
--- a/src/XMLSecurityKey.php
+++ b/src/XMLSecurityKey.php
@@ -50,6 +50,9 @@ class XMLSecurityKey
const AES128_CBC = 'http://www.w3.org/2001/04/xmlenc#aes128-cbc';
const AES192_CBC = 'http://www.w3.org/2001/04/xmlenc#aes192-cbc';
const AES256_CBC = 'http://www.w3.org/2001/04/xmlenc#aes256-cbc';
+ const AES128_GCM = 'http://www.w3.org/2009/xmlenc11#aes128-gcm';
+ const AES192_GCM = 'http://www.w3.org/2009/xmlenc11#aes192-gcm';
+ const AES256_GCM = 'http://www.w3.org/2009/xmlenc11#aes256-gcm';
const RSA_1_5 = 'http://www.w3.org/2001/04/xmlenc#rsa-1_5';
const RSA_OAEP_MGF1P = 'http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p';
const DSA_SHA1 = 'http://www.w3.org/2000/09/xmldsig#dsa-sha1';
@@ -58,6 +61,7 @@ class XMLSecurityKey
const RSA_SHA384 = 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha384';
const RSA_SHA512 = 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha512';
const HMAC_SHA1 = 'http://www.w3.org/2000/09/xmldsig#hmac-sha1';
+ const AUTHTAG_LENGTH = 16;
/** @var array */
private $cryptParams = array();
@@ -142,6 +146,30 @@ public function __construct($type, $params=null)
$this->cryptParams['keysize'] = 32;
$this->cryptParams['blocksize'] = 16;
break;
+ case (self::AES128_GCM):
+ $this->cryptParams['library'] = 'openssl';
+ $this->cryptParams['cipher'] = 'aes-128-gcm';
+ $this->cryptParams['type'] = 'symmetric';
+ $this->cryptParams['method'] = 'http://www.w3.org/2009/xmlenc11#aes128-gcm';
+ $this->cryptParams['keysize'] = 32;
+ $this->cryptParams['blocksize'] = 16;
+ break;
+ case (self::AES192_GCM):
+ $this->cryptParams['library'] = 'openssl';
+ $this->cryptParams['cipher'] = 'aes-192-gcm';
+ $this->cryptParams['type'] = 'symmetric';
+ $this->cryptParams['method'] = 'http://www.w3.org/2009/xmlenc11#aes192-gcm';
+ $this->cryptParams['keysize'] = 32;
+ $this->cryptParams['blocksize'] = 16;
+ break;
+ case (self::AES256_GCM):
+ $this->cryptParams['library'] = 'openssl';
+ $this->cryptParams['cipher'] = 'aes-256-gcm';
+ $this->cryptParams['type'] = 'symmetric';
+ $this->cryptParams['method'] = 'http://www.w3.org/2009/xmlenc11#aes256-gcm';
+ $this->cryptParams['keysize'] = 32;
+ $this->cryptParams['blocksize'] = 16;
+ break;
case (self::RSA_1_5):
$this->cryptParams['library'] = 'openssl';
$this->cryptParams['padding'] = OPENSSL_PKCS1_PADDING;
@@ -397,12 +425,22 @@ private function unpadISO10126($data)
private function encryptSymmetric($data)
{
$this->iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length($this->cryptParams['cipher']));
- $data = $this->padISO10126($data, $this->cryptParams['blocksize']);
- $encrypted = openssl_encrypt($data, $this->cryptParams['cipher'], $this->key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $this->iv);
+ $authTag = null;
+ if(in_array($this->cryptParams['cipher'], ['aes-128-gcm', 'aes-192-gcm', 'aes-256-gcm'])) {
+ if (version_compare(PHP_VERSION, '7.1.0') < 0) {
+ throw new Exception('PHP 7.1.0 is required to use AES GCM algorithms');
+ }
+ $authTag = openssl_random_pseudo_bytes(self::AUTHTAG_LENGTH);
+ $encrypted = openssl_encrypt($data, $this->cryptParams['cipher'], $this->key, OPENSSL_RAW_DATA, $this->iv, $authTag);
+ } else {
+ $data = $this->padISO10126($data, $this->cryptParams['blocksize']);
+ $encrypted = openssl_encrypt($data, $this->cryptParams['cipher'], $this->key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $this->iv);
+ }
+
if (false === $encrypted) {
throw new Exception('Failure encrypting Data (openssl symmetric) - ' . openssl_error_string());
}
- return $this->iv . $encrypted;
+ return $this->iv . $encrypted . $authTag;
}
/**
@@ -416,11 +454,24 @@ private function decryptSymmetric($data)
$iv_length = openssl_cipher_iv_length($this->cryptParams['cipher']);
$this->iv = substr($data, 0, $iv_length);
$data = substr($data, $iv_length);
- $decrypted = openssl_decrypt($data, $this->cryptParams['cipher'], $this->key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $this->iv);
+ $authTag = null;
+ if(in_array($this->cryptParams['cipher'], ['aes-128-gcm', 'aes-192-gcm', 'aes-256-gcm'])) {
+ if (version_compare(PHP_VERSION, '7.1.0') < 0) {
+ throw new Exception('PHP 7.1.0 is required to use AES GCM algorithms');
+ }
+ // obtain and remove the authentication tag
+ $offset = 0 - self::AUTHTAG_LENGTH;
+ $authTag = substr($data, $offset);
+ $data = substr($data, 0, $offset);
+ $decrypted = openssl_decrypt($data, $this->cryptParams['cipher'], $this->key, OPENSSL_RAW_DATA, $this->iv, $authTag);
+ } else {
+ $decrypted = openssl_decrypt($data, $this->cryptParams['cipher'], $this->key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $this->iv);
+ }
+
if (false === $decrypted) {
throw new Exception('Failure decrypting Data (openssl symmetric) - ' . openssl_error_string());
}
- return $this->unpadISO10126($decrypted);
+ return null !== $authTag ? $decrypted : $this->unpadISO10126($decrypted);
}
/**
diff --git a/tests/aes128-gcm-res.xml b/tests/aes128-gcm-res.xml
new file mode 100644
index 00000000..c4c01784
--- /dev/null
+++ b/tests/aes128-gcm-res.xml
@@ -0,0 +1,7 @@
+
+
+rrX5MGztfar3yQz1IAyH4g2rC2g/YoSfS+AU0VnYh3F1bAlqiZADO//zVgntSG+YmzOZf3AxnZkbQgeU0SqqhHQANaWXk9cQcam6YvmP7m+Mz61i3zx3NUnf+5VE//JPIDB/nAoEv1lS/fjHdwUlRhksM8eiI8QZQRnwR46xlK5ixCdnjS1TZWB+lMqnKGsYGCCy8uY0FhhQuC/EHsved66b4fkgOZV2RUng8kSFB14Sbl7+BGgTBK0wEf3jxUHOLKyaJ7pR9iuDuB6iwJ6iAR+hxIPvImX8swSSA6XRmFjO2eQJ0sJrZDKj5If4cgy5PGSr+Dn5XhawY0SnuAz9Wg==
+
+ NOP0SiaC1UmFtGOa+42ucZxEDMVzxVYCdY0qcIauDmbg4cac0SEMBdzB0H9UJVm8JQ0w/G83ItWaD94ruPI9TFaA6Xlzz0rWyB58xzeTgQj8tjsRewZ+P1IbfZQ5lYMfXcUW
+
+
diff --git a/tests/aes192-gcm-res.xml b/tests/aes192-gcm-res.xml
new file mode 100644
index 00000000..a8f5085b
--- /dev/null
+++ b/tests/aes192-gcm-res.xml
@@ -0,0 +1,7 @@
+
+
+wUHsk5XjaGLrW0BFPd5PqeZfbrGvtEblHVSx97yt20I4QGxrA86fqUg7IL/W1qEpolYiuTFHjOjdZtZVjdbk5K6qbU7v/CgCOq7A9BUGsIodQoNWMP4g8JlHzz+QC+A6MPdpE5FWY5nqlvp9uEc/AEj6sgwer0m4+yTckPyS3q43Lq8f7UpKtUf7KtdtpxO8z3JRFxIrel9WCG7SHgKwqQGK1tBdpqOrAFx/zJ8NyPB0Q4OiArRTW/2bL3ilo2cmaSdqn5NNafKxYnRihMZbSxEaELjVsUKOAGTtUX1BK3FVeRE4hppi1Tt8Q014c21nVK5IU8efMlHm4Gy93o21nw==
+
+ ECGYFdVmVq4bzwcRmfF7N8R8ZtP04wNFb6kmMOvjKUUhXOAfMVuCFr5vK80Ehkc4J6xOVvz0yPAXeY9N7piEN0A0JjJ9lNgyBSi0a0ssDBqZgg+cSF0/xzJ1ucem68FByQcu
+
+
diff --git a/tests/aes256-gcm-res.xml b/tests/aes256-gcm-res.xml
new file mode 100644
index 00000000..904182f8
--- /dev/null
+++ b/tests/aes256-gcm-res.xml
@@ -0,0 +1,7 @@
+
+
+iiuhKthdJ7GKUL51Zr4XlbB9+BuhHUObOq3k6AHiNemgktyJom8BXMVI4lVcMScs8IYqF12fn/0xvCmhBJa2l/Hv0SxJOSpCDF6gdXc8d5H5knrQjJuYfy6XqBS2XidGN1vt/oMkbV7D+K+IHzXsHlrhpJTtqy9XJzZ+rAn3C5HfiFgkPwSrPzNYEc6BTFTJc8LIo+CFrEbDzPg5e4infwFs1w4VNTHJ+1AF3JqMxY+tj1o+uVGIAgktkY32yJMlk+PefYcyqh2UWXHVGHCMmxZqDUghhKjy11qi/arXmHBAHGhI4ZFGX2apjpvuxUDy5xcMlc0M2kUq3l7Aypmrbg==
+
+ ZUssRnr2VTgYBN4nIxa3bsRpcwuRHT/Cw8tBryriqCgI8HfaNg+Qgpnhs24pCepUQ8GoAz7//XWvJxJjAcNUNbhfepSn6yHpVjGEp/LscqAvjSNfsGSXBK+17PVgWE4A7+OT
+
+
\ No newline at end of file
diff --git a/tests/saml/encryption.key b/tests/saml/encryption.key
new file mode 100644
index 00000000..fcc4d87e
--- /dev/null
+++ b/tests/saml/encryption.key
@@ -0,0 +1,40 @@
+-----BEGIN PRIVATE KEY-----
+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
+hd3JVswLnFqpRTh+ZTDZRU8F
+-----END PRIVATE KEY-----
diff --git a/tests/saml/encryption_rsa.key b/tests/saml/encryption_rsa.key
new file mode 100644
index 00000000..80bec994
--- /dev/null
+++ b/tests/saml/encryption_rsa.key
@@ -0,0 +1,39 @@
+-----BEGIN RSA PRIVATE KEY-----
+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
+-----END RSA PRIVATE KEY-----
diff --git a/tests/saml/saml-decrypt.phpt b/tests/saml/saml-decrypt.phpt
new file mode 100644
index 00000000..8f79488f
--- /dev/null
+++ b/tests/saml/saml-decrypt.phpt
@@ -0,0 +1,78 @@
+--TEST--
+Basic Decryption
+--FILE--
+name;
+ if (! empty($filename)) {
+ $objKey->loadKey(dirname(__FILE__) . "/$filename", TRUE);
+ } else {
+ $objKey->loadKey(dirname(__FILE__) . "/encryption_rsa.key", TRUE);
+ }
+}
+
+$testFile = "saml-encrypted.xml";
+
+$output = NULL;
+
+$doc = new DOMDocument();
+$doc->load(dirname(__FILE__) . "/$testFile");
+
+try {
+ $objenc = new XMLSecEnc();
+ $encData = $objenc->locateEncryptedData($doc);
+ if (! $encData) {
+ throw new Exception("Cannot locate Encrypted Data");
+ }
+ $objenc->setNode($encData);
+ $objenc->type = $encData->getAttribute("Type");
+ if (! $objKey = $objenc->locateKey()) {
+ throw new Exception("We know the secret key, but not the algorithm");
+ }
+ $key = NULL;
+
+ if ($objKeyInfo = $objenc->locateKeyInfo($objKey)) {
+ if ($objKeyInfo->isEncrypted) {
+ $objencKey = $objKeyInfo->encryptedCtx;
+ locateLocalKey($objKeyInfo);
+ $key = $objencKey->decryptKey($objKeyInfo);
+ }
+ }
+
+ if (! $objKey->key && empty($key)) {
+ locateLocalKey($objKey);
+ }
+ if (empty($objKey->key)) {
+ $objKey->loadKey($key);
+ }
+
+ $token = NULL;
+
+ if ($decrypt = $objenc->decryptNode($objKey, TRUE)) {
+ $output = NULL;
+
+ $xpath = new DOMXpath($decrypt->ownerDocument);
+ $xpath->registerNamespace('saml2p', 'urn:oasis:names:tc:SAML:2.0:protocol');
+ $xpath->registerNamespace('saml2', 'urn:oasis:names:tc:SAML:2.0:assertion');
+
+ $xpathQuery = 'string(/saml2p:Response/saml2:EncryptedAssertion/saml2:Assertion/saml2:AttributeStatement/saml2:Attribute/saml2:AttributeValue/saml2:NameID/text())';
+
+ $nameID = $xpath->evaluate($xpathQuery);
+
+ print "$nameID\n";
+
+ } else {
+ throw new Exception("Unable to decrypt node");;
+ }
+} catch (Exception $e) {
+ var_dump($e);
+}
+
+?>
+--EXPECTF--
+KYzsRqRzQY5qp+bv9T8bHA/AvsI=
diff --git a/tests/saml/saml-encrypted.xml b/tests/saml/saml-encrypted.xml
new file mode 100644
index 00000000..24dec1f2
--- /dev/null
+++ b/tests/saml/saml-encrypted.xml
@@ -0,0 +1,66 @@
+
+https://testidp3-dev.aai.dfn.de/idp/shibboleth3HA0K82ZC2WAbAXvwL2z1Hj3GfTFIdw5iHJXEpoi3Aw=YwhgUqR10jaw7bDW+1hPrAKjBH69qNjFsKn4dbI9m+Iw0fgH26GbwokbkNGAph9ShXBNsSv29ehVCOmtYHPqHCQb3YAK2Ftyc6UuhIX4VcEeMFmfdbXYIRCsGmPWJn4qWJNMVES3FKU3jNF9qXnFtk0tvCnrAIoiBuiR+o3A/XttW+RzvWJSvyyi745d8183kQEbO00wFEKSuw4gjoKJ6tPG8R4Eu/8ZVALm5AfGI2tSiEW8LXoFrO334jdG0Pp7DHbnameMbOZqh3gP8B0PGtlBlG0/Xhvbge4BirbePQetjhdPk0kiNkiipYEntpvtvO7+Q2bmR6acbzD+coboEit/LfmbwhidS8B/S80TRgBltIV7FMzM6JUa3rNp4bllGQo+KgFYiqM2NPHMVrSmztVwcynCLTBDgkaL8iFQYt5TGE/8hk/kXocwfDpqlY16JLMXKYwr2cu4AfsAsNGwPV8dRPdi2FT+v5tu19RAoAlX7M8b6Qt3dtmfVxwJoHyKouF9ZXDFtHYh7DkDcnjAbkFa9a91onvkASK2NpLK6kMg0896DpyjTq6tTF7kSCKb9Ynho5gYnesO1pFJWyiIUqBJ/6glKD59K11J7W+wFMGWqLFcv7H6hQD+dhtQM3/yV5yLEItf78o6yTAtZ6/BoY0ezk+XdHvMcbB/G6BmtHE=MIIKmjCCCYKgAwIBAgIMIBJEUPPYLkAq6JnBMA0GCSqGSIb3DQEBCwUAMIGNMQswCQYDVQQGEwJE
+RTFFMEMGA1UECgw8VmVyZWluIHp1ciBGb2VyZGVydW5nIGVpbmVzIERldXRzY2hlbiBGb3JzY2h1
+bmdzbmV0emVzIGUuIFYuMRAwDgYDVQQLDAdERk4tUEtJMSUwIwYDVQQDDBxERk4tVmVyZWluIEds
+b2JhbCBJc3N1aW5nIENBMB4XDTE4MTExOTE0MjA1NloXDTIxMDIyMDE0MjA1NlowgbMxCzAJBgNV
+BAYTAkRFMQ8wDQYDVQQIDAZCZXJsaW4xDzANBgNVBAcMBkJlcmxpbjFFMEMGA1UECgw8VmVyZWlu
+IHp1ciBGb2VyZGVydW5nIGVpbmVzIERldXRzY2hlbiBGb3JzY2h1bmdzbmV0emVzIGUuIFYuMRkw
+FwYDVQQLDBBHZXNjaGFlZnRzc3RlbGxlMSAwHgYDVQQDDBd0ZXN0aWRwMy1kZXYuYWFpLmRmbi5k
+ZTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAKxh3SJNVPkM6opuC9Y8xA3MtFhqr9w9
+eh1mvKd04HN/Ux8rKLH1nAYlG+uDoI/CeaGRFHh+ouEJ0YNI+tgCcljHfkLYUxnURyMEbvxGWeMk
+if//wCo4NaHuWkf9QKfGridnZAV3TkOCEj/+R8xtUbjcqdKVsh7vxSr1AsPUEF8OyVW1X54BaBnp
+W8fw0T4KVef3jcs+9tS3bzInx6s6VJY7wMGLtdoULToFu6f9KZK179gSGW8FI39NM4agZbzNryCH
+4yaH7VIUESObvXuEHWKBSlpWrbw6KApakWpPiN0KRdxF3T1kTKEab73pvF+3Ca7DxPqATq1KslhG
+J4FHKDOUSIn343TfZLmHHfOWdAZGJED6GfX7Q25WRt3KUeOX5hJsBrJIQ7igro9+mHM7eCMIWG30
+Rbq5VN4eTtUMiOet4lsqmubJK0HWgVd6uLYiuy7qcz4FqathCLq4tlMTLSNhZxTcr5KhcY5ZjoOg
+A5PSfb22BYrd1o/w93Tr0adq7RwA8FBcgr5PMANaVH3nXEMgMfHp/CxscQw7Korin4rLxtOwpRhk
+f8xD6q8zI8XrPdxIHoyPTnLH7xxladclLK2EgqsOEdOrJtVPMHURmMdTvkwmUAb37+BnsJeUUiLy
+Db4fkGKXryFp7Va4nt6+Gtv7GIYCa6Q+PyKKyTj88GurAgMBAAGjggXQMIIFzDBZBgNVHSAEUjBQ
+MAgGBmeBDAECAjANBgsrBgEEAYGtIYIsHjAPBg0rBgEEAYGtIYIsAQEEMBEGDysGAQQBga0hgiwB
+AQQDCDARBg8rBgEEAYGtIYIsAgEEAwgwCQYDVR0TBAIwADAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0l
+BBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMBMB0GA1UdDgQWBBSPVaFUGFCX53+bTmO4KjfPIUapQDAf
+BgNVHSMEGDAWgBRrOpiL+fJTidrgrbIyHgkf6Ko7dDAiBgNVHREEGzAZghd0ZXN0aWRwMy1kZXYu
+YWFpLmRmbi5kZTCBjQYDVR0fBIGFMIGCMD+gPaA7hjlodHRwOi8vY2RwMS5wY2EuZGZuLmRlL2Rm
+bi1jYS1nbG9iYWwtZzIvcHViL2NybC9jYWNybC5jcmwwP6A9oDuGOWh0dHA6Ly9jZHAyLnBjYS5k
+Zm4uZGUvZGZuLWNhLWdsb2JhbC1nMi9wdWIvY3JsL2NhY3JsLmNybDCB2wYIKwYBBQUHAQEEgc4w
+gcswMwYIKwYBBQUHMAGGJ2h0dHA6Ly9vY3NwLnBjYS5kZm4uZGUvT0NTUC1TZXJ2ZXIvT0NTUDBJ
+BggrBgEFBQcwAoY9aHR0cDovL2NkcDEucGNhLmRmbi5kZS9kZm4tY2EtZ2xvYmFsLWcyL3B1Yi9j
+YWNlcnQvY2FjZXJ0LmNydDBJBggrBgEFBQcwAoY9aHR0cDovL2NkcDIucGNhLmRmbi5kZS9kZm4t
+Y2EtZ2xvYmFsLWcyL3B1Yi9jYWNlcnQvY2FjZXJ0LmNydDCCA2EGCisGAQQB1nkCBAIEggNRBIID
+TQNLAHYAb1N2rDHwMRnYmQCkURX/dxUcEdkCwQApBo2yCJo32RMAAAFnLFiQOAAABAMARzBFAiEA
+vGyJoepOba1cZXAQKfKYz1xsLJH9WA/L3dv5PQP2AnACIFzefUnlvr0fKnNsvsz5QUJfCFnkjRa7
+RQj72w8mkibVAHcAqucLfzy41WbIbC8Wl5yfRF9pqw60U1WJsvd6AwEE880AAAFnLFiQRgAABAMA
+SDBGAiEA+Tes3tEHTn9LSFQy+9t/Sxd0hRHzqpkFBtmY5WzadP0CIQDOhYNcF4AKJb5CblDepaDx
+F9jk0Cnz9HdETB4ihxEvuwB2AFWB1MIWkDYBSuoLm1c8U/DA5Dh4cCUIFy+jqh0HE9MMAAABZyxY
+kUUAAAQDAEcwRQIgFYyzXgRfcsp5ahHRWXzVYGfzLDnx9kLMqtJflfcUAb8CIQC+G6taxeHvdrNx
+6y491OKHJb0z9MfGx0JQ2P9cWK0NkgB2AKS5CZC0GFgUh7sTosxncAo8NZgE+RvfuON3zQ7IDdwQ
+AAABZyxYkoAAAAQDAEcwRQIgYY5yPbkr81Pf3wPtX0WkewCqnAPZmEMjCbwYVe81po4CIQCxwAE1
+VpugPod3N0m+SKYCAaExcv3LYQ5zRw2N/hviHQB3ALvZ37wfinG1k5Qjl6qSe0c4V5UKq1LoGpCW
+ZDaOHtGFAAABZyxYk30AAAQDAEgwRgIhAIdvqfip+idHyyVy67ag1gmoS9mLLe7s+HX8/8QjHPr6
+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
diff --git a/tests/xmlsec-decrypt.phpt b/tests/xmlsec-decrypt.phpt
index bc57f8c7..2b2bb2cb 100755
--- a/tests/xmlsec-decrypt.phpt
+++ b/tests/xmlsec-decrypt.phpt
@@ -16,7 +16,8 @@ function locateLocalKey($objKey) {
}
}
-$arTests = array('AOESP_SHA1'=>'oaep_sha1-res.xml');
+$arTests = array('AOESP_SHA1'=>'oaep_sha1-res.xml', 'AES128-GCM'=>'aes128-gcm-res.xml',
+ 'AES192-GCM'=>'aes192-gcm-res.xml', 'AES256-GCM'=>'aes256-gcm-res.xml');
$doc = new DOMDocument();
@@ -69,7 +70,7 @@ foreach ($arTests AS $testName=>$testFile) {
}
}
} catch (Exception $e) {
-
+ var_dump($e);
}
$outfile = dirname(__FILE__) . "/basic-doc.xml";
@@ -89,3 +90,6 @@ foreach ($arTests AS $testName=>$testFile) {
?>
--EXPECTF--
AOESP_SHA1: Passed
+AES128-GCM: Passed
+AES192-GCM: Passed
+AES256-GCM: Passed
\ No newline at end of file
diff --git a/tests/xmlsec-encrypt-aes-gmc.phpt b/tests/xmlsec-encrypt-aes-gmc.phpt
new file mode 100644
index 00000000..5d9be03c
--- /dev/null
+++ b/tests/xmlsec-encrypt-aes-gmc.phpt
@@ -0,0 +1,50 @@
+--TEST--
+Basic Encryption
+--FILE--
+ array('file'=>'aes128-gcm.xml', 'key'=>XMLSecurityKey::AES128_GCM),
+ 'AES192_GCM' => array('file'=>'aes192-gcm.xml', 'key'=>XMLSecurityKey::AES192_GCM),
+ 'AES256_GCM' => array('file'=>'aes256-gcm.xml', 'key'=>XMLSecurityKey::AES256_GCM));
+
+foreach ($arTests AS $testName=>$testParams) {
+ $testFile = $testParams['file'];
+ $testKey = $testParams['key'];
+ if (file_exists(dirname(__FILE__) . "/$testFile")) {
+ unlink(dirname(__FILE__) . "/$testFile");
+ }
+
+ print "$testName: ";
+
+ $dom = new DOMDocument();
+ $dom->load(dirname(__FILE__) . '/basic-doc.xml');
+
+ $objKey = new XMLSecurityKey($testKey);
+ $objKey->generateSessionKey();
+
+ $siteKey = new XMLSecurityKey(XMLSecurityKey::RSA_OAEP_MGF1P, array('type'=>'public'));
+ $siteKey->loadKey(dirname(__FILE__) . '/mycert.pem', TRUE, TRUE);
+
+ $enc = new XMLSecEnc();
+ $enc->setNode($dom->documentElement);
+ $enc->encryptKey($siteKey, $objKey);
+
+ $enc->type = XMLSecEnc::Element;
+ $encNode = $enc->encryptNode($objKey);
+
+ $dom->save(dirname(__FILE__) . "/$testFile");
+
+ $root = $dom->documentElement;
+ echo $root->localName."\n";
+
+ unlink(dirname(__FILE__) . "/$testFile");
+}
+
+?>
+--EXPECTF--
+AES128_GCM: EncryptedData
+AES192_GCM: EncryptedData
+AES256_GCM: EncryptedData
diff --git a/xmlseclibs.php b/xmlseclibs.php
index b2e0fb36..1859bc23 100644
--- a/xmlseclibs.php
+++ b/xmlseclibs.php
@@ -37,7 +37,7 @@
* @author Robert Richards
* @copyright 2007-2020 Robert Richards
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
- * @version 3.0.5-dev
+ * @version 3.1.0
*/
$xmlseclibs_srcdir = dirname(__FILE__) . '/src/';