• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

ssh-vault / ssh-vault / 14317917208

07 Apr 2025 07:35PM UTC coverage: 90.38% (+15.2%) from 75.176%
14317917208

push

github

nbari
fix coverage

2236 of 2474 relevant lines covered (90.38%)

54.55 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

96.0
/src/vault/parse.rs
1
use anyhow::{Result, anyhow};
2
use base64ct::{Base64, Encoding};
3

4
// check if it's a valid SSH-VAULT file and return the data
5
pub fn parse(data: &str) -> Result<(&str, String, Vec<u8>, Vec<u8>)> {
23✔
6
    let tokens: Vec<_> = data.split(';').collect();
23✔
7

23✔
8
    if tokens[0] != "SSH-VAULT" || (tokens[1] != "AES256" && tokens[1] != "CHACHA20-POLY1305") {
23✔
9
        return Err(anyhow!("Not a valid SSH-VAULT file"));
2✔
10
    }
21✔
11

21✔
12
    if tokens[1] == "AES256" {
21✔
13
        if tokens.len() != 4 {
9✔
14
            return Err(anyhow!("Not a valid SSH-VAULT file"));
2✔
15
        }
7✔
16

7✔
17
        let mut lines = tokens[2].lines();
7✔
18

19
        let fingerprint = lines
7✔
20
            .next()
7✔
21
            .ok_or_else(|| anyhow!("Not a valid SSH-VAULT file"))?;
7✔
22

23
        let password = lines.collect::<Vec<&str>>().join("");
6✔
24
        let password = Base64::decode_vec(&password)?;
6✔
25

26
        lines = tokens[3].lines();
6✔
27

6✔
28
        let data = lines.collect::<Vec<&str>>().join("");
6✔
29
        let data = Base64::decode_vec(&data)?;
6✔
30

31
        return Ok((tokens[1], fingerprint.to_string(), password, data));
6✔
32
    } else if tokens[1] == "CHACHA20-POLY1305" {
12✔
33
        if tokens.len() != 6 {
12✔
34
            return Err(anyhow!("Not a valid SSH-VAULT file"));
1✔
35
        }
11✔
36

11✔
37
        let fingerprint = tokens[2].lines().collect::<Vec<&str>>().join("");
11✔
38

11✔
39
        let epk = tokens[3].lines().collect::<Vec<&str>>().join("");
11✔
40
        let epk = Base64::decode_vec(&epk)?;
11✔
41

42
        let password = tokens[4].lines().collect::<Vec<&str>>().join("");
11✔
43
        let password = Base64::decode_vec(&password)?;
11✔
44

45
        let mut epk_and_password = Vec::new();
11✔
46
        epk_and_password.extend_from_slice(&epk);
11✔
47
        epk_and_password.extend_from_slice(&password);
11✔
48

11✔
49
        let data = tokens[5].lines().collect::<Vec<&str>>().join("");
11✔
50
        let data = Base64::decode_vec(&data)?;
11✔
51

52
        return Ok((tokens[1], fingerprint, epk_and_password, data));
11✔
53
    }
×
54

×
55
    Err(anyhow!("Not a valid SSH-VAULT file"))
×
56
}
23✔
57

58
#[cfg(test)]
59
mod tests {
60
    use super::*;
61

62
    #[test]
63
    fn test_parse_invalid_headers() {
1✔
64
        let data = r"SSH-VAULT:CHACHA20-POLY1305;0;0;0;0";
1✔
65
        assert!(parse(data).is_err());
1✔
66
    }
1✔
67

68
    #[test]
69
    fn test_parse_invalid_vault() {
1✔
70
        let data = r"SSH-VAULTCHACHA20-POLY1305SHA256:ZnlGYSmE8yBioOm+jhTxPAk4JagMu
1✔
71
mruoD1rf+WcpFY;EExFHBkGr4L2e0SS0y2Yw9lglLBGVmcho7r3EWSSZHU=;p3kQ
1✔
72
AVM09aZlRhfTZ4Gpp3WJ6AfurNqLo2Y8aDtQVj9uVx8FTJ+pVOTzphZMbCgzbSiU
1✔
73
pqwAZIHYhzss";
1✔
74
        assert!(parse(data).is_err());
1✔
75
    }
1✔
76

77
    #[test]
78
    fn test_parse_missing_data() {
1✔
79
        let data = r"SSH-VAULT;CHACHA20-POLY1305;SHA256:ZnlGYSmE8yBioOm+jhTxPAk4JagMu
1✔
80
mruoD1rf+WcpFY;EExFHBkGr4L2e0SS0y2Yw9lglLBGVmcho7r3EWSSZHU=;p3kQ
1✔
81
AVM09aZlRhfTZ4Gpp3WJ6AfurNqLo2Y8aDtQVj9uVx8FTJ+pVOTzphZMbCgzbSiU
1✔
82
pqwAZIHYhzss";
1✔
83
        assert!(parse(data).is_err());
1✔
84
    }
1✔
85

86
    #[test]
87
    fn test_parse_invalid_rsa_vault() {
1✔
88
        let data = r"SSH-VAULT;AES256;SHA256:ZnlGYSmE8yBioOm+jhTxPAk4JagMu";
1✔
89
        assert!(parse(data).is_err());
1✔
90
    }
1✔
91

92
    #[test]
93
    fn test_parse_no_fingerprint() {
1✔
94
        let data = r"SSH-VAULT;AES256";
1✔
95
        assert!(parse(data).is_err());
1✔
96
    }
1✔
97

98
    #[test]
99
    fn test_parse_no_payload() {
1✔
100
        let data = r"SSH-VAULT;AES256;;0";
1✔
101
        assert!(parse(data).is_err());
1✔
102
    }
1✔
103
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc