Skip to content
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
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
117 changes: 117 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions e2e/assets/ed25519/identity.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
-----BEGIN PRIVATE KEY-----
MFMCAQEwBQYDK2VwBCIEIODVjQrIvbt3PO3FPDKCZs2FarAbsRrLuiQZ+NBslV9U
oSMDIQDVkl2stdaeyBDvfb0t4qy9vhsv6xLl1v7p7i0NO1+9pw==
-----END PRIVATE KEY-----
8 changes: 4 additions & 4 deletions e2e/tests-dfx/secp256k1.bash → e2e/tests-dfx/ed25519.bash
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ teardown() {
standard_teardown
}

@test "can call a canister using a secp256k1 identity" {
openssl ecparam -name secp256k1 -genkey -out identity.pem
assert_command dfx identity import --disable-encryption secp256k1 identity.pem
@test "can call a canister using an ed25519 identity" {
install_asset ed25519
assert_command dfx identity import --disable-encryption ed25519 identity.pem
dfx_new # This installs replica and other binaries
dfx identity use secp256k1
dfx identity use ed25519
Comment thread
adamspofford-dfinity marked this conversation as resolved.
install_asset whoami
dfx_start
dfx canister create whoami
Expand Down
27 changes: 19 additions & 8 deletions e2e/tests-dfx/identity_command.bash
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ frank'
assert_command dfx identity new --disable-encryption alice
assert_match 'Created identity: "alice".' "$stderr"
assert_command head "$DFX_CONFIG_ROOT/.config/dfx/identity/alice/identity.pem"
assert_match "BEGIN PRIVATE KEY"
assert_match "BEGIN EC PRIVATE KEY"

# does not change the default identity
assert_command dfx identity whoami
Expand Down Expand Up @@ -129,7 +129,7 @@ frank'
assert_command dfx identity new --disable-encryption alice

assert_command head "$DFX_CONFIG_ROOT/.config/dfx/identity/alice/identity.pem"
assert_match "BEGIN PRIVATE KEY"
assert_match "BEGIN EC PRIVATE KEY"
assert_command dfx identity list
assert_match \
'alice
Expand Down Expand Up @@ -168,7 +168,7 @@ default'
assert_command_fail dfx identity remove alice

assert_command head "$DFX_CONFIG_ROOT/.config/dfx/identity/alice/identity.pem"
assert_match "BEGIN PRIVATE KEY"
assert_match "BEGIN EC PRIVATE KEY"
assert_command dfx identity list
assert_match \
'alice
Expand Down Expand Up @@ -211,7 +211,7 @@ default'
anonymous
default'
assert_command head "$DFX_CONFIG_ROOT/.config/dfx/identity/alice/identity.pem"
assert_match "BEGIN PRIVATE KEY"
assert_match "BEGIN EC PRIVATE KEY"
x=$(cat "$DFX_CONFIG_ROOT/.config/dfx/identity/alice/identity.pem")
local key="$x"

Expand All @@ -225,7 +225,7 @@ bob
default'
assert_command cat "$DFX_CONFIG_ROOT/.config/dfx/identity/bob/identity.pem"
assert_eq "$key" "$(cat "$DFX_CONFIG_ROOT/.config/dfx/identity/bob/identity.pem")"
assert_match "BEGIN PRIVATE KEY"
assert_match "BEGIN EC PRIVATE KEY"
assert_command_fail cat "$DFX_CONFIG_ROOT/.config/dfx/identity/alice/identity.pem"
}

Expand All @@ -236,7 +236,7 @@ default'
assert_command dfx identity list
assert_match 'bob'
assert_command head "$DFX_CONFIG_ROOT/.config/dfx/identity/bob/identity.pem"
assert_match "BEGIN PRIVATE KEY"
assert_match "BEGIN EC PRIVATE KEY"

assert_command dfx identity whoami
assert_eq 'bob'
Expand All @@ -262,7 +262,7 @@ default'
assert_eq 'charlie'

assert_command head "$DFX_CONFIG_ROOT/.config/dfx/identity/charlie/identity.pem"
assert_match "BEGIN PRIVATE KEY"
assert_match "BEGIN EC PRIVATE KEY"
assert_command_fail cat "$DFX_CONFIG_ROOT/.config/dfx/identity/alice/identity.pem"
}

