tink_core/keyset/
binary_io.rs

1// Copyright 2020 The Tink-Rust Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//      http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14//
15////////////////////////////////////////////////////////////////////////////////
16
17//! Binary I/O for keysets.
18
19use crate::{utils::wrap_err, TinkError};
20use std::io::{Read, Write};
21use tink_proto::prost;
22
23/// `BinaryReader` deserializes a keyset from binary proto format.
24pub struct BinaryReader<T: Read> {
25    r: T,
26}
27
28impl<T: Read> BinaryReader<T> {
29    /// Return a new [`BinaryReader`] that will read from `r`.
30    pub fn new(r: T) -> Self {
31        BinaryReader { r }
32    }
33}
34
35impl<T: Read> super::Reader for BinaryReader<T> {
36    /// Return a (cleartext) [`Keyset`](tink_proto::Keyset) object from the underlying
37    /// [`std::io::Read`].
38    fn read(&mut self) -> Result<tink_proto::Keyset, TinkError> {
39        read::<tink_proto::Keyset>(&mut self.r)
40    }
41
42    /// Return an [`EncryptedKeyset`](tink_proto::EncryptedKeyset) object from the underlying
43    /// [`std::io::Read`].
44    fn read_encrypted(&mut self) -> Result<tink_proto::EncryptedKeyset, TinkError> {
45        read::<tink_proto::EncryptedKeyset>(&mut self.r)
46    }
47}
48
49fn read<T>(r: &mut dyn Read) -> Result<T, TinkError>
50where
51    T: prost::Message + std::default::Default,
52{
53    let mut data = vec![];
54    r.read_to_end(&mut data)
55        .map_err(|e| wrap_err("read failed", e))?;
56    match T::decode(data.as_ref()) {
57        Ok(msg) => Ok(msg),
58        Err(e) => Err(wrap_err("decode failed", e)),
59    }
60}
61
62/// `BinaryWriter` serializes a keyset into binary proto format.
63pub struct BinaryWriter<T: Write> {
64    w: T,
65}
66
67impl<T: Write> BinaryWriter<T> {
68    /// Return a new [`BinaryWriter`] that will write to `w`.
69    pub fn new(w: T) -> Self {
70        BinaryWriter { w }
71    }
72}
73
74impl<T: Write> super::Writer for BinaryWriter<T> {
75    /// Write the keyset to the underlying [`std::io::Write`].
76    fn write(&mut self, keyset: &tink_proto::Keyset) -> Result<(), TinkError> {
77        write(&mut self.w, keyset)
78    }
79
80    /// Write the encrypted keyset to the underlying [`std::io::Write`].
81    fn write_encrypted(&mut self, keyset: &tink_proto::EncryptedKeyset) -> Result<(), TinkError> {
82        write(&mut self.w, keyset)
83    }
84}
85
86fn write<T>(w: &mut dyn Write, msg: &T) -> Result<(), TinkError>
87where
88    T: prost::Message,
89{
90    let mut data = vec![];
91    match msg.encode(&mut data) {
92        Ok(()) => Ok(()),
93        Err(e) => Err(wrap_err("encode failed", e)),
94    }?;
95    match w.write(&data) {
96        Ok(_size) => Ok(()),
97        Err(e) => Err(wrap_err("write failed", e)),
98    }
99}