nethsm_cli/cli/
key.rs

1use std::path::PathBuf;
2
3use clap::{Parser, Subcommand};
4use expression_format::ex_format;
5use nethsm::KeyId;
6use nethsm::{
7    DecryptMode,
8    EncryptMode,
9    KeyFormat,
10    KeyMechanism,
11    KeyType,
12    SignatureType,
13    UserRole::{Administrator, Operator},
14};
15use strum::IntoEnumIterator;
16
17use super::BIN_NAME;
18
19/// The "nethsm key" command.
20#[derive(Debug, Subcommand)]
21#[command(
22    about = "Operate on the keys of a device",
23    long_about = ex_format!("Operate on the keys of a device
24
25Supports all relevant cryptographic operations (decrypt, encrypt, sign), certificate handling, importing, generation and ACL management.
26
27Keys may exist in specific scopes: system-wide or in namespaces (see \"{BIN_NAME} namespace\").
28While system-wide users only have access to system-wide keys, namespaced users only have access to keys in their own namespace."
29    )
30)]
31pub enum KeyCommand {
32    /// The "nethsm key cert" command.
33    #[command(subcommand)]
34    Cert(KeyCertCommand),
35    /// The "nethsm key csr" command.
36    Csr(KeyCsrCommand),
37    /// The "nethsm key decrypt" command.
38    Decrypt(KeyDecryptCommand),
39    /// The "nethsm key encrypt" command.
40    Encrypt(KeyEncryptCommand),
41    /// The "nethsm key generate" command.
42    Generate(KeyGenerateCommand),
43    /// The "nethsm key get" command.
44    Get(KeyGetCommand),
45    /// The "nethsm key import" command.
46    Import(KeyImportCommand),
47    /// The "nethsm key list" command.
48    List(KeyListCommand),
49    /// The "nethsm key public-key" command.
50    PublicKey(KeyPublicKeyCommand),
51    /// The "nethsm key remove" command.
52    Remove(KeyRemoveCommand),
53    /// The "nethsm key sign" command.
54    Sign(KeySignCommand),
55    /// The "nethsm key tag" command.
56    Tag(KeyTagCommand),
57    /// The "nethsm key untag" command.
58    Untag(KeyUntagCommand),
59}
60
61/// The "nethsm key cert" command.
62#[derive(Debug, Subcommand)]
63#[command(
64    about = "Operate on certificates for a key",
65    long_about = "Operate on certificates for a key
66
67Supports certificate retrieval, removal and import.
68
69System-wide users only have access to system-wide keys.
70Namespaced users only have access to keys in their own namespace.
71"
72)]
73pub enum KeyCertCommand {
74    /// The "nethsm key cert delete" command.
75    Delete(KeyCertDeleteCommand),
76    /// The "nethsm key cert get" command.
77    Get(KeyCertGetCommand),
78    /// The "nethsm key cert import" command.
79    Import(KeyCertImportCommand),
80}
81
82#[derive(Debug, Parser)]
83#[command(
84    about = "Delete the certificate for a key",
85    long_about = ex_format!("Delete the certificate for a key
86
87System-wide users in the \"{Administrator}\" role can only delete certificates for system-wide keys.
88Namespaced users in the \"{Administrator}\" role can only delete certificates for keys in their own namespace.
89
90Requires authentication of a user in the \"{Administrator}\" role."
91)
92)]
93pub struct KeyCertDeleteCommand {
94    #[arg(
95        env = "NETHSM_KEY_ID",
96        help = "The ID of the key, for which to delete the certificate"
97    )]
98    pub key_id: KeyId,
99}
100
101#[derive(Debug, Parser)]
102#[command(
103    about = "Get the certificate for a key",
104    long_about = ex_format!("Get the certificate for a key
105
106System-wide users in the \"{Administrator}\" role can only get certificates for system-wide keys.
107Namespaced users in the \"{Administrator}\" role can only get certificates for keys in their own namespace.
108
109Unless a specific output file is specified, the certificate is written to stdout.
110
111Requires authentication of a user in the \"{Administrator}\" or \"{Operator}\" role (with access to the key - see \"{BIN_NAME} key tag\" and \"{BIN_NAME} user tag\")."
112    )
113)]
114pub struct KeyCertGetCommand {
115    #[arg(
116        env = "NETHSM_KEY_ID",
117        help = "The ID of the key, for which to retrieve the certificate"
118    )]
119    pub key_id: KeyId,
120
121    #[arg(
122        env = "NETHSM_FORCE",
123        help = "Write to output file even if it exists already",
124        long,
125        short
126    )]
127    pub force: bool,
128
129    #[arg(
130        env = "NETHSM_KEY_CERT_OUTPUT_FILE",
131        help = "The optional path to a specific output file",
132        long,
133        short
134    )]
135    pub output: Option<PathBuf>,
136}
137
138#[derive(Debug, Parser)]
139#[command(
140    about = "Import the certificate for a key",
141    long_about = ex_format!("Import the certificate for a key
142
143The NetHSM backend can store binary data up to 1 MiB in size as certificate.
144
145System-wide users in the \"{Administrator}\" role can only import certificates for system-wide keys.
146Namespaced users in the \"{Administrator}\" role can only import certificates for keys in their own namespace.
147
148Requires authentication of a user in the \"{Administrator}\" role."
149    )
150)]
151pub struct KeyCertImportCommand {
152    #[arg(
153        env = "NETHSM_KEY_ID",
154        help = "The ID of the key, for which to import the certificate"
155    )]
156    pub key_id: KeyId,
157
158    #[arg(
159        env = "NETHSM_KEY_CERT_FILE",
160        help = "The path to the certificate file to import"
161    )]
162    pub cert_file: PathBuf,
163}
164
165#[derive(Debug, Parser)]
166#[command(
167    about = "Get a Certificate Signing Request for a key",
168    long_about = ex_format!("Get a Certificate Signing Request for a key
169
170The PKCS#10 Certificate Signing Request (CSR) is returned in Privacy-enhanced Electronic Mail (PEM) format.
171Unless a specific output file is chosen, the certificate is returned on stdout.
172
173At a minimum, the \"Common Name\" (CN) attribute for the CSR has to be provided.
174
175System-wide users in the \"{Administrator}\" or \"{Operator}\" role can only create CSRs for system-wide keys.
176Namespaced users in the \"{Administrator}\" or \"{Operator}\" role can only create CSRs for keys in their own namespace.
177
178Requires authentication of a user in the \"{Administrator}\" or \"{Operator}\" role (with access to the key - see \"{BIN_NAME} key tag\" and \"{BIN_NAME} user tag\")."
179    )
180)]
181pub struct KeyCsrCommand {
182    #[arg(env = "NETHSM_KEY_ID", help = "The key ID for which to create a CSR")]
183    pub key_id: KeyId,
184
185    #[arg(
186        env = "NETHSM_KEY_CSR_COMMON_NAME",
187        help = "The mandatory \"Common Name\" (CN) attribute for the CSR",
188        long_help = "The mandatory \"Common Name\" (CN) attribute for the CSR
189
190A fully qualified domain name (FQDN) that should be secured using the CSR."
191    )]
192    pub common_name: String,
193
194    #[arg(
195        env = "NETHSM_KEY_CSR_ORG_NAME",
196        help = "The optional \"Organization Name\" (O) attribute for the CSR",
197        long_help = "The optional \"Organization Name\" (O) attribute for the CSR
198
199Usually the legal name of a company or entity and should include any suffixes such as Ltd., Inc., or Corp."
200    )]
201    pub org_name: Option<String>,
202
203    #[arg(
204        env = "NETHSM_KEY_CSR_ORG_UNIT",
205        help = "The optional \"Organizational Unit\" (OU) attribute for the CSR",
206        long_help = "The optional \"Organizational Unit\" (OU) attribute for the CSR
207
208Internal organization department/division name."
209    )]
210    pub org_unit: Option<String>,
211
212    #[arg(
213        env = "NETHSM_KEY_CSR_LOCALITY",
214        help = "The optional \"Locality\" (L) attribute for the CSR",
215        long_help = "The optional \"Locality\" (L) attribute for the CSR
216
217Name of town, city, village, etc."
218    )]
219    pub locality: Option<String>,
220
221    #[arg(
222        env = "NETHSM_KEY_CSR_STATE",
223        help = "The optional \"State\" (ST) attribute for the CSR",
224        long_help = "The optional \"State\" (ST) attribute for the CSR
225
226Province, region, county or state."
227    )]
228    pub state: Option<String>,
229
230    #[arg(
231        env = "NETHSM_KEY_CSR_COUNTRY",
232        help = "The optional \"Country\" (C) attribute for the CSR",
233        long_help = "The optional \"Country\" (C) attribute for the CSR
234
235The two-letter ISO code for the country where the \"Organization\" (O) is located."
236    )]
237    pub country: Option<String>,
238
239    #[arg(
240        env = "NETHSM_KEY_CSR_EMAIL",
241        help = "The optional \"Email Address\" (EMAIL) attribute for the CSR",
242        long_help = "The optional \"Email Address\" (EMAIL) attribute for the CSR
243
244The organization contact, usually of the certificate administrator or IT department."
245    )]
246    pub email: Option<String>,
247
248    #[arg(
249        env = "NETHSM_FORCE",
250        help = "Write to output file even if it exists already",
251        long,
252        short
253    )]
254    pub force: bool,
255
256    #[arg(
257        env = "NETHSM_KEY_CSR_OUTPUT_FILE",
258        help = "The optional path to a specific output file",
259        long,
260        short
261    )]
262    pub output: Option<PathBuf>,
263}
264
265#[derive(Debug, Parser)]
266#[command(
267    about = "Decrypt a message using a key",
268    long_about = ex_format!("Decrypt a message using a key
269
270The chosen decryption mode must match the targeted key and the initialization vector (if applicable) must be identical to the one used for encryption.
271
272System-wide users in the \"{Operator}\" role can only decrypt messages using system-wide keys.
273Namespaced users in the \"{Operator}\" role can only decrypt messages using keys in their own namespace.
274
275Requires authentication of a user in the \"{Operator}\" role that has access (see \"{BIN_NAME} key tag\" and \"{BIN_NAME} user tag\") to the targeted key."
276    )
277)]
278pub struct KeyDecryptCommand {
279    #[arg(
280        env = "NETHSM_KEY_ID",
281        help = "The ID of the key to use for decryption"
282    )]
283    pub key_id: KeyId,
284
285    #[arg(
286        env = "NETHSM_KEY_DECRYPT_MESSAGE",
287        help = "The path to an encrypted message to decrypt"
288    )]
289    pub message: PathBuf,
290
291    #[arg(
292        env = "NETHSM_KEY_DECRYPT_MODE",
293        help = "The decryption mode to use",
294        long_help = format!("The decryption mode to use
295
296One of {:?} (defaults to \"{:?}\").", DecryptMode::iter().map(Into::into).collect::<Vec<&'static str>>(), DecryptMode::default())
297    )]
298    pub decrypt_mode: Option<DecryptMode>,
299
300    #[arg(
301        env = "NETHSM_FORCE",
302        help = "Write to output file even if it exists already",
303        long,
304        short
305    )]
306    pub force: bool,
307
308    #[arg(
309        env = "NETHSM_KEY_DECRYPT_IV",
310        help = "The path to a file containing the initialization vector (IV) for symmetric decryption",
311        long_help = ex_format!("The path to a file containing the initialization vector (IV) for symmetric decryption
312
313The IV can only be used when choosing symmetric decryption (i.e. with \"{DecryptMode::AesCbc}\")"),
314        long,
315        short
316    )]
317    pub initialization_vector: Option<PathBuf>,
318
319    #[arg(
320        env = "NETHSM_KEY_DECRYPT_OUTPUT",
321        help = "The path to a specific file to write the decrypted message to",
322        long,
323        short
324    )]
325    pub output: Option<PathBuf>,
326}
327
328#[derive(Debug, Parser)]
329#[command(
330    about = "Encrypt a message using a key",
331    long_about = ex_format!("Encrypt a message using a key
332
333Only symmetric encryption is supported.
334
335System-wide users in the \"{Operator}\" role can only encrypt messages using system-wide keys.
336Namespaced users in the \"{Operator}\" role can only encrypt messages using keys in their own namespace.
337
338Requires authentication of a user in the \"{Operator}\" role that has access (see \"{BIN_NAME} key tag\" and \"{BIN_NAME} user tag\") to the targeted key."
339    )
340)]
341pub struct KeyEncryptCommand {
342    #[arg(
343        env = "NETHSM_KEY_ID",
344        help = "The ID of the key to use for encryption"
345    )]
346    pub key_id: KeyId,
347
348    #[arg(
349        env = "NETHSM_KEY_ENCRYPT_MESSAGE",
350        help = "The path to a message to encrypt"
351    )]
352    pub message: PathBuf,
353
354    #[arg(
355        env = "NETHSM_KEY_ENCRYPT_MODE",
356        help = "The encryption mode to use",
357        long_help = format!("The encryption mode to use
358
359One of {:?} (defaults to \"{:?}\").", EncryptMode::iter().map(Into::into).collect::<Vec<&'static str>>(), EncryptMode::default())
360    )]
361    pub encrypt_mode: Option<EncryptMode>,
362
363    #[arg(
364        env = "NETHSM_FORCE",
365        help = "Write to output file even if it exists already",
366        long,
367        short
368    )]
369    pub force: bool,
370
371    #[arg(
372        env = "NETHSM_KEY_ENCRYPT_IV",
373        help = "The path to a file containing the initialization vector (IV) for symmetric encryption",
374        long_help = ex_format!("The path to a file containing the initialization vector (IV) for symmetric encryption
375
376The IV can only be used when choosing symmetric encryption (i.e. with \"{EncryptMode::AesCbc}\")"),
377        long,
378        short
379    )]
380    pub initialization_vector: Option<PathBuf>,
381
382    #[arg(
383        env = "NETHSM_KEY_ENCRYPT_OUTPUT",
384        help = "The path to a specific file to write the encrypted message to",
385        long,
386        short
387    )]
388    pub output: Option<PathBuf>,
389}
390
391#[derive(Debug, Parser)]
392#[command(
393    about = "Generate a new key",
394    long_about = ex_format!("Generate a new key
395
396The provided key type and list of key mechanisms have to match:
397* \"{KeyType::Rsa}\" requires one of {:?KeyMechanism::rsa_mechanisms()}
398* \"{KeyType::Curve25519}\" requires one of {:?KeyMechanism::curve25519_mechanisms()}
399* \"{KeyType::EcP256}\", \"{KeyType::EcP384}\" and \"{KeyType::EcP521}\" require one of {:?KeyMechanism::elliptic_curve_mechanisms()}
400* \"{KeyType::Generic}\" requires at least one of {:?KeyMechanism::generic_mechanisms()}
401
402System-wide users in the \"{Administrator}\" role generate system-wide keys.
403Namespaced users in the \"{Administrator}\" role generate keys in their own namespace.
404
405Note: Although assigning tags to the new key is optional, it is highly recommended as not doing so means that all users in the same scope have access to it!
406
407Requires authentication of a user in the \"{Administrator}\" role."
408    )
409)]
410pub struct KeyGenerateCommand {
411    #[arg(
412        env = "NETHSM_KEY_TYPE",
413        help = "The optional type of key to generate",
414        long_help = format!("The optional type of key to generate
415
416The key type must match the chosen key mechanisms!
417
418One of {:?} (defaults to \"{:?}\").",
419            KeyType::iter().map(Into::into).collect::<Vec<&'static str>>(),
420            KeyType::default()),
421    )]
422    pub key_type: Option<KeyType>,
423
424    #[arg(
425        env = "NETHSM_KEY_MECHANISMS",
426        help = "The mechanisms provided by the generated key",
427        long_help = format!("The mechanisms provided by the generated key
428
429The key mechanisms must match the chosen key type!
430
431At least one of {:?} (defaults to \"{:?}\").",
432            KeyMechanism::iter().map(Into::into).collect::<Vec<&'static str>>(),
433            KeyMechanism::default()),
434    )]
435    pub key_mechanisms: Vec<KeyMechanism>,
436
437    #[arg(
438        env = "NETHSM_KEY_BIT_LENGTH",
439        help = "The optional bit length of the generated key",
440        long_help = "The optional bit length of the generated key
441
442If none is provided, a default is chosen.",
443        long,
444        short = 'L'
445    )]
446    pub length: Option<u32>,
447
448    #[arg(
449        env = "NETHSM_KEY_ID",
450        help = "An optional unique ID that is assigned to the generated key",
451        long_help = "An optional unique ID that is assigned to the generated key
452
453If none is provided a generic one is generated for the key.",
454        long,
455        short
456    )]
457    pub key_id: Option<KeyId>,
458
459    #[arg(
460        env = "NETHSM_KEY_TAGS",
461        help = "An optional list of tags that are assigned to the generated key",
462        long_help = "An optional list of tags that are assigned to the generated key
463
464Tags on keys are used to grant access to those keys for users that carry the same tags.",
465        long,
466        short
467    )]
468    pub tags: Option<Vec<String>>,
469}
470
471#[derive(Debug, Parser)]
472#[command(
473    about = "Get information on a key",
474    long_about = ex_format!("Get information on a key
475
476Displays information on supported key mechanisms, the key type, which restrictions apply (i.e. which tags are set for the key), information on the public key part and how many operations have been done with the key.
477
478System-wide users in the \"{Administrator}\" or \"{Operator}\" role can only retrieve information on system-wide keys.
479Namespaced users in the \"{Administrator}\" or \"{Operator}\" role can only retrieve information on keys in their own namespace.
480
481Requires authentication of a user in the \"{Administrator}\" or \"{Operator}\" role (with access to the key - see \"{BIN_NAME} key tag\" and \"{BIN_NAME} user tag\")."
482    )
483)]
484pub struct KeyGetCommand {
485    #[arg(
486        env = "NETHSM_KEY_ID",
487        help = "The ID of the key, for which to show information for"
488    )]
489    pub key_id: KeyId,
490}
491
492#[derive(Debug, Parser)]
493#[command(
494    about = "Import a key",
495    long_about = ex_format!("Import a key
496
497The provided key data must be provided as PKCS#8 private key in ASN.1 Distinguished Encoding Rules (DER) encoded or Privacy-Enhanced Mail (PEM) format.
498The key data must match the provided key type.
499
500The provided key type and list of key mechanisms have to match:
501* \"{KeyType::Rsa}\" requires one of {:?KeyMechanism::rsa_mechanisms()}
502* \"{KeyType::Curve25519}\" requires one of {:?KeyMechanism::curve25519_mechanisms()}
503* \"{KeyType::EcP256}\", \"{KeyType::EcP384}\" and \"{KeyType::EcP521}\" require one of {:?KeyMechanism::elliptic_curve_mechanisms()}
504* \"{KeyType::Generic}\" requires at least one of {:?KeyMechanism::generic_mechanisms()}
505
506System-wide users in the \"{Administrator}\" role import system-wide keys.
507Namespaced users in the \"{Administrator}\" role import keys in their own namespace.
508
509Note: Although assigning tags to the new key is optional, it is highly recommended as not doing so means that all users in the same scope have access to it!
510
511Requires authentication of a user in the \"{Administrator}\" role."
512    )
513)]
514pub struct KeyImportCommand {
515    #[arg(
516        env = "NETHSM_KEY_TYPE",
517        help = "The type of key to import",
518        long_help = format!("The type of key to import
519
520The key type must match the provided key data and chosen key mechanisms!
521
522One of {:?}.",
523            KeyMechanism::iter().map(Into::into).collect::<Vec<&'static str>>()),
524    )]
525    pub key_type: KeyType,
526
527    #[arg(
528        env = "NETHSM_KEY_FORMAT",
529        help = "The format of key to import",
530        default_value_t = KeyFormat::default(),
531        long,
532        long_help = format!("The format of key to import
533
534Keys can be imported in Distinguished Encoding Rules (DER) or Privacy-Enhanced Mail (PEM) format.
535
536One of {:?}.",
537            KeyFormat::iter().map(Into::into).collect::<Vec<&'static str>>()),
538    )]
539    pub format: KeyFormat,
540
541    #[arg(
542        env = "NETHSM_KEY_DATA",
543        help = "The path to a PKCS#8 private key in ASN.1 DER-encoded format",
544        long_help = "The path to a PKCS#8 private key in ASN.1 DER-encoded format
545
546The private key data must match the chosen key type."
547    )]
548    pub key_data: PathBuf,
549
550    #[arg(
551        env = "NETHSM_KEY_MECHANISMS",
552        help = "The mechanisms provided by the imported key",
553        long_help = format!("The mechanisms provided by the imported key
554
555The key mechanisms must match the chosen key type!
556
557At least one of {:?}.",
558            KeyMechanism::iter().map(Into::into).collect::<Vec<&'static str>>()),
559    )]
560    pub key_mechanisms: Vec<KeyMechanism>,
561
562    #[arg(
563        env = "NETHSM_KEY_ID",
564        help = "An optional unique ID that is assigned to the imported key",
565        long_help = "An optional unique ID that is assigned to the imported key
566
567If none is provided a generic one is generated for the key.",
568        long,
569        short
570    )]
571    pub key_id: Option<KeyId>,
572
573    #[arg(
574        env = "NETHSM_KEY_TAGS",
575        help = "An optional list of tags that are assigned to the imported key",
576        long_help = "An optional list of tags that are assigned to the imported key
577
578Tags on keys are used to grant access to those keys for users that carry the same tags.",
579        long,
580        short
581    )]
582    pub tags: Option<Vec<String>>,
583}
584
585#[derive(Debug, Parser)]
586#[command(
587    about = "List all key IDs",
588    long_about = ex_format!("List all key IDs
589
590Optionally filter the list of key IDs by a keyword.
591
592System-wide users in the \"{Administrator}\" or \"{Operator}\" role can only list system-wide keys.
593Namespaced users in the \"{Administrator}\" or \"{Operator}\" role can only list keys in their own namespace.
594
595Requires authentication of a user in the \"{Administrator}\" or \"{Operator}\" role (with access to the key - see \"{BIN_NAME} key tag\" and \"{BIN_NAME} user tag\")."
596    )
597)]
598pub struct KeyListCommand {
599    #[arg(
600        env = "NETHSM_KEY_ID_FILTER",
601        help = "A filter to apply to the list of key IDs"
602    )]
603    pub filter: Option<String>,
604}
605
606#[derive(Debug, Parser)]
607#[command(
608    about = "Get the public key for a key",
609    long_about = ex_format!("Get the public key for a key
610
611The public key is returned as X.509 public key certificate in Privacy-enhanced Electronic Mail (PEM) format.
612If no specific output file is chosen, the public key is emitted on stdout.
613
614Note: Keys of type \"{KeyType::Generic}\" do not have a public key and this command fails for them!
615
616System-wide users in the \"{Administrator}\" or \"{Operator}\" role can only get the public key for system-wide keys.
617Namespaced users in the \"{Administrator}\" or \"{Operator}\" role can only get the public key for keys in their own namespace.
618
619Requires authentication of a user in the \"{Administrator}\" or \"{Operator}\" role (with access to the key - see \"{BIN_NAME} key tag\" and \"{BIN_NAME} user tag\")."
620    )
621)]
622pub struct KeyPublicKeyCommand {
623    #[arg(
624        env = "NETHSM_KEY_ID",
625        help = "The ID of the key to get the public key for"
626    )]
627    pub key_id: KeyId,
628
629    #[arg(
630        env = "NETHSM_FORCE",
631        help = "Write to output file even if it exists already",
632        long,
633        short
634    )]
635    pub force: bool,
636
637    #[arg(
638        env = "NETHSM_KEY_PUBKEY_OUTPUT_FILE",
639        help = "The optional path to a specific output file",
640        long,
641        short
642    )]
643    pub output: Option<PathBuf>,
644}
645
646#[derive(Debug, Parser)]
647#[command(
648    about = "Remove a key",
649    long_about = ex_format!("Remove a key
650
651System-wide users in the \"{Administrator}\" role can only remove system-wide keys.
652Namespaced users in the \"{Administrator}\" role can only remove keys in their own namespace.
653
654Requires authentication of a user in the \"{Administrator}\" role."
655    )
656)]
657pub struct KeyRemoveCommand {
658    #[arg(env = "NETHSM_KEY_ID", help = "The ID of the key that is removed")]
659    pub key_id: KeyId,
660}
661
662#[derive(Debug, Parser)]
663#[command(
664    about = "Sign a message using a key",
665    long_about = ex_format!("Sign a message using a key
666
667The targeted key must be equipped with relevant key mechanisms for signing.
668The chosen signature type must match the target key type and key mechanisms.
669
670If no specific output file is chosen, the signature is written to stdout.
671
672System-wide users in the \"{Operator}\" role can only create signatures for messages using system-wide keys.
673Namespaced users in the \"{Operator}\" role can only create signatures for messages using keys in their own namespace.
674
675Requires authentication of a user in the \"{Operator}\" role with access (see \"{BIN_NAME} key tag\" and \"{BIN_NAME} user tag\") to the target key."
676    )
677)]
678pub struct KeySignCommand {
679    #[arg(
680        env = "NETHSM_KEY_ID",
681        help = "The ID of the key to use for signing the message"
682    )]
683    pub key_id: KeyId,
684
685    #[arg(
686        env = "NETHSM_KEY_SIGNATURE_TYPE",
687        help = "The signature type to use for the signature",
688        long_help = format!("The signature type to use for the signature
689
690One of {:?}", SignatureType::iter().map(Into::into).collect::<Vec<&'static str>>()),
691    )]
692    pub signature_type: SignatureType,
693
694    #[arg(
695        env = "NETHSM_KEY_SIGNATURE_MESSAGE",
696        help = "The path to a message for which to create a signature"
697    )]
698    pub message: PathBuf,
699
700    #[arg(
701        env = "NETHSM_FORCE",
702        help = "Write to output file even if it exists already",
703        long,
704        short
705    )]
706    pub force: bool,
707
708    #[arg(
709        env = "NETHSM_KEY_SIGNATURE_OUTPUT_FILE",
710        help = "The optional path to a specific file that the signature is written to",
711        long,
712        short
713    )]
714    pub output: Option<PathBuf>,
715}
716
717#[derive(Debug, Parser)]
718#[command(
719    about = "Tag a key",
720    long_about = ex_format!("Tag a key
721
722Tags are used to grant access to keys for users in the \"{Operator}\" role.
723If a user and a key are tagged with the same tag, the user gains access to that key.
724As keys exist either system-wide or in a namespace, users in the \"{Operator}\" role must be in the same scope as the key for this have effect!
725
726Note: Tags on keys must be created before creating tags on users.
727
728System-wide users in the \"{Administrator}\" role can only tag system-wide keys.
729Namespaced users in the \"{Administrator}\" role can only tag keys in their own namespace.
730
731Requires authentication of a user in the \"{Administrator}\" role."
732    )
733)]
734pub struct KeyTagCommand {
735    #[arg(
736        env = "NETHSM_KEY_ID",
737        help = "The ID of the key for which a tag is added"
738    )]
739    pub key_id: KeyId,
740
741    #[arg(env = "NETHSM_KEY_TAG", help = "The tag to add to the key")]
742    pub tag: String,
743}
744
745#[derive(Debug, Parser)]
746#[command(
747    about = "Untag a key",
748    long_about = ex_format!("Untag a key
749
750Removes access to any key for users in the \"{Operator}\" role that have the same tag.
751As keys exist either system-wide or in a namespace, users in the \"{Operator}\" role must be in the same scope as the key for this to have effect!
752
753System-wide users in the \"{Administrator}\" role can only untag system-wide keys.
754Namespaced users in the \"{Administrator}\" role can only untag keys in their own namespace.
755
756Requires authentication of a user in the \"{Administrator}\" role."
757    )
758)]
759pub struct KeyUntagCommand {
760    #[arg(
761        env = "NETHSM_KEY_ID",
762        help = "The ID of the key for which a tag is removed"
763    )]
764    pub key_id: KeyId,
765
766    #[arg(env = "NETHSM_KEY_TAG", help = "The tag to remove from the key")]
767    pub tag: String,
768}