Expand Down Expand Up @@ -427,7 +427,7 @@ default'
echo -n 1 >> bob.pem
tail -n 3 alice.pem > bob.pem
assert_command_fail dfx identity import --disable-encryption bob bob.pem
assert_match 'Invalid Ed25519 private key in PEM file' "$stderr"
assert_match 'Failed to validate PEM content' "$stderr"
}

@test "identity: can import an EC key without an EC PARAMETERS section (as quill generate makes)" {
Expand All @@ -452,3 +452,14 @@ XXX
assert_file_exists export.pem
assert_command dfx identity import --disable-encryption bob export.pem
}

@test "identity: can import a seed phrase" {
reg="seed phrase for identity 'alice': ([a-z ]+)"
assert_command dfx identity new --disable-encryption alice
[[ $stderr =~ $reg ]]
echo "${BASH_REMATCH[1]}" >seed.txt
principal=$(dfx identity get-principal --identity alice)
assert_command dfx identity import alice2 --seed-file seed.txt --disable-encryption
assert_command dfx identity get-principal --identity alice2
assert_eq "$principal"
Comment thread
adamspofford-dfinity marked this conversation as resolved.
}
3 changes: 3 additions & 0 deletions src/dfx/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ anyhow = "1.0.56"
argon2 = "0.4.0"
atty = "0.2.13"
base64 = "0.13.0"
bip32 = "0.4.0"
byte-unit = { version = "4.0.14", features = ["serde"] }
candid = { version = "0.7.15", features = [ "random" ] }
clap = { version = "3.1.6", features = [ "derive" ] }
Expand All @@ -44,6 +45,7 @@ ic-asset = { version = "0.20.0", path = "../canisters/frontend/ic-asset" }
ic-wasm = { version = "0.1.3", default-features = false, features = ["optimize"]}
indicatif = "0.16.0"
itertools = "0.10.3"
k256 = { version = "0.11.4", features = ["pem"] }
lazy_static = "1.4.0"
mime = "0.3.16"
mime_guess = "2.0.4"
Expand Down Expand Up @@ -74,6 +76,7 @@ tempfile = "3.3.0"
term = "0.7.0"
thiserror = "1.0.20"
time = { version = "0.3.9", features = ["serde", "macros", "serde-human-readable"] }
tiny-bip39 = "1.0.0"
tokio = { version = "1.17.0", features = [ "fs" ] }
url = "2.1.0"
walkdir = "2.2.9"
Expand Down
23 changes: 19 additions & 4 deletions src/dfx/src/commands/identity/import.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@ use crate::lib::environment::Environment;
use crate::lib::error::DfxResult;
use crate::lib::identity::identity_manager::{IdentityCreationParameters, IdentityManager};

use anyhow::Context;
use clap::Parser;
use slog::info;
use std::fs;
use std::path::PathBuf;

/// Creates a new identity from a PEM file.
Expand All @@ -13,7 +15,11 @@ pub struct ImportOpts {
new_identity: String,

/// The PEM file to import.
pem_file: PathBuf,
pem_file: Option<PathBuf>,

/// The path to a file with your seed phrase.
#[clap(long, conflicts_with("pem-file"), required_unless_present("pem-file"))]
seed_file: Option<PathBuf>,

/// DANGEROUS: By default, PEM files are encrypted with a password when writing them to disk.
/// If you want the convenience of not having to type your password (but at the risk of having your PEM file compromised), you can disable the encryption.
Expand All @@ -29,9 +35,18 @@ pub struct ImportOpts {
pub fn exec(env: &dyn Environment, opts: ImportOpts) -> DfxResult {
let log = env.get_logger();
let name = opts.new_identity.as_str();
let params = IdentityCreationParameters::PemFile {
src_pem_file: opts.pem_file,
disable_encryption: opts.disable_encryption,
let params = if let Some(src_pem_file) = opts.pem_file {
IdentityCreationParameters::PemFile {
src_pem_file,
disable_encryption: opts.disable_encryption,
}
} else {
let mnemonic =
fs::read_to_string(opts.seed_file.unwrap()).context("Failed to read seed file")?;
IdentityCreationParameters::SeedPhrase {
mnemonic,
disable_encryption: opts.disable_encryption,
}
};
IdentityManager::new(env)?.create_new_identity(name, params, opts.force)?;
info!(log, r#"Imported identity: "{}"."#, name);
Expand Down
Loading