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#[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 #[command(subcommand)]
34 Cert(KeyCertCommand),
35 Csr(KeyCsrCommand),
37 Decrypt(KeyDecryptCommand),
39 Encrypt(KeyEncryptCommand),
41 Generate(KeyGenerateCommand),
43 Get(KeyGetCommand),
45 Import(KeyImportCommand),
47 List(KeyListCommand),
49 PublicKey(KeyPublicKeyCommand),
51 Remove(KeyRemoveCommand),
53 Sign(KeySignCommand),
55 Tag(KeyTagCommand),
57 Untag(KeyUntagCommand),
59}
60
61#[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 Delete(KeyCertDeleteCommand),
76 Get(KeyCertGetCommand),
78 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}