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
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
// Copyright 2020 MaidSafe.net limited.
//
// This SAFE Network Software is licensed to you under The General Public License (GPL), version 3.
// Unless required by applicable law or agreed to in writing, the SAFE Network Software distributed
// under the GPL Licence is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. Please review the Licences for the specific language governing
// permissions and limitations relating to use of the SAFE Network Software.

//! Secret encryption and signing keys with more secure cloning semantics. These
//! keys implement implicit sharing of the underlying sensitive data to avoid
//! multiple copies of it stored in the memory, preventing certain class of attacks.

/// Symmetric encryption utilities.
pub mod shared_secretbox {
    use crate::utils::{self, SymEncKey};
    use serde::{Deserialize, Serialize};
    use std::fmt::{self, Debug};
    use std::ops::Deref;
    use std::sync::Arc;

    /// Shared symmetric encryption key.
    #[derive(Clone, Eq, PartialEq, Serialize, Deserialize)]
    pub struct Key(Arc<SymEncKey>);

    impl Key {
        /// Create new safe-to-share key from the given regular key.
        pub fn new(inner: &SymEncKey) -> Self {
            // NOTE: make sure we move the inner array, not the whole key, because
            // moving the key would leave the `inner` variable in the "moved-from"
            // state which means it's destructor wouldn't be called and the old
            // memory location wouldn't be zeroed - leaving the sensitive data
            // dangling in the memory.
            Self(Arc::new(*inner))
        }

        /// Create new key from the given raw key data.
        pub fn from_raw(data: &SymEncKey) -> Self {
            // FIXME: this function subverts the purpose of this module - it
            // copies the sensitive data. Possible fix might be to take the input by
            // mutable reference and zero it afterwards.
            Self(Arc::new(*data))
        }
    }

    /// Generate new random shared symmetric encryption key.
    pub fn gen_key() -> Key {
        Key::new(&utils::generate_sym_enc_key())
    }

    impl Deref for Key {
        type Target = SymEncKey;

        fn deref(&self) -> &Self::Target {
            &*self.0
        }
    }

    impl Debug for Key {
        fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
            self.0.fmt(f)
        }
    }
}

/// Asymmetric encryption utilities.
pub mod shared_box {
    use bincode::deserialize;
    use serde::{Deserialize, Serialize};
    use std::fmt::{self, Debug};
    use std::ops::Deref;
    use threshold_crypto::{serde_impl::SerdeSecret, SecretKey as BlsSecretKey};

    /// Shared secret encryption key.
    #[derive(Clone, Eq, PartialEq, Serialize, Deserialize)]
    pub struct SecretKey(SerdeSecret<BlsSecretKey>);

    impl SecretKey {
        /// Create new safe-to-share key from the given regular key.
        pub fn new(inner: BlsSecretKey) -> Self {
            Self(SerdeSecret(inner))
        }

        /// Create new key from the given raw key data.
        pub fn from_raw(data: &[u8]) -> Result<Self, crate::Error> {
            // FIXME: this function subverts the purpose of this module - it
            // copies the sensitive data. Possible fix might be to take the input by
            // mutable reference and zero it afterwards.
            let sk = deserialize(data)?;
            Ok(Self(sk))
        }
    }

    /// Generate new random public/secret keypair.
    pub fn gen_keypair() -> (SecretKey, threshold_crypto::PublicKey) {
        let sk = threshold_crypto::SecretKey::random();
        let pk = sk.public_key();
        (SecretKey::new(sk), pk)
    }

    impl Deref for SecretKey {
        type Target = threshold_crypto::SecretKey;

        fn deref(&self) -> &Self::Target {
            &(*self.0)
        }
    }

    impl Debug for SecretKey {
        fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
            self.0.fmt(f)
        }
    }
}