diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/handlers.rs | 136 | ||||
| -rw-r--r-- | src/schema.rs | 2 |
2 files changed, 123 insertions, 15 deletions
diff --git a/src/handlers.rs b/src/handlers.rs index 848cb75..515caa5 100644 --- a/src/handlers.rs +++ b/src/handlers.rs | |||
| @@ -60,9 +60,9 @@ const BEARER: &str = "Bearer "; | |||
| 60 | /// public_key: "---BEGIN PUBLIC KEY..." | 60 | /// public_key: "---BEGIN PUBLIC KEY..." |
| 61 | /// } | 61 | /// } |
| 62 | /// | 62 | /// |
| 63 | /// - Encrypts the serialized string of `auth_plaintext` with 128 bit block AES in CBC mode with Pkcs7 padding using the temporary key (`k_temp`), the result is `auth_ciphertext` TODO should this be base64'd? | 63 | /// - Encrypts the serialized string of `auth_plaintext` with 128 bit block AES in CBC mode with Pkcs7 padding using the temporary key (`k_temp`), the result is `auth_ciphertext` |
| 64 | /// - The temporary key student has picked `k_temp` is encrypted using RSA with OAEP padding scheme | 64 | /// - The temporary key student has picked `k_temp` is encrypted using RSA with OAEP padding scheme |
| 65 | /// using sha256 with `gradecoin_public_key` (TODO base64? same as above), giving us `key_ciphertext` | 65 | /// using sha256 with `gradecoin_public_key`, giving us `key_ciphertext` |
| 66 | /// - The payload JSON object (`auth_request`) can be JSON serialized now: | 66 | /// - The payload JSON object (`auth_request`) can be JSON serialized now: |
| 67 | /// { | 67 | /// { |
| 68 | /// c: "auth_ciphertext" | 68 | /// c: "auth_ciphertext" |
| @@ -103,18 +103,126 @@ pub async fn authenticate_user( | |||
| 103 | let gradecoin_private_key = RSAPrivateKey::from_pkcs1(&der_bytes).expect("failed to parse key"); | 103 | let gradecoin_private_key = RSAPrivateKey::from_pkcs1(&der_bytes).expect("failed to parse key"); |
| 104 | 104 | ||
| 105 | let padding = PaddingScheme::new_oaep::<sha2::Sha256>(); | 105 | let padding = PaddingScheme::new_oaep::<sha2::Sha256>(); |
| 106 | let temp_key = gradecoin_private_key | 106 | |
| 107 | .decrypt(padding, &request.key.as_bytes()) | 107 | let key_ciphertext = match base64::decode(&request.key) { |
| 108 | .expect("failed to decrypt"); | 108 | Ok(c) => c, |
| 109 | 109 | Err(err) => { | |
| 110 | // decrypt c using key dec_key | 110 | debug!( |
| 111 | let cipher = Aes128Cbc::new_var(&temp_key, &request.iv.as_bytes()).unwrap(); | 111 | "The ciphertext of the key was not base64 encoded {}, {}", |
| 112 | let auth_plaintext = cipher | 112 | &request.key, err |
| 113 | .decrypt_vec(&base64::decode(request.c).unwrap()) | 113 | ); |
| 114 | .unwrap(); | 114 | |
| 115 | 115 | let res_json = warp::reply::json(&GradeCoinResponse { | |
| 116 | let request: AuthRequest = | 116 | res: ResponseType::Error, |
| 117 | serde_json::from_str(&String::from_utf8(auth_plaintext).unwrap()).unwrap(); | 117 | message: "The ciphertext of the key was not base64 encoded {}, {}".to_owned(), |
| 118 | }); | ||
| 119 | |||
| 120 | return Ok(warp::reply::with_status(res_json, StatusCode::BAD_REQUEST)); | ||
| 121 | } | ||
| 122 | }; | ||
| 123 | |||
| 124 | let temp_key = match gradecoin_private_key.decrypt(padding, &key_ciphertext) { | ||
| 125 | Ok(k) => k, | ||
| 126 | Err(err) => { | ||
| 127 | debug!( | ||
| 128 | "Failed to decrypt ciphertext {:?}, {}", | ||
| 129 | &key_ciphertext, err | ||
| 130 | ); | ||
| 131 | |||
| 132 | let res_json = warp::reply::json(&GradeCoinResponse { | ||
| 133 | res: ResponseType::Error, | ||
| 134 | message: "Failed to decrypt the ciphertext of the temporary key".to_owned(), | ||
| 135 | }); | ||
| 136 | |||
| 137 | return Ok(warp::reply::with_status(res_json, StatusCode::BAD_REQUEST)); | ||
| 138 | } | ||
| 139 | }; | ||
| 140 | |||
| 141 | let cipher = match Aes128Cbc::new_var(&temp_key, &request.iv.as_bytes()) { | ||
| 142 | Ok(c) => c, | ||
| 143 | Err(err) => { | ||
| 144 | debug!( | ||
| 145 | "Could not create a cipher from temp_key and request.iv {:?}, {}, {}", | ||
| 146 | &temp_key, &request.iv, err | ||
| 147 | ); | ||
| 148 | |||
| 149 | let res_json = warp::reply::json(&GradeCoinResponse { | ||
| 150 | res: ResponseType::Error, | ||
| 151 | message: "Given IV has invalid length".to_owned(), | ||
| 152 | }); | ||
| 153 | |||
| 154 | return Ok(warp::reply::with_status(res_json, StatusCode::BAD_REQUEST)); | ||
| 155 | } | ||
| 156 | }; | ||
| 157 | |||
| 158 | let auth_packet = match base64::decode(&request.c) { | ||
| 159 | Ok(a) => a, | ||
| 160 | |||
| 161 | Err(err) => { | ||
| 162 | debug!( | ||
| 163 | "The auth_packet (c field) did not base64 decode {} {}", | ||
| 164 | &request.c, err | ||
| 165 | ); | ||
| 166 | |||
| 167 | let res_json = warp::reply::json(&GradeCoinResponse { | ||
| 168 | res: ResponseType::Error, | ||
| 169 | message: "The c field was not correctly base64 encoded".to_owned(), | ||
| 170 | }); | ||
| 171 | |||
| 172 | return Ok(warp::reply::with_status(res_json, StatusCode::BAD_REQUEST)); | ||
| 173 | } | ||
| 174 | }; | ||
| 175 | |||
| 176 | let auth_plaintext = match cipher.decrypt_vec(&auth_packet) { | ||
| 177 | Ok(p) => p, | ||
| 178 | Err(err) => { | ||
| 179 | debug!( | ||
| 180 | "Base64 decoded auth request did not decrypt correctly {:?} {}", | ||
| 181 | &auth_packet, err | ||
| 182 | ); | ||
| 183 | |||
| 184 | let res_json = warp::reply::json(&GradeCoinResponse { | ||
| 185 | res: ResponseType::Error, | ||
| 186 | message: "The Bas64 decoded auth request did not decrypt correctly".to_owned(), | ||
| 187 | }); | ||
| 188 | |||
| 189 | return Ok(warp::reply::with_status(res_json, StatusCode::BAD_REQUEST)); | ||
| 190 | } | ||
| 191 | }; | ||
| 192 | |||
| 193 | let utf8_auth_plaintext = match String::from_utf8(auth_plaintext.clone()) { | ||
| 194 | Ok(text) => text, | ||
| 195 | Err(err) => { | ||
| 196 | debug!( | ||
| 197 | "Auth plaintext did not convert into utf8 {:?} {}", | ||
| 198 | &auth_plaintext, err | ||
| 199 | ); | ||
| 200 | |||
| 201 | let res_json = warp::reply::json(&GradeCoinResponse { | ||
| 202 | res: ResponseType::Error, | ||
| 203 | message: "Auth plaintext couldn't get converted to UTF-8".to_owned(), | ||
| 204 | }); | ||
| 205 | |||
| 206 | return Ok(warp::reply::with_status(res_json, StatusCode::BAD_REQUEST)); | ||
| 207 | } | ||
| 208 | }; | ||
| 209 | |||
| 210 | let request: AuthRequest = match serde_json::from_str(&utf8_auth_plaintext) { | ||
| 211 | Ok(req) => req, | ||
| 212 | Err(err) => { | ||
| 213 | debug!( | ||
| 214 | "Auth plaintext did not serialize correctly {:?} {}", | ||
| 215 | &utf8_auth_plaintext, err | ||
| 216 | ); | ||
| 217 | |||
| 218 | let res_json = warp::reply::json(&GradeCoinResponse { | ||
| 219 | res: ResponseType::Error, | ||
| 220 | message: "The auth request JSON did not serialize correctly".to_owned(), | ||
| 221 | }); | ||
| 222 | |||
| 223 | return Ok(warp::reply::with_status(res_json, StatusCode::BAD_REQUEST)); | ||
| 224 | } | ||
| 225 | }; | ||
| 118 | 226 | ||
| 119 | let provided_id = request.student_id.clone(); | 227 | let provided_id = request.student_id.clone(); |
| 120 | 228 | ||
diff --git a/src/schema.rs b/src/schema.rs index 6f2f1f3..dca0eef 100644 --- a/src/schema.rs +++ b/src/schema.rs | |||
| @@ -163,7 +163,7 @@ impl Block { | |||
| 163 | Block { | 163 | Block { |
| 164 | transaction_list: vec!["gradecoin_bank".to_owned()], | 164 | transaction_list: vec!["gradecoin_bank".to_owned()], |
| 165 | nonce: 0, | 165 | nonce: 0, |
| 166 | timestamp: NaiveDate::from_ymd(2021, 04, 11).and_hms(20, 45, 00), | 166 | timestamp: NaiveDate::from_ymd(2021, 4, 11).and_hms(20, 45, 00), |
| 167 | hash: String::from("not_actually_mined"), | 167 | hash: String::from("not_actually_mined"), |
| 168 | } | 168 | } |
| 169 | } | 169 | } |
