summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeal H. Walfield <neal@pep.foundation>2020-12-22 13:49:32 +0100
committerNeal H. Walfield <neal@pep.foundation>2020-12-22 13:49:32 +0100
commit60c7375eaa93867f1b917d5eef163762ef9dc55e (patch)
treeab8d78af197b3e795deea2b0478e13f16d8fa946
parentc2b850125771e3c5cb732d0cd43531e841f10f98 (diff)
sq: Add test cases for sq key adopt.
-rw-r--r--sq/tests/data/keys/alice-lovelace-encryption-subkey-signing-subkey-priv.pgp34
-rw-r--r--sq/tests/data/keys/bob-babbage-cert-only-priv.pgp18
-rw-r--r--sq/tests/data/keys/carol-encryption-subkey-signing-subkey-priv.pgp34
-rw-r--r--sq/tests/sq-key-adopt.rs313
4 files changed, 399 insertions, 0 deletions
diff --git a/sq/tests/data/keys/alice-lovelace-encryption-subkey-signing-subkey-priv.pgp b/sq/tests/data/keys/alice-lovelace-encryption-subkey-signing-subkey-priv.pgp
new file mode 100644
index 00000000..a51312c1
--- /dev/null
+++ b/sq/tests/data/keys/alice-lovelace-encryption-subkey-signing-subkey-priv.pgp
@@ -0,0 +1,34 @@
+-----BEGIN PGP PRIVATE KEY BLOCK-----
+Comment: 5CCB BA06 74EA 5162 615E 36E9 80E5 ADE9 43CA 0DC3
+Comment: Alice Lovelace <alice@example.org>
+
+xVgEX+EpIRYJKwYBBAHaRw8BAQdAk2lV4viRCsrrlI7oZiAFrDW15Ub501ffvU7S
+6yW72T0AAP98f2/23DyuAfXHregxl+xGYN6o6fi77Vi8dYa9wiIb2hSFwsALBB8W
+CgB9BYJf4SkhAwsJBwkQgOWt6UPKDcNHFAAAAAAAHgAgc2FsdEBub3RhdGlvbnMu
+c2VxdW9pYS1wZ3Aub3Jn2zij0tETOdhNjV1/3sgGfKSJvhvxhFFtOKv5oVCjCg8D
+FQoIApsBAh4BFiEEXMu6BnTqUWJhXjbpgOWt6UPKDcMAABzeAQCVmqRLJsxJGNMJ
+h/YMWE13a0A7aUyPGz9/KZwPo3SPDgD8CQ68/y4TKiJ7mq1uXFe7Zy05FaMHsvvi
+Eu0c7pfbsgLNIkFsaWNlIExvdmVsYWNlIDxhbGljZUBleGFtcGxlLm9yZz7CwA4E
+ExYKAIAFgl/hKSEDCwkHCRCA5a3pQ8oNw0cUAAAAAAAeACBzYWx0QG5vdGF0aW9u
+cy5zZXF1b2lhLXBncC5vcmeT5w4uORuaHCWWIK+rzraqwjpRPwebVp6RwmPGxQZ1
+CgMVCggCmQECmwECHgEWIQRcy7oGdOpRYmFeNumA5a3pQ8oNwwAA1cwBAJXM7Y/7
+eu1CSEZnHpGDzPU6sG1vW1DMmrGrfpOC6MaaAQC9g7cgz3lw+0JIIRALUnza1ldV
+Lbo1RvwxCXimdRJLDsdYBF/hKSEWCSsGAQQB2kcPAQEHQD94W151HvcrTgi/kxaj
++GXZVR/Y88YApOIW/4wBFbggAAEA1RuFSSulQ5yhBMbbiSjdtdpBzcqy/mS0/AgQ
+JHkJYZMQH8LAwgQYFgoBNAWCX+EpIQkQgOWt6UPKDcNHFAAAAAAAHgAgc2FsdEBu
+b3RhdGlvbnMuc2VxdW9pYS1wZ3Aub3Jnjj9o9zLfMD6kI28uKxXnh+OtMtHxobKf
+KotBWcbP934CmwICHgG+oAQZFgoAbwWCX+EpIQkQ3EJ5dpXWJOVHFAAAAAAAHgAg
+c2FsdEBub3RhdGlvbnMuc2VxdW9pYS1wZ3Aub3JnhKRR+9OiWWt5iSsaCcLw3ubD
+IOfv9HDCSwEdRnCy0/YWIQRqOx7HYjNivAZudavcQnl2ldYk5QAACdUA/2iU3Zj9
+XUaSD5JglQGEKErfKMYYUZpPOaxTUNotkvLcAP4g47bG6RQPs2KE9ofZyt2vRU+o
+gML+lxdpIyjq4lDUCBYhBFzLugZ06lFiYV426YDlrelDyg3DAAC3jAD/UTXGuANz
+bSSWSwezqCWkuDVF1gGCmptlybiSoQkmbfgA/1KKZ2EMfFn31bDfl5xcLv/ZpL/P
+QgNNKImcXhHo+7gOx10EX+EpIRIKKwYBBAGXVQEFAQEHQJb42VFMY8HDOjz6YID9
+2VlIXRDiriB4y9/kSmbIFW1dAwEICQAA/300m8woegh+4aanj0Jj7Mg1TCAjrIsW
+2Wd4iLyRVcEIEBHCwAMEGBYKAHUFgl/hKSEJEIDlrelDyg3DRxQAAAAAAB4AIHNh
+bHRAbm90YXRpb25zLnNlcXVvaWEtcGdwLm9yZ6N5upvK+V2YoTHp4L4PBhl2gGMt
+yj1Y9/Vr9A/Ua87TApsMAh4BFiEEXMu6BnTqUWJhXjbpgOWt6UPKDcMAALb2APsF
+i7eiPmR16BxyGGlNbr7oGm1zN8YCHj2wmO2L2sS8CQEAxlzlmpOg1617ktMjBU8i
+rxOum0Q1TX/9zb7N8K95jg4=
+=m6EI
+-----END PGP PRIVATE KEY BLOCK-----
diff --git a/sq/tests/data/keys/bob-babbage-cert-only-priv.pgp b/sq/tests/data/keys/bob-babbage-cert-only-priv.pgp
new file mode 100644
index 00000000..2e0135d9
--- /dev/null
+++ b/sq/tests/data/keys/bob-babbage-cert-only-priv.pgp
@@ -0,0 +1,18 @@
+-----BEGIN PGP PRIVATE KEY BLOCK-----
+Comment: C1CF 22F6 C838 07CE 3901 6CDE 8463 B196 87EE 13BB
+Comment: Bob Babbage <bob@example.org>
+
+xVgEX+EpfxYJKwYBBAHaRw8BAQdAIBDRr/OoeKeXc8rAd/zqLcW62SS85wP5PZlu
+3nzemY0AAP9Nr3vg0+0SYqxgIyIlTgx2Cqo8Awht4On30SYMw3q3qA+XwsALBB8W
+CgB9BYJf4Sl/AwsJBwkQhGOxlofuE7tHFAAAAAAAHgAgc2FsdEBub3RhdGlvbnMu
+c2VxdW9pYS1wZ3Aub3Jn6JgygN28hsGXfF45I4NJ9YVpNFcafFcHSJRXVwG6+RoD
+FQoIApsBAh4BFiEEwc8i9sg4B845AWzehGOxlofuE7sAAM1vAQCN1ZW+O1LwSdwN
+gTkRHRzTtat5zuEFUCY5m95GQU+95wD9E84SdcHHJIkxjAcPciVFvruxEl0QfTJZ
+p3BRfZaPag3NHUJvYiBCYWJiYWdlIDxib2JAZXhhbXBsZS5vcmc+wsAOBBMWCgCA
+BYJf4Sl/AwsJBwkQhGOxlofuE7tHFAAAAAAAHgAgc2FsdEBub3RhdGlvbnMuc2Vx
+dW9pYS1wZ3Aub3JnvOACsorPbBGC3UkzAaU1xwXXiWYy0G2ToPt3eZ6kHBwDFQoI
+ApkBApsBAh4BFiEEwc8i9sg4B845AWzehGOxlofuE7sAAL5vAP9SHL/eMSGRDcAB
+FuyttzUGfhFnLrkUsN4uqJSc1AbBvAD/T1eyKmxClkJ77lT8SglwnnBGWzowivdh
+VsJaNN6UDg8=
+=owhs
+-----END PGP PRIVATE KEY BLOCK-----
diff --git a/sq/tests/data/keys/carol-encryption-subkey-signing-subkey-priv.pgp b/sq/tests/data/keys/carol-encryption-subkey-signing-subkey-priv.pgp
new file mode 100644
index 00000000..3a7ad221
--- /dev/null
+++ b/sq/tests/data/keys/carol-encryption-subkey-signing-subkey-priv.pgp
@@ -0,0 +1,34 @@
+-----BEGIN PGP PRIVATE KEY BLOCK-----
+Comment: 0B17 34A8 2726 A5D1 D5AC 1568 1EC1 4781 FD88 09B4
+Comment: Carol <carol@example.org>
+
+xVgEX+E3kBYJKwYBBAHaRw8BAQdASs0ILN2aEvj/twvb1vo7wKT9ABHU6o4ujRX/
+0fFZjpsAAP4xwTpSP8Xe+lSjjGoGoalMi/mO6P1UHK5pgpPga/GS+xM9wsALBB8W
+CgB9BYJf4TeQAwsJBwkQHsFHgf2ICbRHFAAAAAAAHgAgc2FsdEBub3RhdGlvbnMu
+c2VxdW9pYS1wZ3Aub3JnuxssSC5qyTYMvQCsI1mlRJdJXqozDMWspEHgO6obGNED
+FQoIApsBAh4BFiEECxc0qCcmpdHVrBVoHsFHgf2ICbQAAPmBAQC6ZDOJwf/bP5ji
+5uHYGe+m+AfGaPMVTFh6FQjRqBD16wEA6botbClQofBaSx3Rru3XfY3c/cnUi5Jd
+dCZbSbQr0AvNGUNhcm9sIDxjYXJvbEBleGFtcGxlLm9yZz7CwA4EExYKAIAFgl/h
+N5ADCwkHCRAewUeB/YgJtEcUAAAAAAAeACBzYWx0QG5vdGF0aW9ucy5zZXF1b2lh
+LXBncC5vcmdY79mcCoWanc8hEICEfhzTTNkR9+wPApKRCcz/9coeFQMVCggCmQEC
+mwECHgEWIQQLFzSoJyal0dWsFWgewUeB/YgJtAAAC/cA/1y6eWTbR+DNQOPs2fp/
+W4GY8FSuSn0z8IxCy2fPksRpAP92e/0CBkKjaSkaM9r8dKsKpT/krw7WtdAy8WJM
+mHMHBcdYBF/hN5AWCSsGAQQB2kcPAQEHQGP9UaE+6d8Xd/oqtuAe0O4RVH5mXfWh
+ycHiEsMO+JpSAAD/VgdJfyRSjqdCgp5YK/U8+URcYpATf6B5nHmOc/AqZe0PncLA
+wgQYFgoBNAWCX+E3kAkQHsFHgf2ICbRHFAAAAAAAHgAgc2FsdEBub3RhdGlvbnMu
+c2VxdW9pYS1wZ3Aub3JnN4Uv4Qds5xBXfPiQV///S+yksEfVpNda9iLGWasIwGMC
+mwICHgG+oAQZFgoAbwWCX+E3kAkQBdi56tuSqMFHFAAAAAAAHgAgc2FsdEBub3Rh
+dGlvbnMuc2VxdW9pYS1wZ3Aub3Jnk4tn1OpEZd6L6U71mZYgeOSg2WYtQ1bN8hhf
+aqm7xF0WIQQ9VqQkPVzDRWON+xkF2Lnq25KowQAAZ4kA/i1OTj9naXJQT1mSlLki
+Vt3M/BF/o5V9lBPOTBHurb+rAQCRJgWhfbGanDzENHjAMjxaJFuEpQifVrWvZaFx
+GMsvARYhBAsXNKgnJqXR1awVaB7BR4H9iAm0AAA6mAEAloE+iTDr12OLD4m4+d3/
+C8NPedm4Wh8m517WN3lM138BAIbB3YtdYwa9M73lqvjTX7yYwwF1DwkCHrpWFFHf
+nFoLx10EX+E3kBIKKwYBBAGXVQEFAQEHQJqfwagmR2vflwcoPIFgoGK7zRNNpRVo
+GiRvGWwpdek7AwEICQAA/0S6DsVF5rOBKrt5K6JWa6X8uY8zAHtCOeY1no2Srcxg
+EN7CwAMEGBYKAHUFgl/hN5AJEB7BR4H9iAm0RxQAAAAAAB4AIHNhbHRAbm90YXRp
+b25zLnNlcXVvaWEtcGdwLm9yZ2f6a257Ki8vnzBBjR4YfcGcp12EFVbPXgctYDwP
+nP2qApsMAh4BFiEECxc0qCcmpdHVrBVoHsFHgf2ICbQAAFouAP96l5VD9Q+OS+fJ
+g65UnJkGM0iJaykDLIHX9XL789CGcgD/RgIL13421jrt1CZm96/KtabLOSUpNeu3
+xzJTFjzE9wU=
+=/Mna
+-----END PGP PRIVATE KEY BLOCK-----
diff --git a/sq/tests/sq-key-adopt.rs b/sq/tests/sq-key-adopt.rs
new file mode 100644
index 00000000..b3097f14
--- /dev/null
+++ b/sq/tests/sq-key-adopt.rs
@@ -0,0 +1,313 @@
+#[cfg(test)]
+mod integration {
+ use std::path;
+
+ use assert_cmd::Command;
+ use predicates::prelude::*;
+
+ use sequoia_openpgp as openpgp;
+
+ use openpgp::Fingerprint;
+ use openpgp::Result;
+ use openpgp::cert::prelude::*;
+ use openpgp::policy::StandardPolicy;
+ use openpgp::parse::Parse;
+ use openpgp::types::KeyFlags;
+
+ fn dir() -> path::PathBuf {
+ path::Path::new("tests").join("data").join("keys")
+ }
+ fn alice() -> path::PathBuf {
+ // Fingerprint: 5CCB BA06 74EA 5162 615E 36E9 80E5 ADE9 43CA 0DC3
+ // Public-key algo: EdDSA Edwards-curve Digital Signature Algorithm
+ // Public-key size: 256 bits
+ // Secret key: Unencrypted
+ // Creation time: 2020-12-21 23:00:49 UTC
+ // Key flags: certification
+ //
+ // Subkey: 6A3B 1EC7 6233 62BC 066E 75AB DC42 7976 95D6 24E5
+ // Public-key algo: EdDSA Edwards-curve Digital Signature Algorithm
+ // Public-key size: 256 bits
+ // Secret key: Unencrypted
+ // Creation time: 2020-12-21 23:00:49 UTC
+ // Key flags: signing
+ //
+ // Subkey: 827E 4397 F330 7EDA 6ABD 2A6E AD9C 461D 6D2F 0982
+ // Public-key algo: ECDH public key algorithm
+ // Public-key size: 256 bits
+ // Secret key: Unencrypted
+ // Creation time: 2020-12-21 23:00:49 UTC
+ // Key flags: transport encryption, data-at-rest encryption
+ //
+ // UserID: Alice Lovelace <alice@example.org>
+ dir().join("alice-lovelace-encryption-subkey-signing-subkey-priv.pgp")
+ }
+ fn alice_primary() -> (Fingerprint, KeyFlags) {
+ ("5CCB BA06 74EA 5162 615E 36E9 80E5 ADE9 43CA 0DC3".parse().unwrap(),
+ KeyFlags::empty().set_certification())
+ }
+ fn alice_signing() -> (Fingerprint, KeyFlags) {
+ ("6A3B 1EC7 6233 62BC 066E 75AB DC42 7976 95D6 24E5".parse().unwrap(),
+ KeyFlags::empty().set_signing())
+ }
+ fn alice_encryption() -> (Fingerprint, KeyFlags) {
+ ("827E 4397 F330 7EDA 6ABD 2A6E AD9C 461D 6D2F 0982".parse().unwrap(),
+ KeyFlags::empty().set_transport_encryption().set_storage_encryption())
+ }
+ fn bob() -> path::PathBuf {
+ // Fingerprint: C1CF 22F6 C838 07CE 3901 6CDE 8463 B196 87EE 13BB
+ // Public-key algo: EdDSA Edwards-curve Digital Signature Algorithm
+ // Public-key size: 256 bits
+ // Secret key: Unencrypted
+ // Creation time: 2020-12-21 23:02:23 UTC
+ // Key flags: certification
+ //
+ // UserID: Bob Babbage <bob@example.org>
+ dir().join("bob-babbage-cert-only-priv.pgp")
+ }
+ fn bob_primary() -> (Fingerprint, KeyFlags) {
+ ("C1CF 22F6 C838 07CE 3901 6CDE 8463 B196 87EE 13BB".parse().unwrap(),
+ KeyFlags::empty().set_certification())
+ }
+
+ fn carol() -> path::PathBuf {
+ // Fingerprint: 0B17 34A8 2726 A5D1 D5AC 1568 1EC1 4781 FD88 09B4
+ // Public-key algo: EdDSA Edwards-curve Digital Signature Algorithm
+ // Public-key size: 256 bits
+ // Secret key: Unencrypted
+ // Creation time: 2020-12-22 00:02:24 UTC
+ // Key flags: certification
+ //
+ // Subkey: 3D56 A424 3D5C C345 638D FB19 05D8 B9EA DB92 A8C1
+ // Public-key algo: EdDSA Edwards-curve Digital Signature Algorithm
+ // Public-key size: 256 bits
+ // Secret key: Unencrypted
+ // Creation time: 2020-12-22 00:02:24 UTC
+ // Key flags: signing
+ //
+ // Subkey: 1F47 6866 1260 CFFA D3DE B630 5652 476A 8B74 5CE5
+ // Public-key algo: ECDH public key algorithm
+ // Public-key size: 256 bits
+ // Secret key: Unencrypted
+ // Creation time: 2020-12-22 00:02:24 UTC
+ // Key flags: transport encryption, data-at-rest encryption
+ //
+ // UserID: Carol <carol@example.org>
+ dir().join("carol-encryption-subkey-signing-subkey-priv.pgp")
+ }
+ fn carol_primary() -> (Fingerprint, KeyFlags) {
+ ("0B17 34A8 2726 A5D1 D5AC 1568 1EC1 4781 FD88 09B4".parse().unwrap(),
+ KeyFlags::empty().set_certification())
+ }
+ fn carol_signing() -> (Fingerprint, KeyFlags) {
+ ("3D56 A424 3D5C C345 638D FB19 05D8 B9EA DB92 A8C1".parse().unwrap(),
+ KeyFlags::empty().set_signing())
+ }
+ fn carol_encryption() -> (Fingerprint, KeyFlags) {
+ ("1F47 6866 1260 CFFA D3DE B630 5652 476A 8B74 5CE5".parse().unwrap(),
+ KeyFlags::empty().set_transport_encryption().set_storage_encryption())
+ }
+
+ fn check(output: &[u8],
+ key_count: usize,
+ keys: ((Fingerprint, KeyFlags), &[(Fingerprint, KeyFlags)]))
+ -> Result<()>
+ {
+ let p = &StandardPolicy::new();
+
+ let cert = Cert::from_bytes(output).unwrap();
+ let vc = cert.with_policy(p, None).unwrap();
+
+ assert_eq!(key_count, vc.keys().count());
+
+ assert_eq!(vc.primary_key().fingerprint(), keys.0.0);
+ assert_eq!(vc.primary_key().key_flags(), Some(keys.0.1));
+
+ for (subkey, keyflags) in keys.1 {
+ let mut found = false;
+ for k in vc.keys().subkeys() {
+ if k.fingerprint() == *subkey {
+ assert_eq!(k.key_flags().as_ref(), Some(keyflags));
+ found = true;
+ break;
+ }
+ }
+ assert!(found);
+ }
+
+ Ok(())
+ }
+
+ #[test]
+ fn adopt_encryption() -> Result<()> {
+ // Adopt an encryption subkey.
+ Command::cargo_bin("sq").unwrap().arg("key").arg("adopt")
+ .arg(bob())
+ .arg("--keyring").arg(alice())
+ .arg("--key").arg(alice_encryption().0.to_hex())
+ .assert()
+ .code(0)
+ .stdout(predicate::function(|output: &[u8]| -> bool {
+ check(output, 2, (bob_primary(), &[alice_encryption()])).is_ok()
+ }));
+
+ Ok(())
+ }
+
+ #[test]
+ fn adopt_signing() -> Result<()> {
+ // Adopt a signing subkey (subkey has secret key material).
+ Command::cargo_bin("sq").unwrap().arg("key").arg("adopt")
+ .arg(bob())
+ .arg("--keyring").arg(alice())
+ .arg("--key").arg(alice_signing().0.to_hex())
+ .assert()
+ .code(0)
+ .stdout(predicate::function(|output: &[u8]| -> bool {
+ check(output, 2, (bob_primary(), &[alice_signing()])).is_ok()
+ }));
+
+ Ok(())
+ }
+
+ #[test]
+ fn adopt_certification() -> Result<()> {
+ // Adopt a certification subkey (subkey has secret key material).
+ Command::cargo_bin("sq").unwrap().arg("key").arg("adopt")
+ .arg(carol())
+ .arg("--keyring").arg(alice())
+ .arg("--key").arg(alice_primary().0.to_hex())
+ .assert()
+ .code(0)
+ .stdout(predicate::function(|output: &[u8]| -> bool {
+ check(output, 4, (carol_primary(), &[alice_primary()])).is_ok()
+ }));
+
+ Ok(())
+ }
+
+ #[test]
+ fn adopt_encryption_and_signing() -> Result<()> {
+ // Adopt an encryption subkey and a signing subkey.
+ Command::cargo_bin("sq").unwrap().arg("key").arg("adopt")
+ .arg(bob())
+ .arg("--keyring").arg(alice())
+ .arg("--key").arg(alice_signing().0.to_hex())
+ .arg("--key").arg(alice_encryption().0.to_hex())
+ .assert()
+ .code(0)
+ .stdout(predicate::function(|output: &[u8]| -> bool {
+ check(output, 3,
+ (bob_primary(),
+ &[alice_signing(), alice_encryption()]))
+ .is_ok()
+ }));
+
+ Ok(())
+ }
+
+ #[test]
+ fn adopt_twice() -> Result<()> {
+ // Adopt the same an encryption subkey twice.
+ Command::cargo_bin("sq").unwrap().arg("key").arg("adopt")
+ .arg(bob())
+ .arg("--keyring").arg(alice())
+ .arg("--key").arg(alice_encryption().0.to_hex())
+ .arg("--key").arg(alice_encryption().0.to_hex())
+ .assert()
+ .code(0)
+ .stdout(predicate::function(|output: &[u8]| -> bool {
+ check(output, 2, (bob_primary(), &[alice_encryption()])).is_ok()
+ }));
+
+ Ok(())
+ }
+
+ #[test]
+ fn adopt_key_appears_twice() -> Result<()> {
+ // Adopt the an encryption subkey that appears twice.
+ Command::cargo_bin("sq").unwrap().arg("key").arg("adopt")
+ .arg(bob())
+ .arg("--keyring").arg(alice())
+ .arg("--keyring").arg(alice())
+ .arg("--key").arg(alice_encryption().0.to_hex())
+ .assert()
+ .code(0)
+ .stdout(predicate::function(|output: &[u8]| -> bool {
+ check(output, 2, (bob_primary(), &[alice_encryption()])).is_ok()
+ }));
+
+ Ok(())
+ }
+
+ #[test]
+ fn adopt_own_encryption() -> Result<()> {
+ // Adopt its own encryption subkey. This should be a noop.
+ Command::cargo_bin("sq").unwrap().arg("key").arg("adopt")
+ .arg(alice())
+ .arg("--keyring").arg(alice())
+ .arg("--key").arg(alice_encryption().0.to_hex())
+ .assert()
+ .code(0)
+ .stdout(predicate::function(|output: &[u8]| -> bool {
+ check(output, 3, (alice_primary(), &[alice_encryption()])).is_ok()
+ }));
+
+ Ok(())
+ }
+
+ #[test]
+ fn adopt_own_primary() -> Result<()> {
+ // Adopt own primary key.
+ Command::cargo_bin("sq").unwrap().arg("key").arg("adopt")
+ .arg(bob())
+ .arg("--keyring").arg(bob())
+ .arg("--key").arg(bob_primary().0.to_hex())
+ .assert()
+ .code(0)
+ .stdout(predicate::function(|output: &[u8]| -> bool {
+ check(output, 2, (bob_primary(), &[bob_primary()])).is_ok()
+ }));
+
+ Ok(())
+ }
+
+ #[test]
+ fn adopt_missing() -> Result<()> {
+ // Adopt a key that is not present.
+ Command::cargo_bin("sq").unwrap().arg("key").arg("adopt")
+ .arg(bob())
+ .arg("--keyring").arg(bob())
+ .arg("--key").arg("1234 5678 90AB CDEF 1234 5678 90AB CDEF")
+ .assert()
+ .code(1);
+
+ Ok(())
+ }
+
+ #[test]
+ fn adopt_from_multiple() -> Result<()> {
+ // Adopt from multiple certificates simultaneously.
+ Command::cargo_bin("sq").unwrap().arg("key").arg("adopt")
+ .arg(bob())
+ .arg("--keyring").arg(alice())
+ .arg("--key").arg(alice_signing().0.to_hex())
+ .arg("--key").arg(alice_encryption().0.to_hex())
+ .arg("--keyring").arg(carol())
+ .arg("--key").arg(carol_signing().0.to_hex())
+ .arg("--key").arg(carol_encryption().0.to_hex())
+ .assert()
+ .code(0)
+ .stdout(predicate::function(|output: &[u8]| -> bool {
+ check(output, 5,
+ (bob_primary(),
+ &[
+ alice_signing(), alice_encryption(),
+ carol_signing(), carol_encryption()
+ ]))
+ .is_ok()
+ }));
+
+ Ok(())
+ }
+}