Skip to main content

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_KEY_CSR_SUBJECT_ALT_NAMES",
250        help = "The optional list of subject alt names (SAN) for the CSR",
251        long_help = "The optional list of subject alt names (SAN) for the CSR
252
253If omitted, it is set to the same value as common_name.
254If it is set to an empty list, no SAN Extension is added.
255All SANs are considered DNS names, unless they start with \"IP:\" to signal IP names."
256    )]
257    pub subject_alt_names: Option<Vec<String>>,
258
259    #[arg(
260        env = "NETHSM_FORCE",
261        help = "Write to output file even if it exists already",
262        long,
263        short
264    )]
265    pub force: bool,
266
267    #[arg(
268        env = "NETHSM_KEY_CSR_OUTPUT_FILE",
269        help = "The optional path to a specific output file",
270        long,
271        short
272    )]
273    pub output: Option<PathBuf>,
274}
275
276#[derive(Debug, Parser)]
277#[command(
278    about = "Decrypt a message using a key",
279    long_about = ex_format!("Decrypt a message using a key
280
281The chosen decryption mode must match the targeted key and the initialization vector (if applicable) must be identical to the one used for encryption.
282
283System-wide users in the \"{Operator}\" role can only decrypt messages using system-wide keys.
284Namespaced users in the \"{Operator}\" role can only decrypt messages using keys in their own namespace.
285
286Requires 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."
287    )
288)]
289pub struct KeyDecryptCommand {
290    #[arg(
291        env = "NETHSM_KEY_ID",
292        help = "The ID of the key to use for decryption"
293    )]
294    pub key_id: KeyId,
295
296    #[arg(
297        env = "NETHSM_KEY_DECRYPT_MESSAGE",
298        help = "The path to an encrypted message to decrypt"
299    )]
300    pub message: PathBuf,
301
302    #[arg(
303        env = "NETHSM_KEY_DECRYPT_MODE",
304        help = "The decryption mode to use",
305        long_help = format!("The decryption mode to use
306
307One of {:?} (defaults to \"{:?}\").", DecryptMode::iter().map(Into::into).collect::<Vec<&'static str>>(), DecryptMode::default())
308    )]
309    pub decrypt_mode: Option<DecryptMode>,
310
311    #[arg(
312        env = "NETHSM_FORCE",
313        help = "Write to output file even if it exists already",
314        long,
315        short
316    )]
317    pub force: bool,
318
319    #[arg(
320        env = "NETHSM_KEY_DECRYPT_IV",
321        help = "The path to a file containing the initialization vector (IV) for symmetric decryption",
322        long_help = ex_format!("The path to a file containing the initialization vector (IV) for symmetric decryption
323
324The IV can only be used when choosing symmetric decryption (i.e. with \"{DecryptMode::AesCbc}\")"),
325        long,
326        short
327    )]
328    pub initialization_vector: Option<PathBuf>,
329
330    #[arg(
331        env = "NETHSM_KEY_DECRYPT_OUTPUT",
332        help = "The path to a specific file to write the decrypted message to",
333        long,
334        short
335    )]
336    pub output: Option<PathBuf>,
337}
338
339#[derive(Debug, Parser)]
340#[command(
341    about = "Encrypt a message using a key",
342    long_about = ex_format!("Encrypt a message using a key
343
344Only symmetric encryption is supported.
345
346System-wide users in the \"{Operator}\" role can only encrypt messages using system-wide keys.
347Namespaced users in the \"{Operator}\" role can only encrypt messages using keys in their own namespace.
348
349Requires 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."
350    )
351)]
352pub struct KeyEncryptCommand {
353    #[arg(
354        env = "NETHSM_KEY_ID",
355        help = "The ID of the key to use for encryption"
356    )]
357    pub key_id: KeyId,
358
359    #[arg(
360        env = "NETHSM_KEY_ENCRYPT_MESSAGE",
361        help = "The path to a message to encrypt"
362    )]
363    pub message: PathBuf,
364
365    #[arg(
366        env = "NETHSM_KEY_ENCRYPT_MODE",
367        help = "The encryption mode to use",
368        long_help = format!("The encryption mode to use
369
370One of {:?} (defaults to \"{:?}\").", EncryptMode::iter().map(Into::into).collect::<Vec<&'static str>>(), EncryptMode::default())
371    )]
372    pub encrypt_mode: Option<EncryptMode>,
373
374    #[arg(
375        env = "NETHSM_FORCE",
376        help = "Write to output file even if it exists already",
377        long,
378        short
379    )]
380    pub force: bool,
381
382    #[arg(
383        env = "NETHSM_KEY_ENCRYPT_IV",
384        help = "The path to a file containing the initialization vector (IV) for symmetric encryption",
385        long_help = ex_format!("The path to a file containing the initialization vector (IV) for symmetric encryption
386
387The IV can only be used when choosing symmetric encryption (i.e. with \"{EncryptMode::AesCbc}\")"),
388        long,
389        short
390    )]
391    pub initialization_vector: Option<PathBuf>,
392
393    #[arg(
394        env = "NETHSM_KEY_ENCRYPT_OUTPUT",
395        help = "The path to a specific file to write the encrypted message to",
396        long,
397        short
398    )]
399    pub output: Option<PathBuf>,
400}
401
402#[derive(Debug, Parser)]
403#[command(
404    about = "Generate a new key",
405    long_about = ex_format!("Generate a new key
406
407The provided key type and list of key mechanisms have to match:
408* \"{KeyType::Rsa}\" requires one of {:?KeyMechanism::rsa_mechanisms()}
409* \"{KeyType::Curve25519}\" requires one of {:?KeyMechanism::curve25519_mechanisms()}
410* \"{KeyType::EcP256}\", \"{KeyType::EcP384}\" and \"{KeyType::EcP521}\" require one of {:?KeyMechanism::elliptic_curve_mechanisms()}
411* \"{KeyType::Generic}\" requires at least one of {:?KeyMechanism::generic_mechanisms()}
412
413System-wide users in the \"{Administrator}\" role generate system-wide keys.
414Namespaced users in the \"{Administrator}\" role generate keys in their own namespace.
415
416Note: 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!
417
418Requires authentication of a user in the \"{Administrator}\" role."
419    )
420)]
421pub struct KeyGenerateCommand {
422    #[arg(
423        env = "NETHSM_KEY_TYPE",
424        help = "The optional type of key to generate",
425        long_help = format!("The optional type of key to generate
426
427The key type must match the chosen key mechanisms!
428
429One of {:?} (defaults to \"{:?}\").",
430            KeyType::iter().map(Into::into).collect::<Vec<&'static str>>(),
431            KeyType::default()),
432    )]
433    pub key_type: Option<KeyType>,
434
435    #[arg(
436        env = "NETHSM_KEY_MECHANISMS",
437        help = "The mechanisms provided by the generated key",
438        long_help = format!("The mechanisms provided by the generated key
439
440The key mechanisms must match the chosen key type!
441
442At least one of {:?} (defaults to \"{:?}\").",
443            KeyMechanism::iter().map(Into::into).collect::<Vec<&'static str>>(),
444            KeyMechanism::default()),
445    )]
446    pub key_mechanisms: Vec<KeyMechanism>,
447
448    #[arg(
449        env = "NETHSM_KEY_BIT_LENGTH",
450        help = "The optional bit length of the generated key",
451        long_help = "The optional bit length of the generated key
452
453If none is provided, a default is chosen.",
454        long,
455        short = 'L'
456    )]
457    pub length: Option<u32>,
458
459    #[arg(
460        env = "NETHSM_KEY_ID",
461        help = "An optional unique ID that is assigned to the generated key",
462        long_help = "An optional unique ID that is assigned to the generated key
463
464If none is provided a generic one is generated for the key.",
465        long,
466        short
467    )]
468    pub key_id: Option<KeyId>,
469
470    #[arg(
471        env = "NETHSM_KEY_TAGS",
472        help = "An optional list of tags that are assigned to the generated key",
473        long_help = "An optional list of tags that are assigned to the generated key
474
475Tags on keys are used to grant access to those keys for users that carry the same tags.",
476        long,
477        short
478    )]
479    pub tags: Option<Vec<String>>,
480
481    #[arg(
482        env = "NETHSM_KEY_LABEL",
483        help = "An optional label that is assigned to the generated key",
484        long_help = "An optional label that is assigned to the generated key
485
486Labels can be used to filter keys in the list of all keys.",
487        long,
488        short
489    )]
490    pub label: Option<String>,
491}
492
493#[derive(Debug, Parser)]
494#[command(
495    about = "Get information on a key",
496    long_about = ex_format!("Get information on a key
497
498Displays 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.
499
500System-wide users in the \"{Administrator}\" or \"{Operator}\" role can only retrieve information on system-wide keys.
501Namespaced users in the \"{Administrator}\" or \"{Operator}\" role can only retrieve information on keys in their own namespace.
502
503Requires 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\")."
504    )
505)]
506pub struct KeyGetCommand {
507    #[arg(
508        env = "NETHSM_KEY_ID",
509        help = "The ID of the key, for which to show information for"
510    )]
511    pub key_id: KeyId,
512}
513
514#[derive(Debug, Parser)]
515#[command(
516    about = "Import a key",
517    long_about = ex_format!("Import a key
518
519The 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.
520The key data must match the provided key type.
521
522The provided key type and list of key mechanisms have to match:
523* \"{KeyType::Rsa}\" requires one of {:?KeyMechanism::rsa_mechanisms()}
524* \"{KeyType::Curve25519}\" requires one of {:?KeyMechanism::curve25519_mechanisms()}
525* \"{KeyType::EcP256}\", \"{KeyType::EcP384}\" and \"{KeyType::EcP521}\" require one of {:?KeyMechanism::elliptic_curve_mechanisms()}
526* \"{KeyType::Generic}\" requires at least one of {:?KeyMechanism::generic_mechanisms()}
527
528System-wide users in the \"{Administrator}\" role import system-wide keys.
529Namespaced users in the \"{Administrator}\" role import keys in their own namespace.
530
531Note: 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!
532
533Requires authentication of a user in the \"{Administrator}\" role."
534    )
535)]
536pub struct KeyImportCommand {
537    #[arg(
538        env = "NETHSM_KEY_TYPE",
539        help = "The type of key to import",
540        long_help = format!("The type of key to import
541
542The key type must match the provided key data and chosen key mechanisms!
543
544One of {:?}.",
545            KeyMechanism::iter().map(Into::into).collect::<Vec<&'static str>>()),
546    )]
547    pub key_type: KeyType,
548
549    #[arg(
550        env = "NETHSM_KEY_FORMAT",
551        help = "The format of key to import",
552        default_value_t = KeyFormat::default(),
553        long,
554        long_help = format!("The format of key to import
555
556Keys can be imported in Distinguished Encoding Rules (DER) or Privacy-Enhanced Mail (PEM) format.
557
558One of {:?}.",
559            KeyFormat::iter().map(Into::into).collect::<Vec<&'static str>>()),
560    )]
561    pub format: KeyFormat,
562
563    #[arg(
564        env = "NETHSM_KEY_DATA",
565        help = "The path to a PKCS#8 private key in ASN.1 DER-encoded format",
566        long_help = "The path to a PKCS#8 private key in ASN.1 DER-encoded format
567
568The private key data must match the chosen key type."
569    )]
570    pub key_data: PathBuf,
571
572    #[arg(
573        env = "NETHSM_KEY_MECHANISMS",
574        help = "The mechanisms provided by the imported key",
575        long_help = format!("The mechanisms provided by the imported key
576
577The key mechanisms must match the chosen key type!
578
579At least one of {:?}.",
580            KeyMechanism::iter().map(Into::into).collect::<Vec<&'static str>>()),
581    )]
582    pub key_mechanisms: Vec<KeyMechanism>,
583
584    #[arg(
585        env = "NETHSM_KEY_ID",
586        help = "An optional unique ID that is assigned to the imported key",
587        long_help = "An optional unique ID that is assigned to the imported key
588
589If none is provided a generic one is generated for the key.",
590        long,
591        short
592    )]
593    pub key_id: Option<KeyId>,
594
595    #[arg(
596        env = "NETHSM_KEY_TAGS",
597        help = "An optional list of tags that are assigned to the imported key",
598        long_help = "An optional list of tags that are assigned to the imported key
599
600Tags on keys are used to grant access to those keys for users that carry the same tags.",
601        long,
602        short
603    )]
604    pub tags: Option<Vec<String>>,
605
606    #[arg(
607        env = "NETHSM_KEY_LABEL",
608        help = "An optional label that is assigned to the imported key",
609        long_help = "An optional label that is assigned to the imported key
610
611Labels can be used to filter keys in the list of all keys.",
612        long,
613        short
614    )]
615    pub label: Option<String>,
616}
617
618#[derive(Debug, Parser)]
619#[command(
620    about = "List all key IDs",
621    long_about = ex_format!("List all key IDs
622
623Optionally filter the list of key IDs by a keyword.
624
625System-wide users in the \"{Administrator}\" or \"{Operator}\" role can only list system-wide keys.
626Namespaced users in the \"{Administrator}\" or \"{Operator}\" role can only list keys in their own namespace.
627
628Requires 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\")."
629    )
630)]
631pub struct KeyListCommand {
632    #[arg(
633        env = "NETHSM_KEY_ID_FILTER",
634        help = "An optional filter to apply to the list of key IDs",
635        long,
636        short
637    )]
638    pub filter: Option<String>,
639
640    #[arg(
641        env = "NETHSM_KEY_ID_LABEL",
642        help = "An optional label to search for",
643        long,
644        short
645    )]
646    pub label: Option<String>,
647}
648
649#[derive(Debug, Parser)]
650#[command(
651    about = "Get the public key for a key",
652    long_about = ex_format!("Get the public key for a key
653
654The public key is returned as X.509 public key certificate in Privacy-enhanced Electronic Mail (PEM) format.
655If no specific output file is chosen, the public key is emitted on stdout.
656
657Note: Keys of type \"{KeyType::Generic}\" do not have a public key and this command fails for them!
658
659System-wide users in the \"{Administrator}\" or \"{Operator}\" role can only get the public key for system-wide keys.
660Namespaced users in the \"{Administrator}\" or \"{Operator}\" role can only get the public key for keys in their own namespace.
661
662Requires 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\")."
663    )
664)]
665pub struct KeyPublicKeyCommand {
666    #[arg(
667        env = "NETHSM_KEY_ID",
668        help = "The ID of the key to get the public key for"
669    )]
670    pub key_id: KeyId,
671
672    #[arg(
673        env = "NETHSM_FORCE",
674        help = "Write to output file even if it exists already",
675        long,
676        short
677    )]
678    pub force: bool,
679
680    #[arg(
681        env = "NETHSM_KEY_PUBKEY_OUTPUT_FILE",
682        help = "The optional path to a specific output file",
683        long,
684        short
685    )]
686    pub output: Option<PathBuf>,
687}
688
689#[derive(Debug, Parser)]
690#[command(
691    about = "Remove a key",
692    long_about = ex_format!("Remove a key
693
694System-wide users in the \"{Administrator}\" role can only remove system-wide keys.
695Namespaced users in the \"{Administrator}\" role can only remove keys in their own namespace.
696
697Requires authentication of a user in the \"{Administrator}\" role."
698    )
699)]
700pub struct KeyRemoveCommand {
701    #[arg(env = "NETHSM_KEY_ID", help = "The ID of the key that is removed")]
702    pub key_id: KeyId,
703}
704
705#[derive(Debug, Parser)]
706#[command(
707    about = "Sign a message using a key",
708    long_about = ex_format!("Sign a message using a key
709
710The targeted key must be equipped with relevant key mechanisms for signing.
711The chosen signature type must match the target key type and key mechanisms.
712
713If no specific output file is chosen, the signature is written to stdout.
714
715System-wide users in the \"{Operator}\" role can only create signatures for messages using system-wide keys.
716Namespaced users in the \"{Operator}\" role can only create signatures for messages using keys in their own namespace.
717
718Requires authentication of a user in the \"{Operator}\" role with access (see \"{BIN_NAME} key tag\" and \"{BIN_NAME} user tag\") to the target key."
719    )
720)]
721pub struct KeySignCommand {
722    #[arg(
723        env = "NETHSM_KEY_ID",
724        help = "The ID of the key to use for signing the message"
725    )]
726    pub key_id: KeyId,
727
728    #[arg(
729        env = "NETHSM_KEY_SIGNATURE_TYPE",
730        help = "The signature type to use for the signature",
731        long_help = format!("The signature type to use for the signature
732
733One of {:?}", SignatureType::iter().map(Into::into).collect::<Vec<&'static str>>()),
734    )]
735    pub signature_type: SignatureType,
736
737    #[arg(
738        env = "NETHSM_KEY_SIGNATURE_MESSAGE",
739        help = "The path to a message for which to create a signature"
740    )]
741    pub message: PathBuf,
742
743    #[arg(
744        env = "NETHSM_FORCE",
745        help = "Write to output file even if it exists already",
746        long,
747        short
748    )]
749    pub force: bool,
750
751    #[arg(
752        env = "NETHSM_KEY_SIGNATURE_OUTPUT_FILE",
753        help = "The optional path to a specific file that the signature is written to",
754        long,
755        short
756    )]
757    pub output: Option<PathBuf>,
758}
759
760#[derive(Debug, Parser)]
761#[command(
762    about = "Tag a key",
763    long_about = ex_format!("Tag a key
764
765Tags are used to grant access to keys for users in the \"{Operator}\" role.
766If a user and a key are tagged with the same tag, the user gains access to that key.
767As 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!
768
769Note: Tags on keys must be created before creating tags on users.
770
771System-wide users in the \"{Administrator}\" role can only tag system-wide keys.
772Namespaced users in the \"{Administrator}\" role can only tag keys in their own namespace.
773
774Requires authentication of a user in the \"{Administrator}\" role."
775    )
776)]
777pub struct KeyTagCommand {
778    #[arg(
779        env = "NETHSM_KEY_ID",
780        help = "The ID of the key for which a tag is added"
781    )]
782    pub key_id: KeyId,
783
784    #[arg(env = "NETHSM_KEY_TAG", help = "The tag to add to the key")]
785    pub tag: String,
786}
787
788#[derive(Debug, Parser)]
789#[command(
790    about = "Untag a key",
791    long_about = ex_format!("Untag a key
792
793Removes access to any key for users in the \"{Operator}\" role that have the same tag.
794As 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!
795
796System-wide users in the \"{Administrator}\" role can only untag system-wide keys.
797Namespaced users in the \"{Administrator}\" role can only untag keys in their own namespace.
798
799Requires authentication of a user in the \"{Administrator}\" role."
800    )
801)]
802pub struct KeyUntagCommand {
803    #[arg(
804        env = "NETHSM_KEY_ID",
805        help = "The ID of the key for which a tag is removed"
806    )]
807    pub key_id: KeyId,
808
809    #[arg(env = "NETHSM_KEY_TAG", help = "The tag to remove from the key")]
810    pub tag: String,
811}