Skip to content

feat: implement new TPM encryption key flow with PIN support #1082

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions apps/ubuntu_bootstrap/integration_test/screenshot_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,37 @@ Future<void> main() async {
variant: themeVariant,
);

testWidgets(
'passphrase type',
(tester) async {
await tester.runApp(
() => runInstallerApp(
[
'--dry-run-config=examples/dry-run-configs/tpm.yaml',
],
theme: currentTheme,
),
);
await tester.pumpAndSettle();

await tester.jumpToStorageWizard();
await tester.pumpAndSettle();

await tester.testStoragePage(
type: StorageType.erase,
);

await tester.testGuidedCapabilityPage(
guidedCapability: GuidedCapability.CORE_BOOT_ENCRYPTED,
);

await tester.testPassphraseTypePage(
screenshot: '$currentThemeName/passphrase-type',
);
},
variant: themeVariant,
);

testWidgets(
'passphrase',
(tester) async {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -316,7 +316,7 @@ void main() {
guidedCapability: GuidedCapability.CORE_BOOT_ENCRYPTED,
);

await tester.testPassphrasePage(passphrase: '', skip: true);
await tester.testPassphraseTypePage();

await tester.testIdentityPage(identity: identity, password: 'password');
await expectIdentity(identity);
Expand Down Expand Up @@ -370,6 +370,9 @@ void main() {
guidedCapability: GuidedCapability.CORE_BOOT_ENCRYPTED,
);

await tester.testPassphraseTypePage(
passphraseType: PassphraseType.passphrase,
);
await tester.testPassphrasePage(passphrase: 'passphrase');

await tester.testIdentityPage(identity: identity, password: 'password');
Expand All @@ -391,6 +394,66 @@ void main() {
);
});

testWidgets('tpm with pin', (tester) async {
const identity = Identity(
realname: 'User',
hostname: 'ubuntu',
username: 'user',
);

await tester.runApp(
() => app.main([
'--source-catalog=examples/sources/tpm.yaml',
'--dry-run-config=examples/dry-run-configs/tpm.yaml',
'--',
'--bootloader=uefi',
]),
);

await tester.pumpAndSettle();
await tester.testLocalePage();
await tester.testAccessibilityPage();
await tester.testKeyboardPage();
await tester.testNetworkPage(mode: ConnectMode.none);
await tester.testRefreshPage();
await tester.testAutoinstallPage();
await tester.testSourceSelectionPage();
await tester.testCodecsAndDriversPage();

await tester.testStoragePage(
type: StorageType.erase,
);
await tester.testGuidedCapabilityPage(
guidedCapability: GuidedCapability.CORE_BOOT_ENCRYPTED,
);

await tester.testPassphraseTypePage(
passphraseType: PassphraseType.pin,
);
await tester.testPassphrasePage(
passphrase: '12345',
passphraseType: PassphraseType.pin,
);

await tester.testIdentityPage(identity: identity, password: 'password');
await expectIdentity(identity);

await tester.testTimezonePage();
await tester.testConfirmPage();
await tester.testInstallPage();
await tester.testRecoveryKeyPage();
await tester.testDonePage();

final windowClosed = YaruTestWindow.waitForClosed();
await tester.tapContinueTesting();
await expectLater(windowClosed, completes);

await verifySubiquityConfig(
identity: identity,
capability: GuidedCapability.CORE_BOOT_ENCRYPTED,
);
});

