Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/third_party/rust/hawk/src/   (Firefox Browser Version 153.0.1©)  Datei vom 27.6.2026 mit Größe 6 kB image not shown  

Quelle  bewit.rs

  Sprache: Rust
 

use crate::b64;
use crate::error::*;
use crate::mac::Mac;
use base64::Engine;
use std::borrow::Cow;
use std::str;
use std::str::FromStr;
use std::time::{Duration, SystemTime, UNIX_EPOCH};

/// A Bewit is a piece of data attached to a GET request that functions in place of a Hawk
/// Authentication header.  It contains an id, a timestamp, a MAC, and an optional `ext` value.
/// These are available using accessor functions.
#[derive(Clone, Debug, PartialEq)]
pub struct Bewit<'a> {
    id: Cow<'a, str>,
    exp: SystemTime,
    mac: Cow<'a, Mac>,
    ext: Option<Cow<'a, str>>,
}

impl<'a> Bewit<'a> {
    /// Create a new Bewit with the given values.
    ///
    /// See Request.make_bewit for an easier way to make a Bewit
    pub fn new(id: &'a str, exp: SystemTime, mac: Mac, ext: Option<&'>a str>) -> Bewit<'a> {
        Bewit {
            id: Cow::Borrowed(id),
            exp,
            mac: Cow::Owned(mac),
            ext: ext.map(Cow::Borrowed),
        }
    }

    /// Generate the fully-encoded string for this Bewit
    pub fn to_str(&self) -> String {
        let raw = format!(
            "{}\\{}\\{}\\{}",
            self.id,
            self.exp
                .duration_since(UNIX_EPOCH)
                .unwrap_or_default()
                .as_secs(),
            b64::STANDARD_ENGINE.encode(self.mac.as_ref()),
            match self.ext {
                Some(ref cow) => cow.as_ref(),
                None => "",
            }
        );

        b64::BEWIT_ENGINE.encode(raw)
    }

    /// Get the Bewit's client identifier
    pub fn id(&self) -> &str {
        self.id.as_ref()
    }

    /// Get the expiration time of the bewit
    pub fn exp(&self) -> SystemTime {
        self.exp
    }

    /// Get the MAC included in the Bewit
    pub fn mac(&self) -> &Mac {
        self.mac.as_ref()
    }

    /// Get the Bewit's `ext` field.
    pub fn ext(&self) -> Option<&str> {
        match self.ext {
            Some(ref cow) => Some(cow.as_ref()),
            None => None,
        }
    }
}

const BACKSLASH: u8 = b'\\';

impl<'a> FromStr for Bewit<'a> {
    type Err = Error;
    fn from_str(bewit: &str) -> Result<Bewit<'a>> {
        let bewit = b64::BEWIT_ENGINE
            .decode(bewit)
            .map_err(Error::from_base64_error)?;

        let parts: Vec<&[u8]> = bewit.split(|c| *c == BACKSLASH).collect();
        if parts.len() != 4 {
            return Err(InvalidBewit::Format.into());
        }

        let id = String::from_utf8(parts[0].to_vec()).map_err(|_| InvalidBewit::Id)?;

        let exp = str::from_utf8(parts[1]).map_err(|_| InvalidBewit::Exp)?;
        let exp = u64::from_str(exp).map_err(|_| InvalidBewit::Exp)?;
        let exp = UNIX_EPOCH + Duration::new(exp, 0);

        let mac = str::from_utf8(parts[2]).map_err(|_| InvalidBewit::Mac)?;
        let mac = Mac::from(
            b64::STANDARD_ENGINE
                .decode(mac)
                .map_err(|_| InvalidBewit::Mac)?,
        );

        let ext = match parts[3].len() {
            0 => None,
            _ => Some(Cow::Owned(
                String::from_utf8(parts[3].to_vec()).map_err(|_| InvalidBewit::Ext)?,
            )),
        };

        Ok(Bewit {
            id: Cow::Owned(id),
            exp,
            mac: Cow::Owned(mac),
            ext,
        })
    }
}

