X-Git-Url: https://vcs.fsf.org/?a=blobdiff_plain;f=Civi%2FCrypto%2FCryptoToken.php;h=afe415d844f85b62315ef5cc5de36c775d5e9aa8;hb=bc2fb7e2c940f9d9102aa9464e88fd0190793679;hp=2a478fd7ce4ef715962569f5b885ae1f47c91293;hpb=1c49241914553c5a4e6ca0584197864a83ae5559;p=civicrm-core.git diff --git a/Civi/Crypto/CryptoToken.php b/Civi/Crypto/CryptoToken.php index 2a478fd7ce..afe415d844 100644 --- a/Civi/Crypto/CryptoToken.php +++ b/Civi/Crypto/CryptoToken.php @@ -55,11 +55,19 @@ class CryptoToken { */ protected $delim; + /** + * @var \Civi\Crypto\CryptoRegistry|null + */ + private $registry; + /** * CryptoToken constructor. + * + * @param CryptoRegistry $registry */ - public function __construct() { + public function __construct($registry = NULL) { $this->delim = chr(2); + $this->registry = $registry; } /** @@ -69,7 +77,7 @@ class CryptoToken { * @return bool */ public function isPlainText($plainText) { - return is_string($plainText) && ($plainText === '' || $plainText{0} !== $this->delim); + return is_string($plainText) && ($plainText === '' || $plainText[0] !== $this->delim); } /** @@ -85,7 +93,7 @@ class CryptoToken { */ public function encrypt($plainText, $keyIdOrTag) { /** @var CryptoRegistry $registry */ - $registry = \Civi::service('crypto.registry'); + $registry = $this->getRegistry(); $key = $registry->findKey($keyIdOrTag); if ($key['suite'] === 'plain') { @@ -128,7 +136,7 @@ class CryptoToken { } /** @var CryptoRegistry $registry */ - $registry = \Civi::service('crypto.registry'); + $registry = $this->getRegistry(); $tokenData = $this->parse($token); @@ -143,6 +151,40 @@ class CryptoToken { return $plainText; } + /** + * Re-encrypt an existing token with a newer version of the key. + * + * @param string $oldToken + * @param string $keyTag + * Ex: 'CRED' + * + * @return string|null + * A re-encrypted version of $oldToken, or NULL if there should be no change. + * @throws \Civi\Crypto\Exception\CryptoException + */ + public function rekey($oldToken, $keyTag) { + /** @var \Civi\Crypto\CryptoRegistry $registry */ + $registry = $this->getRegistry(); + + $sourceKeys = $registry->findKeysByTag($keyTag); + $targetKey = array_shift($sourceKeys); + + if ($this->isPlainText($oldToken)) { + if ($targetKey['suite'] === 'plain') { + return NULL; + } + } + else { + $tokenData = $this->parse($oldToken); + if ($tokenData['k'] === $targetKey['id'] || !isset($sourceKeys[$tokenData['k']])) { + return NULL; + } + } + + $decrypted = $this->decrypt($oldToken); + return $this->encrypt($decrypted, $targetKey['id']); + } + /** * Parse the content of a token (without decrypting it). * @@ -166,4 +208,14 @@ class CryptoToken { return $tokenData; } + /** + * @return CryptoRegistry + */ + protected function getRegistry(): CryptoRegistry { + if ($this->registry === NULL) { + $this->registry = \Civi::service('crypto.registry'); + } + return $this->registry; + } + }