diff options
author | Артём Павлов [Artyom Pavlov] <newpavlov@gmail.com> | 2017-08-14 07:37:17 +0300 |
---|---|---|
committer | Артём Павлов [Artyom Pavlov] <newpavlov@gmail.com> | 2017-08-14 07:37:17 +0300 |
commit | 331727194c231a10dc2e296922e09aa0e888f4bd (patch) | |
tree | 46e2a32679f399a7584b3b33d3986611195a395c /src/server.rs | |
parent | defd41c0ee00cf06930b733e9ab06163bc6ad1cf (diff) | |
download | PAKEs-331727194c231a10dc2e296922e09aa0e888f4bd.tar.xz |
PAKE repository reorganization
Diffstat (limited to 'src/server.rs')
-rw-r--r-- | src/server.rs | 136 |
1 files changed, 0 insertions, 136 deletions
diff --git a/src/server.rs b/src/server.rs deleted file mode 100644 index 137d6b3..0000000 --- a/src/server.rs +++ /dev/null @@ -1,136 +0,0 @@ -//! SRP server implementation -//! -//! # Usage -//! First receive user's username and public value `a_pub`, retrieve from a -//! database `UserRecord` for a given username, generate `b` (e.g. 512 bits -//! long) and initialize SRP server instance: -//! -//! ```ignore -//! use srp::groups::G_2048; -//! -//! let (username, a_pub) = conn.receive_handshake(); -//! let user = db.retrieve_user_record(username); -//! let b = rng.gen_iter::<u8>().take(64).collect::<Vec<u8>>(); -//! let server = SrpServer::<Sha256>::new(&user, &a_pub, &b, &G_2048)?; -//! ``` -//! -//! Next send to user `b_pub` and `salt` from user record: -//! -//! ```ignore -//! let b_pub = server.get_b_pub(); -//! conn.reply_to_handshake(&user.salt, b_pub); -//! ``` -//! -//! And finally recieve user proof, verify it and send server proof in the -//! reply: -//! -//! ```ignore -//! let user_proof = conn.receive_proof(); -//! let server_proof = server.verify(user_proof)?; -//! conn.send_proof(server_proof); -//! ``` -//! -//! To get the shared secret use `get_key` method. As alternative to using -//! `verify` method it's also possible to use this key for authentificated -//! encryption. -use std::marker::PhantomData; - -use num::{BigUint, Zero}; -use digest::Digest; -use generic_array::GenericArray; - -use tools::powm; -use types::{SrpAuthError, SrpGroup}; - -/// Data provided by users upon registration, usually stored in the database. -pub struct UserRecord<'a> { - pub username: &'a [u8], - pub salt: &'a [u8], - /// Password verifier - pub verifier: &'a [u8], -} - -/// SRP server state -pub struct SrpServer<D: Digest> { - b: BigUint, - a_pub: BigUint, - b_pub: BigUint, - - key: GenericArray<u8, D::OutputSize>, - - d: PhantomData<D> -} - -impl< D: Digest> SrpServer< D> { - /// Create new server state. - pub fn new(user: &UserRecord, a_pub: &[u8], b: &[u8], params: &SrpGroup) - -> Result<Self, SrpAuthError> - { - let a_pub = BigUint::from_bytes_be(a_pub); - // Safeguard against malicious A - if &a_pub % ¶ms.n == BigUint::zero() { - return Err(SrpAuthError { description: "Malicious a_pub value" }) - } - let v = BigUint::from_bytes_be(user.verifier); - let b = BigUint::from_bytes_be(b) % ¶ms.n; - let k = params.compute_k::<D>(); - // kv + g^b - let interm = (k * &v) % ¶ms.n; - let b_pub = (interm + ¶ms.powm(&b)) % ¶ms.n; - // H(A || B) - let u = { - let mut d = D::new(); - d.input(&a_pub.to_bytes_be()); - d.input(&b_pub.to_bytes_be()); - d.result() - }; - let d = Default::default(); - //(Av^u) ^ b - let key = { - let u = BigUint::from_bytes_be(&u); - let t = (&a_pub * powm(&v, &u, ¶ms.n)) % ¶ms.n; - let s = powm(&t, &b, ¶ms.n); - D::digest(&s.to_bytes_be()) - }; - Ok(Self { b, a_pub, b_pub, key, d}) - } - - /// Get private `b` value. (see `new_with_b` documentation) - pub fn get_b(&self) -> Vec<u8> { - self.b.to_bytes_be() - } - - /// Get public `b_pub` value for sending to the user. - pub fn get_b_pub(&self) -> Vec<u8> { - self.b_pub.to_bytes_be() - } - - /// Get shared secret between user and the server. (do not forget to verify - /// that keys are the same!) - pub fn get_key(&self) -> GenericArray<u8, D::OutputSize> { - self.key.clone() - } - - /// Process user proof of having the same shared secret and compute - /// server proof for sending to the user. - pub fn verify(&self, user_proof: &[u8]) - -> Result<GenericArray<u8, D::OutputSize>, SrpAuthError> - { - // M = H(A, B, K) - let mut d = D::new(); - d.input(&self.a_pub.to_bytes_be()); - d.input(&self.b_pub.to_bytes_be()); - d.input(&self.key); - - if user_proof == d.result().as_slice() { - // H(A, M, K) - let mut d = D::new(); - d.input(&self.a_pub.to_bytes_be()); - d.input(user_proof); - d.input(&self.key); - Ok(d.result()) - } else { - Err(SrpAuthError { description: "Incorrect user proof" }) - } - } -} |