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 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
|
This patch is based on the commit described below taken from
https://github.com/mozilla-services/fernet-rs/pull/78
It was modified for use with fernet 0.1.4 in Debian by
Peter Michael Green.
commit 402c2a936b3baba17dc652f17cf72ba25dbc5ffd
Author: jrconlin <jr+git@mozilla.com>
Date: Mon Apr 3 09:03:45 2023 -0700
chore: 2303-update
Use latest base64 library
Index: fernet/Cargo.toml
===================================================================
--- fernet.orig/Cargo.toml
+++ fernet/Cargo.toml
@@ -23,7 +23,7 @@ repository = "https://github.com/mozilla
[package.metadata.docs.rs]
features = ["fernet_danger_timestamps"]
[dependencies.base64]
-version = "0.13"
+version = ">= 0.21, < 1.0"
[dependencies.byteorder]
version = "1"
Index: fernet/src/lib.rs
===================================================================
--- fernet.orig/src/lib.rs
+++ fernet/src/lib.rs
@@ -21,6 +21,7 @@ use std::fmt::{self, Display};
use std::io::{Cursor, Read};
use std::time;
use zeroize::Zeroize;
+use base64::Engine;
const MAX_CLOCK_SKEW: u64 = 60;
@@ -90,7 +91,7 @@ impl Fernet {
/// is recommended. DO NOT USE A HUMAN READABLE PASSWORD AS A KEY. Returns
/// `None` if the key is not 32-bytes base64 encoded.
pub fn new(key: &str) -> Option<Fernet> {
- let key = base64::decode_config(key, base64::URL_SAFE).ok()?;
+ let key = b64_decode_url(key).ok()?;
if key.len() != 32 {
return None;
}
@@ -111,7 +112,7 @@ impl Fernet {
pub fn generate_key() -> String {
let mut key: [u8; 32] = Default::default();
getrandom::getrandom(&mut key).expect("Error in getrandom");
- base64::encode_config(&key, base64::URL_SAFE)
+ crate::b64_encode_url(&key.to_vec())
}
/// Encrypts data into a token. Returns a value (which is base64-encoded) that can be
@@ -169,7 +170,7 @@ impl Fernet {
result.extend_from_slice(&hmac_signer.sign_to_vec().unwrap());
- base64::encode_config(&result, base64::URL_SAFE)
+ crate::b64_encode_url(&result)
}
/// Decrypts a ciphertext. Returns either `Ok(plaintext)` if decryption is
@@ -226,7 +227,7 @@ impl Fernet {
ttl: Option<u64>,
current_time: u64,
) -> Result<Vec<u8>, DecryptionError> {
- let data = match base64::decode_config(token, base64::URL_SAFE) {
+ let data = match b64_decode_url(token) {
Ok(data) => data,
Err(_) => return Err(DecryptionError),
};
@@ -374,19 +375,17 @@ mod tests {
#[test]
fn test_invalid() {
- let f = Fernet::new(&base64::encode_config(&vec![0; 32], base64::URL_SAFE)).unwrap();
+ let f = Fernet::new(&super::b64_encode_url(&vec![0; 32])).unwrap();
// Invalid version byte
assert_eq!(
- f.decrypt(&base64::encode_config(b"\x81", base64::URL_SAFE)),
+ f.decrypt(&crate::b64_encode_url(&b"\x81".to_vec())),
Err(DecryptionError)
);
// Timestamp too short
assert_eq!(
- f.decrypt(&base64::encode_config(
- b"\x80\x00\x00\x00",
- base64::URL_SAFE
- )),
+ f.decrypt(&super::b64_encode_url(
+ &b"\x80\x00\x00\x00".to_vec())),
Err(DecryptionError)
);
// Invalid base64
@@ -395,7 +394,7 @@ mod tests {
#[test]
fn test_roundtrips() {
- let f = Fernet::new(&base64::encode_config(&vec![0; 32], base64::URL_SAFE)).unwrap();
+ let f = Fernet::new(&super::b64_encode_url(&vec![0; 32])).unwrap();
for val in [b"".to_vec(), b"Abc".to_vec(), b"\x00\xFF\x00\x00".to_vec()].iter() {
assert_eq!(f.decrypt(&f.encrypt(&val)), Ok(val.clone()));
@@ -405,8 +404,8 @@ mod tests {
#[test]
fn test_new_errors() {
assert!(Fernet::new("axxx").is_none());
- assert!(Fernet::new(&base64::encode_config(&vec![0, 33], base64::URL_SAFE)).is_none());
- assert!(Fernet::new(&base64::encode_config(&vec![0, 31], base64::URL_SAFE)).is_none());
+ assert!(Fernet::new(&super::b64_encode_url(&vec![0, 33])).is_none());
+ assert!(Fernet::new(&super::b64_encode_url(&vec![0, 31])).is_none());
}
#[test]
@@ -505,3 +504,14 @@ mod tests {
);
}
}
+
+/// base64 had a habit of changing this a fair bit, so isolating these functions
+/// to reduce future code changes.
+///
+pub(crate) fn b64_decode_url(input: &str) -> std::result::Result<Vec<u8>, base64::DecodeError> {
+ base64::engine::general_purpose::URL_SAFE_NO_PAD.decode(input.trim_end_matches('='))
+}
+
+pub(crate) fn b64_encode_url(input: &Vec<u8>) -> String {
+ base64::engine::general_purpose::URL_SAFE.encode(input)
+}
|