| 
									
										
										
										
											2010-02-22 09:05:32 -05:00
										 |  |  | <?php | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * StatusNet - the distributed open-source microblogging tool | 
					
						
							|  |  |  |  * Copyright (C) 2010, StatusNet, Inc. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * A sample module to show best practices for StatusNet plugins | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * PHP version 5 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This program is free software: you can redistribute it and/or modify | 
					
						
							|  |  |  |  * it under the terms of the GNU Affero General Public License as published by | 
					
						
							|  |  |  |  * the Free Software Foundation, either version 3 of the License, or | 
					
						
							|  |  |  |  * (at your option) any later version. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This program is distributed in the hope that it will be useful, | 
					
						
							|  |  |  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
					
						
							|  |  |  |  * GNU Affero General Public License for more details. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * You should have received a copy of the GNU Affero General Public License | 
					
						
							|  |  |  |  * along with this program.  If not, see <http://www.gnu.org/licenses/>. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * @package   StatusNet | 
					
						
							|  |  |  |  * @author    James Walker <james@status.net> | 
					
						
							|  |  |  |  * @copyright 2010 StatusNet, Inc. | 
					
						
							|  |  |  |  * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 | 
					
						
							|  |  |  |  * @link      http://status.net/ | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class MagicEnvelope | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     const ENCODING = 'base64url'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const NS = 'http://salmon-protocol.org/ns/magic-env'; | 
					
						
							| 
									
										
										
										
											2010-09-03 01:35:04 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-22 09:05:32 -05:00
										 |  |  |     private function normalizeUser($user_id) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         if (substr($user_id, 0, 5) == 'http:' || | 
					
						
							|  |  |  |             substr($user_id, 0, 6) == 'https:' || | 
					
						
							|  |  |  |             substr($user_id, 0, 5) == 'acct:') { | 
					
						
							|  |  |  |             return $user_id; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (strpos($user_id, '@') !== FALSE) { | 
					
						
							|  |  |  |             return 'acct:' . $user_id; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return 'http://' . $user_id; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     public function getKeyPair($signer_uri) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2010-02-25 23:38:25 -05:00
										 |  |  |         $disco = new Discovery(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-26 04:07:58 -05:00
										 |  |  |         try { | 
					
						
							|  |  |  |             $xrd = $disco->lookup($signer_uri); | 
					
						
							|  |  |  |         } catch (Exception $e) { | 
					
						
							|  |  |  |             return false; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if ($xrd->links) { | 
					
						
							|  |  |  |             if ($link = Discovery::getService($xrd->links, Magicsig::PUBLICKEYREL)) { | 
					
						
							| 
									
										
										
										
											2010-03-24 14:27:35 -04:00
										 |  |  |                 $keypair = false; | 
					
						
							|  |  |  |                 $parts = explode(',', $link['href']); | 
					
						
							|  |  |  |                 if (count($parts) == 2) { | 
					
						
							|  |  |  |                     $keypair = $parts[1]; | 
					
						
							|  |  |  |                 } else { | 
					
						
							| 
									
										
										
										
											2010-03-11 14:32:22 -05:00
										 |  |  |                     // Backwards compatibility check for separator bug in 0.9.0
 | 
					
						
							| 
									
										
										
										
											2010-03-24 14:27:35 -04:00
										 |  |  |                     $parts = explode(';', $link['href']); | 
					
						
							|  |  |  |                     if (count($parts) == 2) { | 
					
						
							|  |  |  |                         $keypair = $parts[1]; | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                 } | 
					
						
							| 
									
										
										
										
											2010-09-03 01:35:04 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-03-24 14:27:35 -04:00
										 |  |  |                 if ($keypair) { | 
					
						
							|  |  |  |                     return $keypair; | 
					
						
							| 
									
										
										
										
											2010-03-11 14:32:22 -05:00
										 |  |  |                 } | 
					
						
							| 
									
										
										
										
											2010-02-26 04:07:58 -05:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2010-02-25 23:38:25 -05:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2010-09-19 15:17:36 +02:00
										 |  |  |         // TRANS: Exception.
 | 
					
						
							|  |  |  |         throw new Exception(_m('Unable to locate signer public key.')); | 
					
						
							| 
									
										
										
										
											2010-02-22 09:05:32 -05:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-05 23:26:09 +00:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * The current MagicEnvelope spec as used in StatusNet 0.9.7 and later | 
					
						
							|  |  |  |      * includes both the original data and some signing metadata fields as | 
					
						
							|  |  |  |      * the input plaintext for the signature hash. | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @param array $env | 
					
						
							|  |  |  |      * @return string | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public function signingText($env) { | 
					
						
							|  |  |  |         return implode('.', array($env['data'], // this field is pre-base64'd
 | 
					
						
							|  |  |  |                             Magicsig::base64_url_encode($env['data_type']), | 
					
						
							|  |  |  |                             Magicsig::base64_url_encode($env['encoding']), | 
					
						
							|  |  |  |                             Magicsig::base64_url_encode($env['alg']))); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2010-02-22 09:05:32 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-05 14:05:59 -08:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @param <type> $text | 
					
						
							|  |  |  |      * @param <type> $mimetype | 
					
						
							|  |  |  |      * @param <type> $keypair | 
					
						
							|  |  |  |      * @return array: associative array of envelope properties | 
					
						
							|  |  |  |      * @fixme it might be easier to work with storing envelope data these in the object instead of passing arrays around | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2010-02-26 14:21:21 -05:00
										 |  |  |     public function signMessage($text, $mimetype, $keypair) | 
					
						
							| 
									
										
										
										
											2010-02-22 09:05:32 -05:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2010-02-26 04:07:58 -05:00
										 |  |  |         $signature_alg = Magicsig::fromString($keypair); | 
					
						
							| 
									
										
										
										
											2010-03-26 13:37:46 -04:00
										 |  |  |         $armored_text = Magicsig::base64_url_encode($text); | 
					
						
							| 
									
										
										
										
											2011-01-05 23:26:09 +00:00
										 |  |  |         $env = array( | 
					
						
							| 
									
										
										
										
											2010-02-22 09:05:32 -05:00
										 |  |  |             'data' => $armored_text, | 
					
						
							|  |  |  |             'encoding' => MagicEnvelope::ENCODING, | 
					
						
							|  |  |  |             'data_type' => $mimetype, | 
					
						
							| 
									
										
										
										
											2011-01-05 23:26:09 +00:00
										 |  |  |             'sig' => '', | 
					
						
							| 
									
										
										
										
											2010-02-22 09:05:32 -05:00
										 |  |  |             'alg' => $signature_alg->getName() | 
					
						
							|  |  |  |         ); | 
					
						
							| 
									
										
										
										
											2011-01-05 23:26:09 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         $env['sig'] = $signature_alg->sign($this->signingText($env)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return $env; | 
					
						
							| 
									
										
										
										
											2010-02-22 09:05:32 -05:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-05 14:05:59 -08:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Create an <me:env> XML representation of the envelope. | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @param array $env associative array with envelope data | 
					
						
							|  |  |  |      * @return string representation of XML document | 
					
						
							|  |  |  |      * @fixme it might be easier to work with storing envelope data these in the object instead of passing arrays around | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2010-02-26 15:39:30 -05:00
										 |  |  |     public function toXML($env) { | 
					
						
							| 
									
										
										
										
											2010-08-02 16:42:28 -04:00
										 |  |  |         $xs = new XMLStringer(); | 
					
						
							|  |  |  |         $xs->startXML(); | 
					
						
							|  |  |  |         $xs->elementStart('me:env', array('xmlns:me' => MagicEnvelope::NS)); | 
					
						
							|  |  |  |         $xs->element('me:data', array('type' => $env['data_type']), $env['data']); | 
					
						
							|  |  |  |         $xs->element('me:encoding', null, $env['encoding']); | 
					
						
							|  |  |  |         $xs->element('me:alg', null, $env['alg']); | 
					
						
							|  |  |  |         $xs->element('me:sig', null, $env['sig']); | 
					
						
							|  |  |  |         $xs->elementEnd('me:env'); | 
					
						
							| 
									
										
										
										
											2010-09-03 01:35:04 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-02 16:42:28 -04:00
										 |  |  |         $string =  $xs->getString(); | 
					
						
							|  |  |  |         common_debug($string); | 
					
						
							|  |  |  |         return $string; | 
					
						
							| 
									
										
										
										
											2010-02-26 15:39:30 -05:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-05 14:05:59 -08:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Extract the contained XML payload, and insert a copy of the envelope | 
					
						
							|  |  |  |      * signature data as an <me:provenance> section. | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @param array $env associative array with envelope data | 
					
						
							|  |  |  |      * @return string representation of modified XML document | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @fixme in case of XML parsing errors, this will spew to the error log or output | 
					
						
							|  |  |  |      * @fixme it might be easier to work with storing envelope data these in the object instead of passing arrays around | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2010-02-22 09:05:32 -05:00
										 |  |  |     public function unfold($env) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $dom = new DOMDocument(); | 
					
						
							| 
									
										
										
										
											2010-03-26 13:37:46 -04:00
										 |  |  |         $dom->loadXML(Magicsig::base64_url_decode($env['data'])); | 
					
						
							| 
									
										
										
										
											2010-02-22 09:05:32 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if ($dom->documentElement->tagName != 'entry') { | 
					
						
							|  |  |  |             return false; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $prov = $dom->createElementNS(MagicEnvelope::NS, 'me:provenance'); | 
					
						
							|  |  |  |         $prov->setAttribute('xmlns:me', MagicEnvelope::NS); | 
					
						
							|  |  |  |         $data = $dom->createElementNS(MagicEnvelope::NS, 'me:data', $env['data']); | 
					
						
							|  |  |  |         $data->setAttribute('type', $env['data_type']); | 
					
						
							|  |  |  |         $prov->appendChild($data); | 
					
						
							|  |  |  |         $enc = $dom->createElementNS(MagicEnvelope::NS, 'me:encoding', $env['encoding']); | 
					
						
							|  |  |  |         $prov->appendChild($enc); | 
					
						
							|  |  |  |         $alg = $dom->createElementNS(MagicEnvelope::NS, 'me:alg', $env['alg']); | 
					
						
							|  |  |  |         $prov->appendChild($alg); | 
					
						
							|  |  |  |         $sig = $dom->createElementNS(MagicEnvelope::NS, 'me:sig', $env['sig']); | 
					
						
							|  |  |  |         $prov->appendChild($sig); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $dom->documentElement->appendChild($prov); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return $dom->saveXML(); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2010-09-03 01:35:04 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-05 14:05:59 -08:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Find the author URI referenced in the given Atom entry. | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @param string $text string containing Atom entry XML | 
					
						
							|  |  |  |      * @return mixed URI string or false if XML parsing fails, or null if no author URI can be found | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @fixme XML parsing failures will spew to error logs/output | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2010-02-22 09:05:32 -05:00
										 |  |  |     public function getAuthor($text) { | 
					
						
							|  |  |  |         $doc = new DOMDocument(); | 
					
						
							|  |  |  |         if (!$doc->loadXML($text)) { | 
					
						
							|  |  |  |             return FALSE; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if ($doc->documentElement->tagName == 'entry') { | 
					
						
							|  |  |  |             $authors = $doc->documentElement->getElementsByTagName('author'); | 
					
						
							|  |  |  |             foreach ($authors as $author) { | 
					
						
							|  |  |  |                 $uris = $author->getElementsByTagName('uri'); | 
					
						
							|  |  |  |                 foreach ($uris as $uri) { | 
					
						
							|  |  |  |                     return $this->normalizeUser($uri->nodeValue); | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2010-09-03 01:35:04 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-05 14:05:59 -08:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Check if the author in the Atom entry fragment claims to match | 
					
						
							|  |  |  |      * the given identifier URI. | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @param string $text string containing Atom entry XML | 
					
						
							|  |  |  |      * @param string $signer_uri | 
					
						
							|  |  |  |      * @return boolean | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2010-02-22 09:05:32 -05:00
										 |  |  |     public function checkAuthor($text, $signer_uri) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         return ($this->getAuthor($text) == $signer_uri); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2010-09-03 01:35:04 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-05 14:05:59 -08:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Attempt to verify cryptographic signing for parsed envelope data. | 
					
						
							|  |  |  |      * Requires network access to retrieve public key referenced by the envelope signer. | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * Details of failure conditions are dumped to output log and not exposed to caller. | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @param array $env array representation of magic envelope data, as returned from MagicEnvelope::parse() | 
					
						
							|  |  |  |      * @return boolean | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @fixme it might be easier to work with storing envelope data these in the object instead of passing arrays around | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2010-02-22 09:05:32 -05:00
										 |  |  |     public function verify($env) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         if ($env['alg'] != 'RSA-SHA256') { | 
					
						
							| 
									
										
										
										
											2010-03-04 01:46:34 -05:00
										 |  |  |             common_log(LOG_DEBUG, "Salmon error: bad algorithm"); | 
					
						
							| 
									
										
										
										
											2010-02-22 09:05:32 -05:00
										 |  |  |             return false; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if ($env['encoding'] != MagicEnvelope::ENCODING) { | 
					
						
							| 
									
										
										
										
											2010-03-04 01:46:34 -05:00
										 |  |  |             common_log(LOG_DEBUG, "Salmon error: bad encoding"); | 
					
						
							| 
									
										
										
										
											2010-02-22 09:05:32 -05:00
										 |  |  |             return false; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-03-26 13:37:46 -04:00
										 |  |  |         $text = Magicsig::base64_url_decode($env['data']); | 
					
						
							| 
									
										
										
										
											2010-02-22 09:05:32 -05:00
										 |  |  |         $signer_uri = $this->getAuthor($text); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-03-04 01:46:34 -05:00
										 |  |  |         try { | 
					
						
							|  |  |  |             $keypair = $this->getKeyPair($signer_uri); | 
					
						
							|  |  |  |         } catch (Exception $e) { | 
					
						
							|  |  |  |             common_log(LOG_DEBUG, "Salmon error: ".$e->getMessage()); | 
					
						
							|  |  |  |             return false; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2010-09-03 01:35:04 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-03-04 01:46:34 -05:00
										 |  |  |         $verifier = Magicsig::fromString($keypair); | 
					
						
							| 
									
										
										
										
											2010-02-22 09:05:32 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-03-04 01:46:34 -05:00
										 |  |  |         if (!$verifier) { | 
					
						
							|  |  |  |             common_log(LOG_DEBUG, "Salmon error: unable to parse keypair"); | 
					
						
							|  |  |  |             return false; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2010-09-03 01:35:04 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-05 23:26:09 +00:00
										 |  |  |         return $verifier->verify($this->signingText($env), $env['sig']); | 
					
						
							| 
									
										
										
										
											2010-02-22 09:05:32 -05:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-05 14:05:59 -08:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Extract envelope data from an XML document containing an <me:env> or <me:provenance> element. | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @param string XML source | 
					
						
							|  |  |  |      * @return mixed associative array of envelope data, or false on unrecognized input | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @fixme it might be easier to work with storing envelope data these in the object instead of passing arrays around | 
					
						
							|  |  |  |      * @fixme will spew errors to logs or output in case of XML parse errors | 
					
						
							|  |  |  |      * @fixme may give fatal errors if some elements are missing or invalid XML | 
					
						
							|  |  |  |      * @fixme calling DOMDocument::loadXML statically triggers warnings in strict mode | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2010-02-22 09:05:32 -05:00
										 |  |  |     public function parse($text) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $dom = DOMDocument::loadXML($text); | 
					
						
							|  |  |  |         return $this->fromDom($dom); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-05 14:05:59 -08:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Extract envelope data from an XML document containing an <me:env> or <me:provenance> element. | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @param DOMDocument $dom | 
					
						
							|  |  |  |      * @return mixed associative array of envelope data, or false on unrecognized input | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @fixme it might be easier to work with storing envelope data these in the object instead of passing arrays around | 
					
						
							|  |  |  |      * @fixme may give fatal errors if some elements are missing | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2010-02-22 09:05:32 -05:00
										 |  |  |     public function fromDom($dom) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2010-03-09 18:47:20 -05:00
										 |  |  |         $env_element = $dom->getElementsByTagNameNS(MagicEnvelope::NS, 'env')->item(0); | 
					
						
							|  |  |  |         if (!$env_element) { | 
					
						
							| 
									
										
										
										
											2010-02-22 09:05:32 -05:00
										 |  |  |             $env_element = $dom->getElementsByTagNameNS(MagicEnvelope::NS, 'provenance')->item(0); | 
					
						
							| 
									
										
										
										
											2010-03-09 18:47:20 -05:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (!$env_element) { | 
					
						
							| 
									
										
										
										
											2010-02-22 09:05:32 -05:00
										 |  |  |             return false; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $data_element = $env_element->getElementsByTagNameNS(MagicEnvelope::NS, 'data')->item(0); | 
					
						
							| 
									
										
										
										
											2010-08-07 09:48:21 -04:00
										 |  |  |         $sig_element = $env_element->getElementsByTagNameNS(MagicEnvelope::NS, 'sig')->item(0); | 
					
						
							| 
									
										
										
										
											2010-02-22 09:05:32 -05:00
										 |  |  |         return array( | 
					
						
							| 
									
										
										
										
											2010-08-07 09:48:21 -04:00
										 |  |  |             'data' => preg_replace('/\s/', '', $data_element->nodeValue), | 
					
						
							| 
									
										
										
										
											2010-02-22 09:05:32 -05:00
										 |  |  |             'data_type' => $data_element->getAttribute('type'), | 
					
						
							|  |  |  |             'encoding' => $env_element->getElementsByTagNameNS(MagicEnvelope::NS, 'encoding')->item(0)->nodeValue, | 
					
						
							|  |  |  |             'alg' => $env_element->getElementsByTagNameNS(MagicEnvelope::NS, 'alg')->item(0)->nodeValue, | 
					
						
							| 
									
										
										
										
											2010-08-07 09:48:21 -04:00
										 |  |  |             'sig' => preg_replace('/\s/', '', $sig_element->nodeValue), | 
					
						
							| 
									
										
										
										
											2010-02-22 09:05:32 -05:00
										 |  |  |         ); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2011-01-05 23:26:09 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * Variant of MagicEnvelope using the earlier signature form listed in the MagicEnvelope | 
					
						
							|  |  |  |  * spec in early 2010; this was used in StatusNet up through 0.9.6, so for backwards compatiblity | 
					
						
							|  |  |  |  * we still need to accept and sometimes send this format. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | class MagicEnvelopeCompat extends MagicEnvelope { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * StatusNet through 0.9.6 used an earlier version of the MagicEnvelope spec | 
					
						
							|  |  |  |      * which used only the input data, without the additional fields, as the plaintext | 
					
						
							|  |  |  |      * for signing. | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @param array $env | 
					
						
							|  |  |  |      * @return string | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public function signingText($env) { | 
					
						
							|  |  |  |         return $env['data']; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 |