Ejemplo n.º 1
0
 /**
  * @param array|string $formats
  * @param string $blob
  * @return Message
  * @throws InvalidMessageException
  */
 public function decode($formats, $blob)
 {
     $formats = (array) $formats;
     $prefixLen = 0;
     foreach ($formats as $format) {
         $prefixLen = max($prefixLen, strlen($format));
     }
     list($prefix) = explode(Constants::PROTOCOL_DELIM, substr($blob, 0, $prefixLen + 1));
     if (!in_array($prefix, $formats)) {
         if (in_array(GarbledMessage::NAME, $formats)) {
             return GarbledMessage::decode($blob);
         } else {
             throw new InvalidMessageException("Unexpected message type.");
         }
     }
     switch ($prefix) {
         case StdMessage::NAME:
             return StdMessage::decode($this->cxnStore, $blob);
         case InsecureMessage::NAME:
             return InsecureMessage::decode($blob);
         case RegistrationMessage::NAME:
             return RegistrationMessage::decode($this->appStore, $blob);
         case AppMetasMessage::NAME:
             return AppMetasMessage::decode($this->certValidator, $blob);
         default:
             throw new InvalidMessageException("Unrecognized message type.");
     }
 }
Ejemplo n.º 2
0
 /**
  * @param AppStoreInterface $appStore
  * @param string $blob
  * @return array
  *   Decoded data.
  */
 public static function decode($appStore, $blob)
 {
     $parts = explode(Constants::PROTOCOL_DELIM, $blob, 5);
     if (count($parts) != 5) {
         throw new InvalidMessageException('Invalid message: insufficient parameters');
     }
     list($wireProt, $wireAppId, $rsaCiphertextB64, $signature, $body) = $parts;
     if ($wireProt !== self::NAME) {
         throw new InvalidMessageException('Invalid message: wrong protocol name');
     }
     $appPrivKey = $appStore->getPrivateKey($wireAppId);
     if (!$appPrivKey) {
         throw new InvalidMessageException('Received message intended for unknown app.');
     }
     $rsaCiphertext = base64_decode($rsaCiphertextB64);
     if (strlen($rsaCiphertext) !== Constants::RSA_MSG_BYTES) {
         throw new InvalidMessageException("RSA ciphertext has incorrect length");
     }
     $secret = UserError::adapt('Civi\\Cxn\\Rpc\\Exception\\InvalidMessageException', function () use($rsaCiphertext, $appPrivKey) {
         return RegistrationMessage::getRsa($appPrivKey, 'private')->decrypt($rsaCiphertext);
     });
     if (empty($secret)) {
         throw new InvalidMessageException("Invalid message: decryption produced empty secret");
     }
     $plaintext = AesHelper::authenticateThenDecrypt($secret, $body, $signature);
     return json_decode($plaintext, TRUE);
 }
Ejemplo n.º 3
0
 public function decode($formats, $message)
 {
     $prefixLen = 0;
     foreach ($formats as $format) {
         $prefixLen = max($prefixLen, strlen($format));
     }
     list($prefix) = explode(Constants::PROTOCOL_DELIM, substr($message, 0, $prefixLen + 1));
     if (!in_array($prefix, $formats)) {
         throw new InvalidMessageException("Unexpected message type.");
     }
     switch ($prefix) {
         case StdMessage::NAME:
             return StdMessage::decode($this->cxnStore, $message);
         case InsecureMessage::NAME:
             return InsecureMessage::decode($message);
         case RegistrationMessage::NAME:
             return RegistrationMessage::decode($this->appId, $this->appPrivKey, $message);
         default:
             throw new InvalidMessageException("Unrecognized message type");
     }
 }
Ejemplo n.º 4
0
 /**
  * @param $appMeta
  * @param $entity
  * @param $action
  * @param $params
  * @param $cxn
  * @return array
  * @throws Exception\InvalidMessageException
  */
 protected function doCall($appMeta, $entity, $action, $params, $cxn)
 {
     $appCert = new \File_X509();
     $appCert->loadX509($appMeta['appCert']);
     $req = new RegistrationMessage($cxn['appId'], $appCert->getPublicKey(), array('cxn' => $cxn, 'entity' => $entity, 'action' => $action, 'params' => $params));
     list($respHeaders, $respCiphertext, $respCode) = $this->http->send('POST', $cxn['appUrl'], $req->encode());
     $respMessage = $this->decode(array(StdMessage::NAME, InsecureMessage::NAME, GarbledMessage::NAME), $respCiphertext);
     if ($respMessage instanceof GarbledMessage) {
         return array($respCode, array('is_error' => 1, 'error_message' => 'Received garbled message', 'original_message' => $respMessage->getData()));
     } elseif ($respMessage instanceof InsecureMessage) {
         return array($respCode, array('is_error' => 1, 'error_message' => 'Received insecure error message', 'original_message' => $respMessage->getData()));
     }
     if ($respMessage->getCxnId() != $cxn['cxnId']) {
         // Tsk, tsk, Mallory!
         throw new \RuntimeException('Received response from incorrect connection.');
     }
     return array($respCode, $respMessage->getData());
 }