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
//! The `hawk` crate provides support for [Hawk](https://github.com/hueniverse/hawk)
//! authentictation. It is a low-level crate, used by higher-level crates to integrate with various
//! Rust HTTP libraries.  For example `hyper-hawk` integrates Hawk with Hyper.
//!
//! # Examples
//!
//! ## Hawk Client
//!
//! A client can attach a Hawk Authorization header to requests by providing credentials to a
//! Request instance, which will generate the header.
//!
//! ```
//! #[macro_use] extern crate pretty_assertions;
//! extern crate time;
//! extern crate hawk;
//!
//! use hawk::{RequestBuilder, Credentials, Key, SHA256, PayloadHasher};
//!
//! fn main() {
//!     // provide the Hawk id and key
//!     let credentials = Credentials {
//!         id: "test-client".to_string(),
//!         key: Key::new(vec![99u8; 32], &SHA256),
//!     };
//!
//!     let payload_hash = PayloadHasher::hash("text/plain", &SHA256, "request-body");
//!
//!     // provide the details of the request to be authorized
//!      let request = RequestBuilder::new("POST", "example.com", 80, "/v1/users")
//!         .hash(&payload_hash[..])
//!         .request();
//!
//!     // Get the resulting header, including the calculated MAC; this involves a random
//!     // nonce, so the MAC will be different on every request.
//!     let header = request.make_header(&credentials).unwrap();
//!
//!     // the header would the be attached to the request
//!     assert_eq!(header.id.unwrap(), "test-client");
//!     assert_eq!(header.mac.unwrap().len(), 32);
//!     assert_eq!(header.hash.unwrap().len(), 32);
//! }
//! ```
//!
//! ## Hawk Server
//!
//! To act as a server, parse the Hawk Authorization header from the request, generate a new
//! Request instance, and use the request to validate the header.
//!
//! ```
//! extern crate time;
//! extern crate hawk;
//!
//! use hawk::{RequestBuilder, Header, Key, SHA256};
//! use hawk::mac::Mac;
//!
//! fn main() {
//!    let mac = Mac::from(vec![7, 22, 226, 240, 84, 78, 49, 75, 115, 144, 70,
//!                             106, 102, 134, 144, 128, 225, 239, 95, 132, 202,
//!                             154, 213, 118, 19, 63, 183, 108, 215, 134, 118, 115]);
//!    // get the header (usually from the received request; constructed directly here)
//!    let hdr = Header::new(Some("dh37fgj492je"),
//!                          Some(time::Timespec::new(1353832234, 0)),
//!                          Some("j4h3g2"),
//!                          Some(mac),
//!                          Some("my-ext-value"),
//!                          Some(vec![1, 2, 3, 4]),
//!                          Some("my-app"),
//!                          Some("my-dlg")).unwrap();
//!
//!    // build a request object based on what we know
//!    let hash = vec![1, 2, 3, 4];
//!    let request = RequestBuilder::new("GET", "localhost", 443, "/resource")
//!        .hash(&hash[..])
//!        .request();
//!
//!    let key = Key::new(vec![99u8; 32], &SHA256);
//!    if !request.validate_header(&hdr, &key, time::Duration::weeks(5200)) {
//!        panic!("header validation failed. Is it 2117 already?");
//!    }
//! }
extern crate base64;
extern crate time;
extern crate ring;
extern crate url;
extern crate rand;

#[cfg(test)]
#[macro_use]
extern crate pretty_assertions;

#[macro_use]
extern crate error_chain;

mod header;
pub use header::Header;

mod credentials;
pub use credentials::{Credentials, Key};

mod request;
pub use request::{Request, RequestBuilder};

mod response;
pub use response::{Response, ResponseBuilder};

mod error;
pub use error::*;

mod payload;
pub use payload::PayloadHasher;

mod bewit;
pub use bewit::Bewit;

pub mod mac;

// convenience imports
pub use ring::digest::{SHA256, SHA384, SHA512};