1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
use byteorder::{BigEndian, ByteOrder}; /// A `Writer` is used for encoding a key in OpenSSH compatible format. #[derive(Debug)] pub struct Writer { inner: Vec<u8>, } impl Writer { /// Creates a new `Writer` instance. /// /// # Example /// ```rust /// let writer = sshkeys::Writer::new(); /// ``` pub fn new() -> Writer { Writer { inner: Vec::new() } } /// Writes a byte sequence to the underlying vector. /// The value is represented as a the byte sequence length, /// followed by the actual byte sequence. /// /// # Example /// ```rust /// # use sshkeys; /// let mut writer = sshkeys::Writer::new(); /// writer.write_bytes(&[0, 0, 0, 42]); /// let bytes = writer.into_bytes(); /// assert_eq!(bytes, vec![0, 0, 0, 4, 0, 0, 0, 42]); /// ``` pub fn write_bytes(&mut self, val: &[u8]) { let size = val.len() as u32; let mut buf = vec![0; 4]; BigEndian::write_u32(&mut buf, size); self.inner.append(&mut buf); self.inner.extend_from_slice(&val); } /// Writes a `string` value to the underlying byte sequence. /// /// # Example /// ```rust /// # use sshkeys; /// let mut writer = sshkeys::Writer::new(); /// writer.write_string("a test string"); /// let bytes = writer.into_bytes(); /// assert_eq!(bytes, [0, 0, 0, 13, 97, 32, 116, 101, 115, 116, 32, 115, 116, 114, 105, 110, 103]); /// ``` pub fn write_string(&mut self, val: &str) { self.write_bytes(val.as_bytes()); } /// Writes an `mpint` value to the underlying byte sequence. /// If the MSB bit of the first byte is set then the number is /// negative, otherwise it is positive. /// Positive numbers must be preceeded by a leading zero byte according to RFC 4251, section 5. /// /// # Example /// ```rust /// # use sshkeys; /// let mut writer = sshkeys::Writer::new(); /// writer.write_mpint(&[1, 0, 1]); /// let bytes = writer.into_bytes(); /// assert_eq!(bytes, [0, 0, 0, 3, 1, 0, 1]); /// ``` pub fn write_mpint(&mut self, val: &[u8]) { let mut bytes = val.to_vec(); // If most significant bit is set then prepend a zero byte to // avoid interpretation as a negative number. if val.get(0).unwrap_or(&0) & 0x80 != 0 { bytes.insert(0, 0); } self.write_bytes(&bytes); } /// Converts the `Writer` into a byte sequence. /// This consumes the underlying byte sequence used by the `Writer`. /// /// # Example /// ```rust /// let mut writer = sshkeys::Writer::new(); /// writer.write_string("some data"); /// let bytes = writer.into_bytes(); /// assert_eq!(bytes, [0, 0, 0, 9, 115, 111, 109, 101, 32, 100, 97, 116, 97]); /// ``` pub fn into_bytes(self) -> Vec<u8> { self.inner } }