Skip to content

Commit

Permalink
Remove unwraps, add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
essamhassan committed Aug 15, 2023
1 parent 82a99b4 commit b2119fb
Show file tree
Hide file tree
Showing 4 changed files with 244 additions and 13 deletions.
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,7 @@ docker exec -it -e RUST_LOG=debug prover ./prover http://verifier:50051 register
- Login
```bash
docker exec -it -e RUST_LOG=debug prover ./prover http://verifier:50051 register --client-id="clienttest"
```
```

# Pending work
- Looks like there is an opportunity to improve performance of BigInt expontiation.
2 changes: 0 additions & 2 deletions src/lib/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ pub mod blind_auth_api {
tonic::include_proto!("blind_auth");
}


// Generates a random BigInt between min and max
pub fn generate_randomness(min: &BigInt, max: &BigInt) -> BigInt {
let mut rng = rand::thread_rng();
Expand All @@ -25,7 +24,6 @@ pub fn generate_randomness(min: &BigInt, max: &BigInt) -> BigInt {
min + random_bigint % &range
}


// Generates a param pair p1, p2 where p1=(g^exponent)%p, p2=(h^exponent)%p
pub fn gen_params(exponent: &BigInt) -> (String, String) {
let p1 = PublicParams::g().modpow(exponent, &PublicParams::p());
Expand Down
81 changes: 71 additions & 10 deletions src/lib/verifier.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,32 @@ impl BlindAuth for AuthServer {
) -> Result<Response<RegisterResponse>, Status> {
info!("register request: {:?}", request.get_ref());

if request.get_ref().user.is_empty() {
return Err(Status::invalid_argument("user field is not set"));
}

let y1 = match BigInt::from_str_radix(request.get_ref().y1.as_str(), 16) {
Ok(y) => y,
Err(_) => {
return Err(Status::invalid_argument(
"y1 field is not base16 number string",
))
}
};

let y2 = match BigInt::from_str_radix(request.get_ref().y2.as_str(), 16) {
Ok(r) => r,
Err(_) => {
return Err(Status::invalid_argument(
"y2 field is not base16 number string",
))
}
};

self.store.insert_user(User {
id: request.get_ref().user.to_string(),
y1: BigInt::from_str_radix(request.get_ref().y1.as_str(), 16).unwrap(),
y2: BigInt::from_str_radix(request.get_ref().y2.as_str(), 16).unwrap(),
y1: y1,
y2: y2,
});

Ok(Response::new(RegisterResponse { success: true }))
Expand All @@ -45,13 +67,35 @@ impl BlindAuth for AuthServer {
request.get_ref()
);

if request.get_ref().user.is_empty() {
return Err(Status::invalid_argument("user field is not set"));
}

let r1 = match BigInt::from_str_radix(request.get_ref().r1.as_str(), 16) {
Ok(r) => r,
Err(_) => {
return Err(Status::invalid_argument(
"r1 field is not base16 number string",
))
}
};

let r2 = match BigInt::from_str_radix(request.get_ref().r2.as_str(), 16) {
Ok(r) => r,
Err(_) => {
return Err(Status::invalid_argument(
"r2 field is not base16 number string",
))
}
};

if let Some(user) = self.store.get_user(&request.get_ref().user) {
let c = generate_randomness(&BigInt::from(2), &PublicParams::q().sub(2));
let challenge = Challenge {
c: c.clone(),
user_id: user.id,
r1: BigInt::from_str_radix(request.get_ref().r1.as_str(), 16).unwrap(),
r2: BigInt::from_str_radix(request.get_ref().r2.as_str(), 16).unwrap(),
r1: r1,
r2: r2,
id: generate_id(),
};
self.store.insert_challenge(challenge.clone());
Expand All @@ -70,12 +114,29 @@ impl BlindAuth for AuthServer {
request: Request<AuthAnswerRequest>,
) -> Result<Response<AuthAnswerResponse>, Status> {
info!("verify_authentication req: {:?}", request.get_ref());
let challenge = self
.store
.get_challenge(&request.get_ref().auth_id)
.unwrap();
let user = self.store.get_user(&challenge.user_id).unwrap();
let auth_s = BigInt::from_str_radix(request.get_ref().s.as_str(), 16).unwrap();

if request.get_ref().auth_id.is_empty() {
return Err(Status::invalid_argument("auth_id field is not set"));
}

let challenge = match self.store.get_challenge(&request.get_ref().auth_id) {
Some(challenge) => challenge,
None => return Err(Status::not_found("challenge not found")),
};

let user = match self.store.get_user(&challenge.user_id) {
Some(user) => user,
None => {
return Err(Status::failed_precondition(
"failed to fetch user for supplied challenge",
))
}
};

let auth_s = match BigInt::from_str_radix(request.get_ref().s.as_str(), 16) {
Ok(s) => s,
Err(err) => return Err(Status::invalid_argument(err.to_string())),
};

let success = verify_challenge(&user, &challenge, auth_s);
let session = Session {
Expand Down
169 changes: 169 additions & 0 deletions tests/verifier_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,3 +151,172 @@ async fn test_verify_authentication_failed() {
tonic::Code::PermissionDenied
);
}

#[tokio::test]
async fn test_empty_user_register() {
let store = DataStore::new();
let auth_server = AuthServer { store };

let request = RegisterRequest {
user: "".to_string(),
y1: "1".to_string(),
y2: "2".to_string(),
};

let result = auth_server.register(Request::new(request)).await;

assert_eq!(result.unwrap_err().code(), tonic::Code::InvalidArgument);
}

#[tokio::test]
async fn test_invalid_y1_register() {
let store = DataStore::new();
let auth_server = AuthServer { store };

let request = RegisterRequest {
user: "test_user".to_string(),
y1: "invalid_y1".to_string(),
y2: "2".to_string(),
};

let result = auth_server.register(Request::new(request)).await;

assert_eq!(result.unwrap_err().code(), tonic::Code::InvalidArgument);
}

#[tokio::test]
async fn test_invalid_y2_register() {
let store = DataStore::new();
let auth_server = AuthServer { store };

let request = RegisterRequest {
user: "test_user".to_string(),
y1: "1".to_string(),
y2: "invalid_y2".to_string(),
};

let result = auth_server.register(Request::new(request)).await;

assert_eq!(result.unwrap_err().code(), tonic::Code::InvalidArgument);
}

#[tokio::test]
async fn test_empty_user_auth_challenge() {
let store = DataStore::new();
let auth_server = AuthServer { store };

let request = AuthChallengeRequest {
user: "".to_string(),
r1: "1".to_string(),
r2: "2".to_string(),
};

let result = auth_server
.create_authentication_challenge(Request::new(request))
.await;

assert_eq!(result.unwrap_err().code(), tonic::Code::InvalidArgument);
}

#[tokio::test]
async fn test_invalid_r1_auth_challenge() {
let store = DataStore::new();
let auth_server = AuthServer { store };

let request = AuthChallengeRequest {
user: "test_user".to_string(),
r1: "invalid_r1".to_string(),
r2: "2".to_string(),
};

let result = auth_server
.create_authentication_challenge(Request::new(request))
.await;

assert_eq!(result.unwrap_err().code(), tonic::Code::InvalidArgument);
}

#[tokio::test]
async fn test_invalid_r2_auth_challenge() {
let store = DataStore::new();
let auth_server = AuthServer { store };

let request = AuthChallengeRequest {
user: "test_user".to_string(),
r1: "1".to_string(),
r2: "invalid_r2".to_string(),
};

let result = auth_server
.create_authentication_challenge(Request::new(request))
.await;

assert_eq!(result.unwrap_err().code(), tonic::Code::InvalidArgument);
}

#[tokio::test]
async fn test_empty_auth_id_verify_auth() {
let store = DataStore::new();
let auth_server = AuthServer { store };

let request = AuthAnswerRequest {
auth_id: "".to_string(),
s: "1".to_string(),
};

let result = auth_server
.verify_authentication(Request::new(request))
.await;

assert_eq!(result.unwrap_err().code(), tonic::Code::InvalidArgument);
}

#[tokio::test]
async fn test_invalid_s_verify_auth() {
let store = DataStore::new();
let auth_server = AuthServer { store };

// Insert a user and challenge into the DataStore
let user = User {
id: String::from("dummy"),
y1: BigInt::from(1),
y2: BigInt::from(3),
};
auth_server.store.insert_user(user.clone());
let challenge = Challenge {
user_id: String::from("dummy"),
c: BigInt::from(1),
r2: BigInt::from(3),
r1: BigInt::from(4),
id: String::from("challengeid"),
};
auth_server.store.insert_challenge(challenge.clone());

let request = AuthAnswerRequest {
auth_id: "challengeid".to_string(),
s: "invalid_s".to_string(),
};

let result = auth_server
.verify_authentication(Request::new(request))
.await;

assert_eq!(result.unwrap_err().code(), tonic::Code::InvalidArgument);
}

#[tokio::test]
async fn test_invalid_challenge_id() {
let store = DataStore::new();
let auth_server = AuthServer { store };

let request = AuthAnswerRequest {
auth_id: "invalid_challenge_id".to_string(),
s: "not_important_s".to_string(),
};

let result = auth_server
.verify_authentication(Request::new(request))
.await;

assert_eq!(result.unwrap_err().code(), tonic::Code::NotFound);
}

0 comments on commit b2119fb

Please sign in to comment.