Skip to content

Commit 26be9c7

Browse files
wiktor-kfriedenberg
andcommitted
Implement decoding certificates in PublicCredential
Signed-off-by: Wiktor Kwapisiewicz <wiktor@metacode.biz> See: #98 Co-authored-by: Sasha F <cornflake.matchbox397@icantbelieveitsnotgmail.com>
1 parent ae28a54 commit 26be9c7

4 files changed

Lines changed: 89 additions & 2 deletions

File tree

src/proto/message/credential.rs

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -140,8 +140,27 @@ impl Decode for PublicCredential {
140140
type Error = Error;
141141

142142
fn decode(reader: &mut impl Reader) -> core::result::Result<Self, Self::Error> {
143-
// TODO: implement parsing certificates
144-
Ok(Self::Key(KeyData::decode(reader)?))
143+
// full blob can be passed to Certificate::decode or
144+
// KeyData::decode, both of which expect to read the algorithm
145+
// string themselves.
146+
let alg = String::decode(reader)?;
147+
148+
let remaining_len = reader.remaining_len();
149+
let mut buf = Vec::with_capacity(4 + alg.len() + remaining_len);
150+
alg.encode(&mut buf)?;
151+
let mut tail = vec![0u8; remaining_len];
152+
reader.read(&mut tail)?;
153+
buf.extend_from_slice(&tail);
154+
155+
let mut slice: &[u8] = &buf;
156+
157+
if Algorithm::new_certificate(&alg).is_ok() {
158+
let cert = Certificate::decode(&mut slice)?;
159+
Ok(Self::Cert(Box::new(cert)))
160+
} else {
161+
let key = KeyData::decode(&mut slice)?;
162+
Ok(Self::Key(key))
163+
}
145164
}
146165
}
147166

src/proto/message/request.rs

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,3 +148,71 @@ impl Encode for Request {
148148
Ok(())
149149
}
150150
}
151+
152+
#[cfg(test)]
153+
mod tests {
154+
use ssh_key::Algorithm;
155+
use testresult::TestResult;
156+
157+
use super::*;
158+
use crate::proto::{PublicCredential, Response};
159+
160+
#[test]
161+
fn sign_with_cert() -> TestResult {
162+
let req =
163+
Request::decode(&mut &std::fs::read("tests/messages/req-sign-with-cert.bin")?[..])?;
164+
let Request::SignRequest(req) = req else {
165+
panic!("expected SignRequest");
166+
};
167+
let PublicCredential::Cert(cert) = req.pubkey else {
168+
panic!("expected certificate");
169+
};
170+
assert_eq!(cert.algorithm(), Algorithm::Rsa { hash: None });
171+
Ok(())
172+
}
173+
174+
#[test]
175+
fn sign_with_pubkey() -> TestResult {
176+
let req = Request::decode(&mut &std::fs::read("tests/messages/req-sign-request.bin")?[..])?;
177+
let Request::SignRequest(req) = req else {
178+
panic!("expected SignRequest");
179+
};
180+
let PublicCredential::Key(cert) = req.pubkey else {
181+
panic!("expected key");
182+
};
183+
assert_eq!(cert.algorithm(), Algorithm::Rsa { hash: None });
184+
Ok(())
185+
}
186+
187+
#[test]
188+
fn resp_identities_with_cert() -> TestResult {
189+
let resp = Response::decode(
190+
&mut &std::fs::read("tests/messages/resp-identities-with-cert.bin")?[..],
191+
)?;
192+
let Response::IdentitiesAnswer(resp) = resp else {
193+
panic!("expected IdentitiesAnswer");
194+
};
195+
assert_eq!(resp.len(), 4);
196+
let PublicCredential::Cert(cert) = &resp[3].pubkey else {
197+
panic!("expected certificate");
198+
};
199+
assert_eq!(cert.algorithm(), Algorithm::Rsa { hash: None });
200+
Ok(())
201+
}
202+
203+
#[test]
204+
fn resp_identities_with_key() -> TestResult {
205+
let resp = Response::decode(
206+
&mut &std::fs::read("tests/messages/resp-identities-answer.bin")?[..],
207+
)?;
208+
let Response::IdentitiesAnswer(resp) = resp else {
209+
panic!("expected IdentitiesAnswer");
210+
};
211+
assert_eq!(resp.len(), 1);
212+
let PublicCredential::Key(key) = &resp[0].pubkey else {
213+
panic!("expected key");
214+
};
215+
assert_eq!(key.algorithm(), Algorithm::Rsa { hash: None });
216+
Ok(())
217+
}
218+
}
File renamed without changes.
File renamed without changes.

0 commit comments

Comments
 (0)