protected function unpackMessageUpdate(Channel $chan, array $updateData)
{
// This is the JSON message from the tree node, stored as an array:
$this->updateMessage = $updateData;
if ($this->isPackageUpdate() || $this->isAirshipUpdate()) {
// These aren't signed for updating the tree.
return;
}
// We need a precise format:
$dateGen = (new \DateTime($this->stored['date_generated']))->format(\AIRSHIP_DATE_FORMAT);
$messageToSign = ['action' => $this->action, 'date_generated' => $dateGen, 'public_key' => $updateData['public_key'], 'supplier' => $updateData['supplier'], 'type' => $updateData['type']];
try {
$this->supplier = $this->loadSupplier($chan, $updateData);
} catch (NoSupplier $ex) {
if (!$this->isNewSupplier) {
throw $ex;
}
}
// If this isn't a new supplier, we need to verify the key
if ($this->isNewSupplier) {
return;
}
if ($updateData['master'] === null) {
throw new CouldNotUpdate(\__('The master data is NULL, but the supplier exists.'));
}
$master = \json_decode($updateData['master'], true);
foreach ($this->supplier->getSigningKeys() as $supKey) {
// Yes, this is (in fact) a SignaturePublicKey:
if (IDE_HACKS) {
$supKey['key'] = new SignaturePublicKey();
}
if ($supKey['type'] !== 'master') {
continue;
}
$pub = \Sodium\bin2hex($supKey['key']->getRawKeyMaterial());
// Is this the key we're looking for?
if (\hash_equals($pub, $master['public_key'])) {
// Store the public key
$this->supplierMasterKeyUsed = $supKey['key'];
break;
}
}
if (empty($this->supplierMasterKeyUsed)) {
throw new CouldNotUpdate(\__('The provided public key does not match any known master key.'));
}
$encoded = \json_encode($messageToSign);
if (!Asymmetric::verify($encoded, $this->supplierMasterKeyUsed, $master['signature'])) {
throw new CouldNotUpdate(\__('Invalid signature for this master key.'));
}
}