1 //
2 // Copyright 2020 Signal Messenger, LLC.
3 // SPDX-License-Identifier: AGPL-3.0-only
4 //
5 
6 use crate::proto;
7 use crate::{KeyPair, PrivateKey, PublicKey, Result, SignalProtocolError};
8 
9 use rand::{CryptoRng, Rng};
10 use std::convert::TryFrom;
11 
12 use prost::Message;
13 
14 #[derive(Debug, PartialOrd, Ord, PartialEq, Eq, Clone, Copy)]
15 pub struct IdentityKey {
16     public_key: PublicKey,
17 }
18 
19 impl IdentityKey {
new(public_key: PublicKey) -> Self20     pub fn new(public_key: PublicKey) -> Self {
21         Self { public_key }
22     }
23 
24     #[inline]
public_key(&self) -> &PublicKey25     pub fn public_key(&self) -> &PublicKey {
26         &self.public_key
27     }
28 
29     #[inline]
serialize(&self) -> Box<[u8]>30     pub fn serialize(&self) -> Box<[u8]> {
31         self.public_key.serialize()
32     }
33 
decode(value: &[u8]) -> Result<Self>34     pub fn decode(value: &[u8]) -> Result<Self> {
35         let pk = PublicKey::try_from(value)?;
36         Ok(Self { public_key: pk })
37     }
38 }
39 
40 impl TryFrom<&[u8]> for IdentityKey {
41     type Error = SignalProtocolError;
42 
try_from(value: &[u8]) -> Result<Self>43     fn try_from(value: &[u8]) -> Result<Self> {
44         IdentityKey::decode(value)
45     }
46 }
47 
48 impl From<PublicKey> for IdentityKey {
from(value: PublicKey) -> Self49     fn from(value: PublicKey) -> Self {
50         Self { public_key: value }
51     }
52 }
53 
54 impl From<IdentityKey> for PublicKey {
from(value: IdentityKey) -> Self55     fn from(value: IdentityKey) -> Self {
56         value.public_key
57     }
58 }
59 
60 #[derive(Copy, Clone)]
61 pub struct IdentityKeyPair {
62     identity_key: IdentityKey,
63     private_key: PrivateKey,
64 }
65 
66 impl IdentityKeyPair {
new(identity_key: IdentityKey, private_key: PrivateKey) -> Self67     pub fn new(identity_key: IdentityKey, private_key: PrivateKey) -> Self {
68         Self {
69             identity_key,
70             private_key,
71         }
72     }
73 
generate<R: CryptoRng + Rng>(csprng: &mut R) -> Self74     pub fn generate<R: CryptoRng + Rng>(csprng: &mut R) -> Self {
75         let keypair = KeyPair::generate(csprng);
76 
77         Self {
78             identity_key: keypair.public_key.into(),
79             private_key: keypair.private_key,
80         }
81     }
82 
83     #[inline]
identity_key(&self) -> &IdentityKey84     pub fn identity_key(&self) -> &IdentityKey {
85         &self.identity_key
86     }
87 
88     #[inline]
public_key(&self) -> &PublicKey89     pub fn public_key(&self) -> &PublicKey {
90         self.identity_key.public_key()
91     }
92 
93     #[inline]
private_key(&self) -> &PrivateKey94     pub fn private_key(&self) -> &PrivateKey {
95         &self.private_key
96     }
97 
serialize(&self) -> Box<[u8]>98     pub fn serialize(&self) -> Box<[u8]> {
99         let structure = proto::storage::IdentityKeyPairStructure {
100             public_key: self.identity_key.serialize().to_vec(),
101             private_key: self.private_key.serialize().to_vec(),
102         };
103 
104         let result = structure.encode_to_vec();
105         result.into_boxed_slice()
106     }
107 }
108 
109 impl TryFrom<&[u8]> for IdentityKeyPair {
110     type Error = SignalProtocolError;
111 
try_from(value: &[u8]) -> Result<Self>112     fn try_from(value: &[u8]) -> Result<Self> {
113         let structure = proto::storage::IdentityKeyPairStructure::decode(value)?;
114         Ok(Self {
115             identity_key: IdentityKey::try_from(&structure.public_key[..])?,
116             private_key: PrivateKey::deserialize(&structure.private_key)?,
117         })
118     }
119 }
120 
121 impl TryFrom<PrivateKey> for IdentityKeyPair {
122     type Error = SignalProtocolError;
123 
try_from(private_key: PrivateKey) -> Result<Self>124     fn try_from(private_key: PrivateKey) -> Result<Self> {
125         let identity_key = IdentityKey::new(private_key.public_key()?);
126         Ok(Self::new(identity_key, private_key))
127     }
128 }
129 
130 impl From<KeyPair> for IdentityKeyPair {
from(value: KeyPair) -> Self131     fn from(value: KeyPair) -> Self {
132         Self {
133             identity_key: value.public_key.into(),
134             private_key: value.private_key,
135         }
136     }
137 }
138 
139 impl From<IdentityKeyPair> for KeyPair {
from(value: IdentityKeyPair) -> Self140     fn from(value: IdentityKeyPair) -> Self {
141         Self::new(value.identity_key.into(), value.private_key)
142     }
143 }
144 
145 #[cfg(test)]
146 mod tests {
147     use super::*;
148 
149     use rand::rngs::OsRng;
150 
151     #[test]
test_identity_key_from()152     fn test_identity_key_from() {
153         let key_pair = KeyPair::generate(&mut OsRng);
154         let key_pair_public_serialized = key_pair.public_key.serialize();
155         let identity_key = IdentityKey::from(key_pair.public_key);
156         assert_eq!(key_pair_public_serialized, identity_key.serialize());
157     }
158 
159     #[test]
test_serialize_identity_key_pair() -> Result<()>160     fn test_serialize_identity_key_pair() -> Result<()> {
161         let identity_key_pair = IdentityKeyPair::generate(&mut OsRng);
162         let serialized = identity_key_pair.serialize();
163         let deserialized_identity_key_pair = IdentityKeyPair::try_from(&serialized[..])?;
164         assert_eq!(
165             identity_key_pair.identity_key(),
166             deserialized_identity_key_pair.identity_key()
167         );
168         assert_eq!(
169             identity_key_pair.private_key().key_type(),
170             deserialized_identity_key_pair.private_key().key_type()
171         );
172         assert_eq!(
173             identity_key_pair.private_key().serialize(),
174             deserialized_identity_key_pair.private_key().serialize()
175         );
176 
177         Ok(())
178     }
179 }
180