testWidgets('manual partitioning', (tester) async {
final storage = [
fakeDisk(
Expand Down
36 changes: 24 additions & 12 deletions apps/ubuntu_bootstrap/lib/l10n/ubuntu_bootstrap_en.arb
Original file line number Diff line number Diff line change
Expand Up @@ -171,21 +171,33 @@
"installCodecsSubtitle": "Including but not limited to MP3, MP4, MOV and similar",
"batteryWarning": "The computer is not plugged in to a power source.",
"offlineWarning": "You are currently offline",
"choosePassphraseTitle": "Disk passphrase",
"choosePassphraseHeader": "Create a passphrase",
"choosePassphraseBody": "You need a passphrase to encrypt your files. You will be prompted for your passphrase every time you turn on your computer.",
"choosePassphraseHint": "Choose a passphrase",
"choosePassphraseConfirmHint": "Confirm the passphrase",
"choosePassphraseRequired": "A passphrase is required",
"choosePassphraseMismatch": "The passphrases do not match",
"choosePassphraseInfoHeader": "Store your passphrase somewhere safe",
"choosePassphraseInfoBody": "If you lose your passphrase, you will lose all your data.",
"chooseOptionalPassphraseHeader": "Create a passphrase (optional)",
"chooseOptionalPassphraseBody": "A passphrase can help protect your data even if your hardware gets compromised. You will need to enter the passphrase every time you turn on your computer. You will not be able to remove it later",
"choosePassphraseBody": "You will need to enter your passphrase every time you turn on your computer. This passphrase is different from your user password.",
"choosePassphraseInfoHeader": "Make sure to save your passphrase",
"choosePassphraseInfoBody": "If you lose it, you will lose all your data.",
"chooseOptionalPassphraseInfoHeader": "Store your passphrase and recovery key somewhere safe",
"chooseOptionalPassphraseInfoBody": "If you lose your passphrase, you will lose all your data. The passphrase does not replace the recovery key or your user password.",
"createPassphrase": "Create a passphrase",
"confirmPassphrase": "Confirm the passphrase",
"passphrasePageTitle": "Encryption",
"passphrasePageHeaderPassphrase": "Create an encryption passphrase",
"passphrasePageHeaderPin": "Create an encryption PIN",
"passphrasePageBodyPassphrase": "You will need to enter your passphrase every time you turn on your computer. This passphrase is different from your user password. You will be able to change it later, but not disable it. If you forget your passphrase, you can regain access to your disk by using your recovery key.",
"passphrasePageBodyPin": "You will need to enter your PIN every time you turn on your computer. This PIN is different from your user password. You will be able to change it later, but not disable it. If you forget your PIN, you can regain access to your disk by using your recovery key.",
"passphrasePageChoosePassphraseHint": "Choose a passphrase",
"passphrasePageConfirmPassphraseHint": "Confirm passphrase",
"passphrasePageRequiredPassphrase": "A passphrase is required",
"passphrasePageMismatchPassphrase": "The passphrases do not match",
"passphrasePageChoosePinHint": "Choose a PIN",
"passphrasePageConfirmPinHint": "Confirm PIN",
"passphrasePageRequiredPin": "A PIN is required",
"passphrasePageMismatchPin": "The PINs do not match",
"passphraseTypePassphraseTileTitle": "Require a passphrase",
"passphraseTypePassphraseTileSubTitle": "Most secure. You will need to enter a passphrase every time you turn on your computer.",
"passphraseTypePinTileTitle": "Require a PIN",
"passphraseTypePinTileSubTitle": "More secure. You will need to enter a numeric PIN every time you turn on your computer.",
"passphraseTypeNoneTileTitle": "Unlock disk automatically",
"passphraseTypeNoneTileSubTitle": "Most convenient. Make sure not to enable automatic login for any user.",
"passphraseTypePageHeader": "Add an encryption PIN or passphrase",
"passphraseTypePageBody": "By default, your computer’s Trusted Platform Module (TPM) unlocks your disk when you start Ubuntu. However, you can also require a PIN or a passphrase to further protect your data. You will be able to change your PIN or passphrase later, but not disable them.",
"installationTypeTitle": "Disk setup",
"installationTypeHeader": "How do you want to install {DISTRO}?",
"@installationTypeHeader": {
Expand Down
152 changes: 112 additions & 40 deletions apps/ubuntu_bootstrap/lib/l10n/ubuntu_bootstrap_localizations.dart
Original file line number Diff line number Diff line change
Expand Up @@ -719,12 +719,6 @@ abstract class UbuntuBootstrapLocalizations {
/// **'You are currently offline'**
String get offlineWarning;

/// No description provided for @choosePassphraseTitle.
///
/// In en, this message translates to:
/// **'Disk passphrase'**
String get choosePassphraseTitle;

/// No description provided for @choosePassphraseHeader.
///
/// In en, this message translates to:
Expand All @@ -734,80 +728,158 @@ abstract class UbuntuBootstrapLocalizations {
/// No description provided for @choosePassphraseBody.
///
/// In en, this message translates to:
/// **'You need a passphrase to encrypt your files. You will be prompted for your passphrase every time you turn on your computer.'**
/// **'You will need to enter your passphrase every time you turn on your computer. This passphrase is different from your user password.'**
String get choosePassphraseBody;

/// No description provided for @choosePassphraseHint.
/// No description provided for @choosePassphraseInfoHeader.
///
/// In en, this message translates to:
/// **'Make sure to save your passphrase'**
String get choosePassphraseInfoHeader;

/// No description provided for @choosePassphraseInfoBody.
///
/// In en, this message translates to:
/// **'If you lose it, you will lose all your data.'**
String get choosePassphraseInfoBody;

/// No description provided for @chooseOptionalPassphraseInfoHeader.
///
/// In en, this message translates to:
/// **'Store your passphrase and recovery key somewhere safe'**
String get chooseOptionalPassphraseInfoHeader;

/// No description provided for @chooseOptionalPassphraseInfoBody.
///
/// In en, this message translates to:
/// **'If you lose your passphrase, you will lose all your data. The passphrase does not replace the recovery key or your user password.'**
String get chooseOptionalPassphraseInfoBody;

/// No description provided for @passphrasePageTitle.
///
/// In en, this message translates to:
/// **'Encryption'**
String get passphrasePageTitle;

/// No description provided for @passphrasePageHeaderPassphrase.
///
/// In en, this message translates to:
/// **'Create an encryption passphrase'**
String get passphrasePageHeaderPassphrase;

/// No description provided for @passphrasePageHeaderPin.
///
/// In en, this message translates to:
/// **'Create an encryption PIN'**
String get passphrasePageHeaderPin;

/// No description provided for @passphrasePageBodyPassphrase.
///
/// In en, this message translates to:
/// **'You will need to enter your passphrase every time you turn on your computer. This passphrase is different from your user password. You will be able to change it later, but not disable it. If you forget your passphrase, you can regain access to your disk by using your recovery key.'**
String get passphrasePageBodyPassphrase;

/// No description provided for @passphrasePageBodyPin.
///
/// In en, this message translates to:
/// **'You will need to enter your PIN every time you turn on your computer. This PIN is different from your user password. You will be able to change it later, but not disable it. If you forget your PIN, you can regain access to your disk by using your recovery key.'**
String get passphrasePageBodyPin;

/// No description provided for @passphrasePageChoosePassphraseHint.
///
/// In en, this message translates to:
/// **'Choose a passphrase'**
String get choosePassphraseHint;
String get passphrasePageChoosePassphraseHint;

/// No description provided for @choosePassphraseConfirmHint.
/// No description provided for @passphrasePageConfirmPassphraseHint.
///
/// In en, this message translates to:
/// **'Confirm the passphrase'**
String get choosePassphraseConfirmHint;
/// **'Confirm passphrase'**
String get passphrasePageConfirmPassphraseHint;

/// No description provided for @choosePassphraseRequired.
/// No description provided for @passphrasePageRequiredPassphrase.
///
/// In en, this message translates to:
/// **'A passphrase is required'**
String get choosePassphraseRequired;
String get passphrasePageRequiredPassphrase;

/// No description provided for @choosePassphraseMismatch.
/// No description provided for @passphrasePageMismatchPassphrase.
///
/// In en, this message translates to:
/// **'The passphrases do not match'**
String get choosePassphraseMismatch;
String get passphrasePageMismatchPassphrase;

/// No description provided for @choosePassphraseInfoHeader.
/// No description provided for @passphrasePageChoosePinHint.
///
/// In en, this message translates to:
/// **'Store your passphrase somewhere safe'**
String get choosePassphraseInfoHeader;
/// **'Choose a PIN'**
String get passphrasePageChoosePinHint;

/// No description provided for @choosePassphraseInfoBody.
/// No description provided for @passphrasePageConfirmPinHint.
///
/// In en, this message translates to:
/// **'If you lose your passphrase, you will lose all your data.'**
String get choosePassphraseInfoBody;
/// **'Confirm PIN'**
String get passphrasePageConfirmPinHint;

/// No description provided for @chooseOptionalPassphraseHeader.
/// No description provided for @passphrasePageRequiredPin.
///
/// In en, this message translates to:
/// **'Create a passphrase (optional)'**
String get chooseOptionalPassphraseHeader;
/// **'A PIN is required'**
String get passphrasePageRequiredPin;

/// No description provided for @chooseOptionalPassphraseBody.
/// No description provided for @passphrasePageMismatchPin.
///
/// In en, this message translates to:
/// **'A passphrase can help protect your data even if your hardware gets compromised. You will need to enter the passphrase every time you turn on your computer. You will not be able to remove it later'**
String get chooseOptionalPassphraseBody;
/// **'The PINs do not match'**
String get passphrasePageMismatchPin;

/// No description provided for @chooseOptionalPassphraseInfoHeader.
/// No description provided for @passphraseTypePassphraseTileTitle.
///
/// In en, this message translates to:
/// **'Store your passphrase and recovery key somewhere safe'**
String get chooseOptionalPassphraseInfoHeader;
/// **'Require a passphrase'**
String get passphraseTypePassphraseTileTitle;

/// No description provided for @chooseOptionalPassphraseInfoBody.
/// No description provided for @passphraseTypePassphraseTileSubTitle.
///
/// In en, this message translates to:
/// **'If you lose your passphrase, you will lose all your data. The passphrase does not replace the recovery key or your user password.'**
String get chooseOptionalPassphraseInfoBody;
/// **'Most secure. You will need to enter a passphrase every time you turn on your computer.'**
String get passphraseTypePassphraseTileSubTitle;

/// No description provided for @createPassphrase.
/// No description provided for @passphraseTypePinTileTitle.
///
/// In en, this message translates to:
/// **'Create a passphrase'**
String get createPassphrase;
/// **'Require a PIN'**
String get passphraseTypePinTileTitle;

/// No description provided for @passphraseTypePinTileSubTitle.
///
/// In en, this message translates to:
/// **'More secure. You will need to enter a numeric PIN every time you turn on your computer.'**
String get passphraseTypePinTileSubTitle;

/// No description provided for @passphraseTypeNoneTileTitle.
///
/// In en, this message translates to:
/// **'Unlock disk automatically'**
String get passphraseTypeNoneTileTitle;

/// No description provided for @passphraseTypeNoneTileSubTitle.
///
/// In en, this message translates to:
/// **'Most convenient. Make sure not to enable automatic login for any user.'**
String get passphraseTypeNoneTileSubTitle;

/// No description provided for @passphraseTypePageHeader.
///
/// In en, this message translates to:
/// **'Add an encryption PIN or passphrase'**
String get passphraseTypePageHeader;

/// No description provided for @confirmPassphrase.
/// No description provided for @passphraseTypePageBody.
///
/// In en, this message translates to:
/// **'Confirm the passphrase'**
String get confirmPassphrase;
/// **'By default, your computer’s Trusted Platform Module (TPM) unlocks your disk when you start Ubuntu. However, you can also require a PIN or a passphrase to further protect your data. You will be able to change your PIN or passphrase later, but not disable them.'**
String get passphraseTypePageBody;

/// No description provided for @installationTypeTitle.
///
Expand Down
Loading
Loading