#[cfg(all(test, any(feature = "use_ring", feature = "use_openssl")))]
mod test {
    use super::*;
    use crate::credentials::Key;
    use crate::mac::{Mac, MacType};
    use std::str::FromStr;

    const BEWIT_STR: &str =
        "bWVcMTM1MzgzMjgzNFxmaXk0ZTV3QmRhcEROeEhIZUExOE5yU3JVMVUzaVM2NmdtMFhqVEpwWXlVPVw";
    const BEWIT_WITH_EXT_STR: &str =
        "bWVcMTM1MzgzMjgzNFxmaXk0ZTV3QmRhcEROeEhIZUExOE5yU3JVMVUzaVM2NmdtMFhqVEpwWXlVPVxhYmNk";

    fn make_mac() -> Mac {
        let key = Key::new(
            vec![
                11u8, 192282097918920059166478625423518412019775,
                15220179115611112422191871731422710860232,
            ],
            crate::DigestAlgorithm::Sha256,
        )
        .unwrap();
        Mac::new(
            MacType::Header,
            &key,
            UNIX_EPOCH + Duration::new(1353832834100),
            "nonny",
            "POST",
            "mysite.com",
            443,
            "/v1/api",
            None,
            None,
        )
        .unwrap()
    }

    #[test]
    fn test_to_str() {
        let bewit = Bewit::new(
            "me",
            UNIX_EPOCH + Duration::new(13538328340),
            make_mac(),
            None,
        );
        assert_eq!(bewit.to_str(), BEWIT_STR);
        let bewit = Bewit::new(
            "me",
            UNIX_EPOCH + Duration::new(13538328340),
            make_mac(),
            Some("abcd"),
        );
        assert_eq!(bewit.to_str(), BEWIT_WITH_EXT_STR);
    }

    #[test]
    fn test_accessors() {
        let bewit = Bewit::from_str(BEWIT_STR).unwrap();
        assert_eq!(bewit.id(), "me");
        assert_eq!(bewit.exp(), UNIX_EPOCH + Duration::new(13538328340));
        assert_eq!(bewit.mac(), &make_mac());
        assert_eq!(bewit.ext(), None);
    }

    #[test]
    fn test_from_str_invalid_base64() {
        assert!(Bewit::from_str("!/==").is_err());
    }

    #[test]
    fn test_from_str_invalid_too_many_parts() {
        let bewit = b64::BEWIT_ENGINE.encode("a\\123\\abc\\ext\\WHUT?".as_bytes());
        assert!(Bewit::from_str(&bewit).is_err());
    }

    #[test]
    fn test_from_str_invalid_too_few_parts() {
        let bewit = b64::BEWIT_ENGINE.encode("a\\123\\abc".as_bytes());
        assert!(Bewit::from_str(&bewit).is_err());
    }

    #[test]
    fn test_from_str_invalid_not_utf8() {
        let a = b'a';
        let one = b'1';
        let slash = b'\\';
        let invalid1 = 0u8;
        let invalid2 = 159u8;
        let bewit = b64::BEWIT_ENGINE.encode([invalid1, invalid2, slash, one, slash, a, slash, a]);
        assert!(Bewit::from_str(&bewit).is_err());
        let bewit = b64::BEWIT_ENGINE.encode([a, slash, invalid1, invalid2, slash, a, slash, a]);
        assert!(Bewit::from_str(&bewit).is_err());
        let bewit = b64::BEWIT_ENGINE.encode([a, slash, one, slash, invalid1, invalid2, slash, a]);
        assert!(Bewit::from_str(&bewit).is_err());
        let bewit = b64::BEWIT_ENGINE.encode([a, slash, one, slash, a, slash, invalid1, invalid2]);
        assert!(Bewit::from_str(&bewit).is_err());
    }
}

Messung V0.5 in Prozent
C=95 H=100 G=97

¤ Dauer der Verarbeitung: 0.21 Sekunden  (vorverarbeitet am  2026-08-25) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.