Skip to main content

dfx_core/error/
identity.rs

1use crate::error::config::GetSharedWalletConfigPathError;
2use crate::error::fs::{
3    ReadFileError, ReadPermissionsError, RemoveDirectoryAndContentsError, RemoveDirectoryError,
4    RemoveFileError, RenameError, SetPermissionsError, WriteFileError,
5};
6use crate::error::keyring::KeyringMaintenanceError;
7use crate::error::{
8    config::ConfigError,
9    encryption::EncryptionError,
10    fs::{CopyFileError, CreateDirAllError, EnsureParentDirExistsError, NoParentPathError},
11    get_user_home::GetUserHomeError,
12    keyring::KeyringError,
13    structured_file::StructuredFileError,
14    wallet_config::{SaveWalletConfigError, WalletConfigError},
15};
16use candid::types::principal::PrincipalError;
17use ic_agent::identity::PemError;
18use ic_identity_hsm::HardwareIdentityError;
19use std::path::PathBuf;
20use std::string::FromUtf8Error;
21use thiserror::Error;
22
23#[derive(Error, Debug)]
24pub enum CallSenderFromWalletError {
25    #[error("Failed to read principal from id '{0}', and did not find a wallet for that identity")]
26    ParsePrincipalFromIdFailedAndNoWallet(String, #[source] PrincipalError),
27
28    #[error(
29        "Failed to read principal from id '{0}' ({1}), and failed to load the wallet for that identity"
30    )]
31    ParsePrincipalFromIdFailedAndGetWalletCanisterIdFailed(
32        String,
33        PrincipalError,
34        #[source] WalletConfigError,
35    ),
36}
37
38#[derive(Error, Debug)]
39pub enum ConvertMnemonicToKeyError {
40    #[error("Failed to derive extended secret key from path")]
41    DeriveExtendedKeyFromPathFailed(#[source] bip32::Error),
42}
43
44#[derive(Error, Debug)]
45pub enum CreateIdentityConfigError {
46    #[error("Failed to generate a fresh encryption configuration")]
47    GenerateFreshEncryptionConfigurationFailed(#[source] EncryptionError),
48
49    #[error("Failed to check for keyring availability")]
50    KeyringAvailabilityCheckFailed(#[source] KeyringMaintenanceError),
51}
52
53#[derive(Error, Debug)]
54pub enum CreateNewIdentityError {
55    #[error("Cannot create an anonymous identity.")]
56    CannotCreateAnonymousIdentity(),
57
58    #[error("Failed to clean up previous creation attempts")]
59    CleanupPreviousCreationAttemptsFailed(#[from] RemoveDirectoryAndContentsError),
60
61    #[error("Failed to create identity config")]
62    ConvertMnemonicToKeyFailed(#[source] ConvertMnemonicToKeyError),
63
64    #[error("Convert secret key to sec1 Pem failed")]
65    ConvertSecretKeyToSec1PemFailed(#[source] Box<sec1::Error>),
66
67    #[error("Failed to create identity config")]
68    CreateIdentityConfigFailed(#[source] CreateIdentityConfigError),
69
70    #[error("Failed to create mnemonic from phrase: {0}")]
71    CreateMnemonicFromPhraseFailed(String),
72
73    #[error("failed to create temporary identity directory")]
74    CreateTemporaryIdentityDirectoryFailed(#[source] CreateDirAllError),
75
76    #[error("Failed to generate key")]
77    GenerateKeyFailed(#[source] GenerateKeyError),
78
79    #[error("Identity already exists.")]
80    IdentityAlreadyExists(),
81
82    #[error("Failed to load pem file")]
83    LoadPemFromFileFailed(#[source] LoadPemFromFileError),
84
85    #[error("Failed to remove identity")]
86    RemoveIdentityFailed(#[source] RemoveIdentityError),
87
88    #[error("Failed to rename temporary directory to permanent identity directory")]
89    RenameTemporaryIdentityDirectoryFailed(#[from] RenameError),
90
91    #[error("Failed to save identity configuration")]
92    SaveIdentityConfigurationFailed(#[source] SaveIdentityConfigurationError),
93
94    #[error("Failed to save pem")]
95    SavePemFailed(#[source] SavePemError),
96
97    #[error("Failed to switch back over to the identity you're replacing")]
98    SwitchBackToIdentityFailed(#[source] UseIdentityByNameError),
99
100    #[error("Failed to temporarily switch over to anonymous identity")]
101    SwitchToAnonymousIdentityFailed(#[source] UseIdentityByNameError),
102
103    #[error("Failed to validate pem file")]
104    ValidatePemFileFailed(#[source] ValidatePemFileError),
105}
106
107#[derive(Error, Debug)]
108pub enum ExportIdentityError {
109    #[error("Failed to get identity config")]
110    GetIdentityConfigFailed(#[source] GetIdentityConfigOrDefaultError),
111
112    #[error("The specified identity does not exist")]
113    IdentityDoesNotExist(#[source] RequireIdentityExistsError),
114
115    #[error("Failed to load pem file")]
116    LoadPemFailed(#[source] LoadPemError),
117
118    #[error("Could not translate pem file to text")]
119    TranslatePemContentToTextFailed(#[source] FromUtf8Error),
120
121    #[error("Failed to validate pem file")]
122    ValidatePemFileFailed(#[source] ValidatePemFileError),
123}
124
125#[derive(Error, Debug)]
126pub enum GenerateKeyError {
127    #[error("Failed to convert mnemonic to key")]
128    ConvertMnemonicToKeyFailed(#[source] ConvertMnemonicToKeyError),
129
130    #[error("Failed to generate a fresh secp256k1 key")]
131    GenerateFreshSecp256k1KeyFailed(#[source] Box<sec1::Error>),
132}
133
134#[derive(Error, Debug)]
135pub enum GetIdentityConfigOrDefaultError {
136    #[error("Failed to load configuration for identity '{0}'")]
137    LoadIdentityConfigurationFailed(String, #[source] StructuredFileError),
138}
139
140#[derive(Error, Debug)]
141pub enum GetLegacyCredentialsPemPathError {
142    #[error("Failed to get legacy pem path")]
143    GetLegacyPemPathFailed(#[source] GetUserHomeError),
144}
145
146#[derive(Error, Debug)]
147pub enum InitializeIdentityManagerError {
148    #[error("Cannot create identity directory")]
149    CreateIdentityDirectoryFailed(#[source] CreateDirAllError),
150
151    #[error("Failed to generate key")]
152    GenerateKeyFailed(#[source] GenerateKeyError),
153
154    #[error(transparent)]
155    GetLegacyCredentialsPemPathFailed(#[from] GetLegacyCredentialsPemPathError),
156
157    #[error("failed to migrate legacy identity")]
158    MigrateLegacyIdentityFailed(#[source] CopyFileError),
159
160    #[error("Failed to save configuration")]
161    SaveConfigurationFailed(#[source] StructuredFileError),
162
163    #[error("Failed to write pem to file")]
164    WritePemToFileFailed(#[source] WritePemToFileError),
165}
166
167#[derive(Error, Debug)]
168pub enum InstantiateIdentityFromNameError {
169    #[error("Failed to get principal of identity: {0}")]
170    GetIdentityPrincipalFailed(String),
171
172    #[error("Failed to load identity")]
173    LoadIdentityFailed(#[source] LoadIdentityError),
174
175    #[error("Identity must exist")]
176    RequireIdentityExistsFailed(#[source] RequireIdentityExistsError),
177}
178
179#[derive(Error, Debug)]
180pub enum LoadIdentityError {
181    #[error("Failed to get identity config")]
182    GetIdentityConfigOrDefaultFailed(#[source] GetIdentityConfigOrDefaultError),
183
184    #[error("Failed to instantiate identity")]
185    NewIdentityFailed(#[source] NewIdentityError),
186}
187
188#[derive(Error, Debug)]
189pub enum LoadPemError {
190    #[error("Failed to load PEM file from file")]
191    LoadFromFileFailed(#[source] LoadPemFromFileError),
192
193    #[error("Failed to load PEM file from keyring for identity '{0}'")]
194    LoadFromKeyringFailed(Box<String>, #[source] KeyringError),
195}
196
197#[derive(Error, Debug)]
198pub enum LoadPemFromFileError {
199    #[error("Failed to decrypt PEM file at {0}")]
200    DecryptPemFileFailed(PathBuf, #[source] EncryptionError),
201
202    #[error("failed to read pem file")]
203    ReadPemFileFailed(#[from] ReadFileError),
204}
205
206#[derive(Error, Debug)]
207pub enum LoadPemIdentityError {
208    #[error("Cannot read identity file '{0}'")]
209    ReadIdentityFileFailed(String, #[source] Box<PemError>),
210}
211
212#[derive(Error, Debug)]
213pub enum MapWalletsToRenamedIdentityError {
214    #[error("Failed to get config directory for identity manager")]
215    GetConfigDirectoryFailed(#[source] ConfigError),
216
217    #[error(transparent)]
218    GetSharedNetworkDataDirectoryFailed(#[from] GetSharedWalletConfigPathError),
219
220    #[error(transparent)]
221    LoadNetworkMetadata(#[from] StructuredFileError),
222
223    #[error("Failed to rename wallet global config key")]
224    RenameWalletGlobalConfigKeyFailed(#[source] RenameWalletGlobalConfigKeyError),
225}
226
227#[derive(Error, Debug)]
228pub enum NewHardwareIdentityError {
229    #[error("Failed to instantiate hardware identity for identity '{0}'")]
230    InstantiateHardwareIdentityFailed(String, #[source] Box<HardwareIdentityError>),
231}
232
233#[derive(Error, Debug)]
234pub enum NewIdentityError {
235    #[error("Failed to load PEM")]
236    LoadPemFailed(#[source] LoadPemError),
237
238    #[error("Failed to load PEM identity")]
239    LoadPemIdentityFailed(#[source] LoadPemIdentityError),
240
241    #[error("Failed to instantiate hardware identity")]
242    NewHardwareIdentityFailed(#[source] NewHardwareIdentityError),
243}
244
245#[derive(Error, Debug)]
246pub enum NewIdentityManagerError {
247    #[error("Failed to get config directory for identity manager")]
248    GetConfigDirectoryFailed(#[source] ConfigError),
249
250    #[error("Failed to load identity manager configuration")]
251    LoadIdentityManagerConfigurationFailed(#[source] StructuredFileError),
252
253    #[error("Failed to initialize identity manager")]
254    InitializeFailed(#[source] InitializeIdentityManagerError),
255
256    #[error("The specified identity must exist")]
257    OverrideIdentityMustExist(#[source] RequireIdentityExistsError),
258
259    #[error(r#"No identity configuration found.  Please run "dfx identity get-principal" or "dfx identity new <identity name>" to create a new identity."#)]
260    NoIdentityConfigurationFound,
261}
262
263#[derive(Error, Debug)]
264pub enum RemoveIdentityError {
265    #[error("Cannot delete the anonymous identity.")]
266    CannotDeleteAnonymousIdentity(),
267
268    #[error("Cannot delete the default identity.")]
269    CannotDeleteDefaultIdentity(),
270
271    #[error("Failed to display linked wallets")]
272    DisplayLinkedWalletsFailed(#[source] WalletConfigError),
273
274    #[error(
275        "If you want to remove an identity with configured wallets, please use the --drop-wallets flag."
276    )]
277    DropWalletsFlagRequiredToRemoveIdentityWithWallets(),
278
279    #[error("failed to remove identity directory")]
280    RemoveIdentityDirectoryFailed(#[source] RemoveDirectoryError),
281
282    #[error("Failed to remove identity file")]
283    RemoveIdentityFileFailed(#[from] RemoveFileError),
284
285    #[error("Failed to remove identity from keyring")]
286    RemoveIdentityFromKeyringFailed(#[source] KeyringError),
287
288    #[error("Identity must exist")]
289    RequireIdentityExistsFailed(#[source] RequireIdentityExistsError),
290}
291
292#[derive(Error, Debug)]
293pub enum RenameIdentityError {
294    #[error("Cannot create an anonymous identity.")]
295    CannotCreateAnonymousIdentity(),
296
297    #[error("Failed to get identity config")]
298    GetIdentityConfigFailed(#[source] GetIdentityConfigOrDefaultError),
299
300    #[error("Identity already exists.")]
301    IdentityAlreadyExists(),
302
303    #[error("Identity does not exist")]
304    IdentityDoesNotExist(#[source] RequireIdentityExistsError),
305
306    #[error("Failed to load pem")]
307    LoadPemFailed(#[source] LoadPemError),
308
309    #[error("Failed to map wallets to renamed identity")]
310    MapWalletsToRenamedIdentityFailed(#[source] MapWalletsToRenamedIdentityError),
311
312    #[error("Failed to remove identity from keyring")]
313    RemoveIdentityFromKeyringFailed(#[source] KeyringError),
314
315    #[error("failed to rename identity directory")]
316    RenameIdentityDirectoryFailed(#[from] RenameError),
317
318    #[error("Failed to save identity configuration")]
319    SaveIdentityConfigurationFailed(#[source] SaveIdentityConfigurationError),
320
321    #[error("Failed to save pem")]
322    SavePemFailed(#[source] SavePemError),
323
324    #[error("Failed to switch over default identity settings")]
325    SwitchDefaultIdentitySettingsFailed(#[source] WriteDefaultIdentityError),
326}
327
328#[derive(Error, Debug)]
329pub enum RenameWalletGlobalConfigKeyError {
330    #[error("Failed to rename '{0}' to '{1}' in the global wallet config")]
331    RenameWalletFailed(Box<String>, Box<String>, #[source] WalletConfigError),
332
333    #[error(transparent)]
334    SaveWalletConfig(#[from] SaveWalletConfigError),
335}
336
337#[derive(Error, Debug)]
338pub enum RequireIdentityExistsError {
339    #[error("Identity {0} does not exist at '{1}'.")]
340    IdentityDoesNotExist(String, PathBuf),
341
342    #[error("An Identity named {0} cannot be created as it is reserved for internal use.")]
343    ReservedIdentityName(String),
344}
345
346#[derive(Error, Debug)]
347pub enum SaveIdentityConfigurationError {
348    #[error("failed to ensure identity configuration directory exists")]
349    EnsureIdentityConfigurationDirExistsFailed(#[source] EnsureParentDirExistsError),
350
351    #[error("Failed to save identity configuration")]
352    SaveIdentityConfigurationFailed(#[source] StructuredFileError),
353}
354
355#[derive(Error, Debug)]
356pub enum SavePemError {
357    #[error("Cannot save PEM content for an HSM.")]
358    CannotSavePemContentForHsm(),
359
360    #[error("Failed to write PEM to file")]
361    WritePemToFileFailed(#[source] WritePemToFileError),
362
363    #[error("Failed to write PEM to keyring")]
364    WritePemToKeyringFailed(#[source] KeyringError),
365}
366
367#[derive(Error, Debug)]
368pub enum UseIdentityByNameError {
369    #[error("Identity must exist")]
370    RequireIdentityExistsFailed(#[source] RequireIdentityExistsError),
371
372    #[error("Failed to write default identity")]
373    WriteDefaultIdentityFailed(#[source] WriteDefaultIdentityError),
374}
375
376#[derive(Error, Debug)]
377pub enum ValidatePemFileError {
378    #[error(transparent)]
379    PemError(#[from] ic_agent::identity::PemError),
380
381    #[error(
382        "Ed25519 v1 keys (those generated by OpenSSL) are not supported. Try again with a v2 key"
383    )]
384    UnsupportedKeyVersion(),
385
386    #[error("Failed to validate PEM content")]
387    ValidatePemContentFailed(#[source] Box<PemError>),
388}
389
390#[derive(Error, Debug)]
391pub enum WriteDefaultIdentityError {
392    #[error("Failed to save identity manager configuration")]
393    SaveIdentityManagerConfigurationFailed(#[source] StructuredFileError),
394}
395
396#[derive(Error, Debug)]
397pub enum WritePemContentError {
398    #[error(transparent)]
399    CreateDirAll(#[from] CreateDirAllError),
400
401    #[error(transparent)]
402    NoParent(#[from] NoParentPathError),
403
404    #[error(transparent)]
405    ReadPermissions(#[from] ReadPermissionsError),
406
407    #[error(transparent)]
408    SetPermissions(#[from] SetPermissionsError),
409
410    #[error(transparent)]
411    Write(#[from] WriteFileError),
412}
413
414#[derive(Error, Debug)]
415pub enum WritePemToFileError {
416    #[error("Failed to encrypt PEM file")]
417    EncryptPemFileFailed(PathBuf, #[source] EncryptionError),
418
419    #[error("failed to write PEM content")]
420    WritePemContentFailed(#[source] WritePemContentError),
421}