Skip to content

Commit dcec785

Browse files
committed
Move PrivateCredential to the credential module
Signed-off-by: Wiktor Kwapisiewicz <[email protected]>
1 parent ae7d5a5 commit dcec785

File tree

3 files changed

+116
-120
lines changed

3 files changed

+116
-120
lines changed

src/proto/message/add_remove.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
11
//! Add a key to an agent with or without constraints and supporting data types.
22
33
mod constrained;
4-
mod credential;
54

65
pub use constrained::*;
7-
pub use credential::*;
86
use secrecy::ExposeSecret as _;
97
use secrecy::SecretString;
108
use ssh_encoding::{self, CheckedSum, Decode, Encode, Reader, Writer};
119
use ssh_key::public::KeyData;
1210

11+
use super::PrivateCredential;
1312
use crate::proto::{Error, Result};
1413

1514
/// Add a key to an agent.

src/proto/message/add_remove/credential.rs

Lines changed: 0 additions & 115 deletions
This file was deleted.

src/proto/message/credential.rs

Lines changed: 115 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,119 @@
1-
use ssh_encoding::{Decode, Encode, Reader};
2-
use ssh_key::{public::KeyData, Certificate};
1+
//! A container for a public / private key pair, or a certificate / private key.
32
4-
use crate::proto::Error;
3+
use std::str::FromStr as _;
4+
5+
use ssh_encoding::{self, CheckedSum, Decode, Encode, Reader, Writer};
6+
use ssh_key::public::KeyData;
7+
use ssh_key::{certificate::Certificate, private::KeypairData, Algorithm};
8+
9+
use crate::proto::{Error, PrivateKeyData, Result};
10+
11+
/// A container for a public / private key pair, or a certificate / private key.
12+
///
13+
/// When adding an identity to an agent, a user can provide either:
14+
/// 1. A public / private key pair
15+
/// 2. An OpenSSH [certificate](https://github.com/openssh/openssh-portable/blob/master/PROTOCOL.certkeys)
16+
///
17+
/// This structure covers both types of identities a user may
18+
/// send to an agent as part of a [`Request::AddIdentity`](crate::proto::Request::AddIdentity) message.
19+
#[derive(Clone, PartialEq, Debug)]
20+
pub enum PrivateCredential {
21+
/// A public/private key pair
22+
Key {
23+
/// Public/private key pair data
24+
privkey: KeypairData,
25+
26+
/// Key comment, if any.
27+
comment: String,
28+
},
29+
30+
/// An OpenSSH [certificate](https://github.com/openssh/openssh-portable/blob/master/PROTOCOL.certkeys)
31+
Cert {
32+
/// Certificate algorithm.
33+
algorithm: Algorithm,
34+
35+
/// Certificate data.
36+
certificate: Certificate,
37+
38+
/// Private key data.
39+
privkey: PrivateKeyData,
40+
41+
/// Comment, if any.
42+
comment: String,
43+
},
44+
}
45+
46+
impl Decode for PrivateCredential {
47+
type Error = Error;
48+
49+
fn decode(reader: &mut impl Reader) -> Result<Self> {
50+
let alg = String::decode(reader)?;
51+
let cert_alg = Algorithm::new_certificate(&alg);
52+
53+
if let Ok(algorithm) = cert_alg {
54+
let certificate = reader.read_prefixed(|reader| {
55+
let cert = Certificate::decode(reader)?;
56+
Ok::<_, Error>(cert)
57+
})?;
58+
let privkey = PrivateKeyData::decode_as(reader, algorithm.clone())?;
59+
let comment = String::decode(reader)?;
60+
61+
Ok(PrivateCredential::Cert {
62+
algorithm,
63+
certificate,
64+
privkey,
65+
comment,
66+
})
67+
} else {
68+
let algorithm = Algorithm::from_str(&alg).map_err(ssh_encoding::Error::from)?;
69+
let privkey = KeypairData::decode_as(reader, algorithm)?;
70+
let comment = String::decode(reader)?;
71+
Ok(PrivateCredential::Key { privkey, comment })
72+
}
73+
}
74+
}
75+
76+
impl Encode for PrivateCredential {
77+
fn encoded_len(&self) -> ssh_encoding::Result<usize> {
78+
match self {
79+
Self::Key { privkey, comment } => {
80+
[privkey.encoded_len()?, comment.encoded_len()?].checked_sum()
81+
}
82+
Self::Cert {
83+
algorithm,
84+
certificate,
85+
privkey,
86+
comment,
87+
} => [
88+
algorithm.to_certificate_type().encoded_len()?,
89+
certificate.encoded_len_prefixed()?,
90+
privkey.encoded_len()?,
91+
comment.encoded_len()?,
92+
]
93+
.checked_sum(),
94+
}
95+
}
96+
97+
fn encode(&self, writer: &mut impl Writer) -> ssh_encoding::Result<()> {
98+
match self {
99+
Self::Key { privkey, comment } => {
100+
privkey.encode(writer)?;
101+
comment.encode(writer)
102+
}
103+
Self::Cert {
104+
algorithm,
105+
certificate,
106+
privkey,
107+
comment,
108+
} => {
109+
algorithm.to_certificate_type().encode(writer)?;
110+
certificate.encode_prefixed(writer)?;
111+
privkey.encode(writer)?;
112+
comment.encode(writer)
113+
}
114+
}
115+
}
116+
}
5117

6118
#[derive(Debug, PartialEq, Eq, Clone)]
7119
/// Represents a public credential.

0 commit comments

Comments
 (0)