33
44use DOMElement ;
55use Exception ;
6+ use phpseclib3 \Crypt \PublicKeyLoader ;
7+ use phpseclib3 \Crypt \RSA ;
68
79/**
810 * xmlseclibs.php
@@ -62,6 +64,7 @@ class XMLSecurityKey
6264 const RSA_SHA384 = 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha384 ' ;
6365 const RSA_SHA512 = 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha512 ' ;
6466 const HMAC_SHA1 = 'http://www.w3.org/2000/09/xmldsig#hmac-sha1 ' ;
67+ const RSA_SHA256_MGF1 = 'http://www.w3.org/2007/05/xmldsig-more#sha256-rsa-MGF1 ' ;
6568 const AUTHTAG_LENGTH = 16 ;
6669
6770 /** @var array */
@@ -183,10 +186,10 @@ public function __construct($type, $params=null)
183186 }
184187 throw new Exception ('Certificate "type" (private/public) must be passed via parameters ' );
185188 case (self ::RSA_OAEP_MGF1P ):
186- $ this ->cryptParams ['library ' ] = 'openssl ' ;
187- $ this ->cryptParams ['padding ' ] = OPENSSL_PKCS1_OAEP_PADDING ;
189+ $ this ->cryptParams ['library ' ] = 'phpseclib ' ;
190+ $ this ->cryptParams ['padding ' ] = RSA :: ENCRYPTION_OAEP ;
188191 $ this ->cryptParams ['method ' ] = 'http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p ' ;
189- $ this ->cryptParams ['hash ' ] = null ;
192+ $ this ->cryptParams ['digest ' ] = ' sha1 ' ;
190193 if (is_array ($ params ) && ! empty ($ params ['type ' ])) {
191194 if ($ params ['type ' ] == 'public ' || $ params ['type ' ] == 'private ' ) {
192195 $ this ->cryptParams ['type ' ] = $ params ['type ' ];
@@ -195,10 +198,10 @@ public function __construct($type, $params=null)
195198 }
196199 throw new Exception ('Certificate "type" (private/public) must be passed via parameters ' );
197200 case (self ::RSA_OAEP ):
198- $ this ->cryptParams ['library ' ] = 'openssl ' ;
199- $ this ->cryptParams ['padding ' ] = OPENSSL_PKCS1_OAEP_PADDING ;
201+ $ this ->cryptParams ['library ' ] = 'phpseclib ' ;
202+ $ this ->cryptParams ['padding ' ] = RSA :: ENCRYPTION_OAEP ;
200203 $ this ->cryptParams ['method ' ] = 'http://www.w3.org/2009/xmlenc11#rsa-oaep ' ;
201- $ this ->cryptParams ['hash ' ] = 'http://www.w3.org/2009/xmlenc11#mgf1sha1 ' ;
204+ $ this ->cryptParams ['digest ' ] = 'sha256 ' ;
202205 if (is_array ($ params ) && ! empty ($ params ['type ' ])) {
203206 if ($ params ['type ' ] == 'public ' || $ params ['type ' ] == 'private ' ) {
204207 $ this ->cryptParams ['type ' ] = $ params ['type ' ];
@@ -257,6 +260,18 @@ public function __construct($type, $params=null)
257260 $ this ->cryptParams ['library ' ] = $ type ;
258261 $ this ->cryptParams ['method ' ] = 'http://www.w3.org/2000/09/xmldsig#hmac-sha1 ' ;
259262 break ;
263+ case (self ::RSA_SHA256_MGF1 ):
264+ $ this ->cryptParams ['library ' ] = 'phpseclib ' ;
265+ $ this ->cryptParams ['method ' ] = 'http://www.w3.org/2007/05/xmldsig-more#sha256-rsa-MGF1 ' ;
266+ $ this ->cryptParams ['padding ' ] = RSA ::SIGNATURE_PSS ;
267+ $ this ->cryptParams ['digest ' ] = 'SHA256 ' ;
268+ if (is_array ($ params ) && ! empty ($ params ['type ' ])) {
269+ if ($ params ['type ' ] == 'public ' || $ params ['type ' ] == 'private ' ) {
270+ $ this ->cryptParams ['type ' ] = $ params ['type ' ];
271+ break ;
272+ }
273+ }
274+ throw new Exception ('Certificate "type" (private/public) must be passed via parameters ' );
260275 default :
261276 throw new Exception ('Invalid Key Type ' );
262277 }
@@ -291,9 +306,9 @@ public function generateSessionKey()
291306 throw new Exception ('Unknown key size for type " ' . $ this ->type . '". ' );
292307 }
293308 $ keysize = $ this ->cryptParams ['keysize ' ];
294-
309+
295310 $ key = openssl_random_pseudo_bytes ($ keysize );
296-
311+
297312 if ($ this ->type === self ::TRIPLEDES_CBC ) {
298313 /* Make sure that the generated key has the proper parity bits set.
299314 * Mcrypt doesn't care about the parity bits, but others may care.
@@ -308,7 +323,7 @@ public function generateSessionKey()
308323 $ key [$ i ] = chr ($ byte );
309324 }
310325 }
311-
326+
312327 $ this ->key = $ key ;
313328 return $ key ;
314329 }
@@ -372,17 +387,17 @@ public function loadKey($key, $isFile=false, $isCert = false)
372387 if ($ this ->cryptParams ['library ' ] == 'openssl ' ) {
373388 switch ($ this ->cryptParams ['type ' ]) {
374389 case 'public ' :
375- if ($ isCert ) {
376- /* Load the thumbprint if this is an X509 certificate. */
377- $ this ->X509Thumbprint = self ::getRawThumbprint ($ this ->key );
378- }
379- $ this ->key = openssl_get_publickey ($ this ->key );
380- if (! $ this ->key ) {
381- throw new Exception ('Unable to extract public key ' );
382- }
383- break ;
384-
385- case 'private ' :
390+ if ($ isCert ) {
391+ /* Load the thumbprint if this is an X509 certificate. */
392+ $ this ->X509Thumbprint = self ::getRawThumbprint ($ this ->key );
393+ }
394+ $ this ->key = openssl_get_publickey ($ this ->key );
395+ if (! $ this ->key ) {
396+ throw new Exception ('Unable to extract public key ' );
397+ }
398+ break ;
399+
400+ case 'private ' :
386401 $ this ->key = openssl_get_privatekey ($ this ->key , $ this ->passphrase );
387402 break ;
388403
@@ -450,7 +465,7 @@ private function encryptSymmetric($data)
450465 $ data = $ this ->padISO10126 ($ data , $ this ->cryptParams ['blocksize ' ]);
451466 $ encrypted = openssl_encrypt ($ data , $ this ->cryptParams ['cipher ' ], $ this ->key , OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING , $ this ->iv );
452467 }
453-
468+
454469 if (false === $ encrypted ) {
455470 throw new Exception ('Failure encrypting Data (openssl symmetric) - ' . openssl_error_string ());
456471 }
@@ -481,7 +496,7 @@ private function decryptSymmetric($data)
481496 } else {
482497 $ decrypted = openssl_decrypt ($ data , $ this ->cryptParams ['cipher ' ], $ this ->key , OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING , $ this ->iv );
483498 }
484-
499+
485500 if (false === $ decrypted ) {
486501 throw new Exception ('Failure decrypting Data (openssl symmetric) - ' . openssl_error_string ());
487502 }
@@ -629,6 +644,14 @@ public function decryptData($data)
629644 case 'private ' :
630645 return $ this ->decryptPrivate ($ data );
631646 }
647+ } else if ($ this ->cryptParams ['library ' ] === 'phpseclib ' ) {
648+ $ private = PublicKeyLoader::load ($ this ->key );
649+ $ result = $ private
650+ ->withPadding ($ this ->cryptParams ['padding ' ])
651+ ->withHash ($ this ->cryptParams ['digest ' ])
652+ ->withMGFHash ($ this ->cryptParams ['digest ' ])
653+ ->decrypt ($ data );
654+ return $ result ;
632655 }
633656 }
634657
@@ -643,6 +666,13 @@ public function signData($data)
643666 switch ($ this ->cryptParams ['library ' ]) {
644667 case 'openssl ' :
645668 return $ this ->signOpenSSL ($ data );
669+ case 'phpseclib ' :
670+ $ private = PublicKeyLoader::load ($ this ->key );
671+ return $ private
672+ ->withPadding ($ this ->cryptParams ['padding ' ])
673+ ->withHash ($ this ->cryptParams ['digest ' ])
674+ ->withMGFHash ($ this ->cryptParams ['digest ' ])
675+ ->sign ($ data );
646676 case (self ::HMAC_SHA1 ):
647677 return hash_hmac ("sha1 " , $ data , $ this ->key , true );
648678 }
@@ -669,6 +699,14 @@ public function verifySignature($data, $signature)
669699 switch ($ this ->cryptParams ['library ' ]) {
670700 case 'openssl ' :
671701 return $ this ->verifyOpenSSL ($ data , $ signature );
702+ case 'phpseclib ' :
703+ $ public = PublicKeyLoader::load ($ this ->key );
704+ $ result = $ public
705+ ->withPadding ($ this ->cryptParams ['padding ' ])
706+ ->withHash ($ this ->cryptParams ['digest ' ])
707+ ->withMGFHash ($ this ->cryptParams ['digest ' ])
708+ ->verify ($ data , $ signature );
709+ return $ result === true ? 1 : 0 ;
672710 case (self ::HMAC_SHA1 ):
673711 $ expectedSignature = hash_hmac ("sha1 " , $ data , $ this ->key , true );
674712 return strcmp ($ signature , $ expectedSignature ) == 0 ;
0 commit comments