Commit 57b7e6a9 authored by dpi's avatar dpi Committed by Joao Ventura
Browse files

Issue #3318452 by dpi, jcnventura, acbramley: Invalid keys cause silent failures/success messages

parent cf5c582c
Loading
Loading
Loading
Loading
+18 −2
Original line number Diff line number Diff line
@@ -11,6 +11,7 @@ use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Url;
use Drupal\encrypt\EncryptionProfileManagerInterface;
use Drupal\encrypt\EncryptServiceInterface;
use Drupal\encrypt\Exception\EncryptException;
use Drupal\tfa\Plugin\TfaSetupInterface;
use Drupal\tfa\Plugin\TfaValidationInterface;
use Drupal\tfa\TfaBasePlugin;
@@ -343,11 +344,21 @@ class TfaHotp extends TfaBasePlugin implements TfaValidationInterface, TfaSetupI
   *
   * @param string $seed
   *   Un-encrypted seed.
   *
   * @throws \Drupal\encrypt\Exception\EncryptException
   *   Can throw an EncryptException.
   */
  public function storeSeed($seed) {
    // Encrypt seed for storage.
    $encrypted = $this->encryptService->encrypt($seed, $this->encryptionProfile);

    // Until EncryptServiceInterface::encrypt enforces a non-empty string,
    // validate return value is a non-empty string. \base64_encode() below must
    // also only receive a string.
    if (!is_string($encrypted) || strlen($encrypted) === 0) {
      throw new EncryptException('Empty encryption value received from encryption service.');
    }

    $record = [
      $this->pluginId . '_seed' => [
        'seed' => base64_encode($encrypted),
@@ -460,9 +471,14 @@ class TfaHotp extends TfaBasePlugin implements TfaValidationInterface, TfaSetupI
   */
  public function submitSetupForm(array $form, FormStateInterface $form_state) {
    // Write seed for user.
    try {
      $this->storeSeed($this->seed);
      return TRUE;
    }
    catch (EncryptException $e) {
    }
    return FALSE;
  }

  /**
   * Get a base64 qrcode image uri of seed.
+25 −2
Original line number Diff line number Diff line
@@ -11,6 +11,7 @@ use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Url;
use Drupal\encrypt\EncryptionProfileManagerInterface;
use Drupal\encrypt\EncryptServiceInterface;
use Drupal\encrypt\Exception\EncryptException;
use Drupal\tfa\Plugin\TfaSetupInterface;
use Drupal\tfa\Plugin\TfaValidationInterface;
use Drupal\tfa\TfaBasePlugin;
@@ -92,6 +93,13 @@ class TfaTotp extends TfaBasePlugin implements TfaValidationInterface, TfaSetupI
   */
  protected $userStorage;

  /**
   * Un-encrypted seed.
   *
   * @var string
   */
  protected $seed;

  /**
   * Encryption profile.
   *
@@ -337,11 +345,21 @@ class TfaTotp extends TfaBasePlugin implements TfaValidationInterface, TfaSetupI
   *
   * @param string $seed
   *   Un-encrypted seed.
   *
   * @throws \Drupal\encrypt\Exception\EncryptException
   *   Can throw an EncryptException.
   */
  public function storeSeed($seed) {
    // Encrypt seed for storage.
    $encrypted = $this->encryptService->encrypt($seed, $this->encryptionProfile);

    // Until EncryptServiceInterface::encrypt enforces a non-empty string,
    // validate return value is a non-empty string. \base64_encode() below must
    // also only receive a string.
    if (!is_string($encrypted) || strlen($encrypted) === 0) {
      throw new EncryptException('Empty encryption value received from encryption service.');
    }

    $record = [
      $this->pluginId . '_seed' => [
        'seed' => base64_encode($encrypted),
@@ -450,9 +468,14 @@ class TfaTotp extends TfaBasePlugin implements TfaValidationInterface, TfaSetupI
   */
  public function submitSetupForm(array $form, FormStateInterface $form_state) {
    // Write seed for user.
    try {
      $this->storeSeed($this->seed);
      return TRUE;
    }
    catch (EncryptException $e) {
    }
    return FALSE;
  }

  /**
   * Get a base64 qrcode image uri of seed.
+46 −0
Original line number Diff line number Diff line
<?php

declare(strict_types=1);

namespace Drupal\tfa_test_encryption\Plugin\EncryptionMethod;

use Drupal\encrypt\EncryptionMethodInterface;
use Drupal\encrypt\Exception\EncryptException;
use Drupal\encrypt\Plugin\EncryptionMethod\EncryptionMethodBase;

/**
 * A failing test encryption method.
 *
 * @EncryptionMethod(
 *   id = \Drupal\tfa_test_encryption\Plugin\EncryptionMethod\FailingEncryption::PLUGIN_ID,
 *   title = @Translation("A failing test encryption method"),
 *   description = "A failing test encryption method.",
 *   key_type = {"encryption"}
 * )
 */
final class FailingEncryption extends EncryptionMethodBase implements EncryptionMethodInterface {

  const PLUGIN_ID = 'tfa_test_encryption_failing_encryption';

  /**
   * {@inheritdoc}
   */
  public function checkDependencies($text = NULL, $key = NULL) {
    return [];
  }

  /**
   * {@inheritdoc}
   */
  public function encrypt($text, $key, $options = []) {
    throw new EncryptException('Failed to encrypt!');
  }

  /**
   * {@inheritdoc}
   */
  public function decrypt($text, $key, $options = []) {
    throw new EncryptException('Failed to decrypt');
  }

}
+5 −0
Original line number Diff line number Diff line
name: TFA Test Encryption
type: module
package: Testing
dependencies:
  - drupal:user
+13 −1
Original line number Diff line number Diff line
@@ -9,6 +9,7 @@ use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\Core\Url;
use Drupal\encrypt\EncryptionProfileManagerInterface;
use Drupal\encrypt\EncryptServiceInterface;
use Drupal\encrypt\Exception\EncryptException;
use Drupal\tfa\Plugin\TfaSetupInterface;
use Drupal\tfa\Plugin\TfaValidationInterface;
use Drupal\tfa\TfaBasePlugin;
@@ -102,6 +103,11 @@ class TfaTestValidationPlugin extends TfaBasePlugin implements TfaValidationInte
   * {@inheritdoc}
   */
  public function getForm(array $form, FormStateInterface $form_state) {
    $form['actions']['login'] = [
      '#type' => 'submit',
      '#button_type' => 'primary',
      '#value' => $this->t('Next'),
    ];
    return $form;
  }

@@ -160,7 +166,13 @@ class TfaTestValidationPlugin extends TfaBasePlugin implements TfaValidationInte
   * {@inheritdoc}
   */
  public function submitSetupForm(array $form, FormStateInterface $form_state) {
    try {
      $encrypted = $this->encryptService->encrypt($form_state->getValue('expected_field'), $this->encryptionProfile);
    }
    catch (EncryptException $e) {
      return FALSE;
    }

    $record = [
      'test_data' => [
        'expected_field' => base64_encode($encrypted),
Loading