diff --git a/Cargo.toml b/Cargo.toml index 64cf91e4..dd09f2d3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,14 +4,11 @@ version = "0.1.0" authors = ["Tim Bruijnzeels ", "Martin Hoffmann "] [dependencies] -base64 = "^0.9" -hyper = "0.12" +rpki = { git="https://github.com/NLnetLabs/rpki-rs.git" } +base64 = "^0.9" +bytes = "^0.4" +hyper = "0.12" futures = "0.1" failure = "^0.1" -xml-rs = "0.8.0" - -[features] -# Panic when a parsing error occurs. This feature is intended for -# development use exclusively and MUST NOT be enabled in release builds. -extra-debug = [] +xml-rs = "0.8.0" diff --git a/src/lib.rs b/src/lib.rs index 29d7bb0e..955e94af 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,7 +1,8 @@ +extern crate rpki; extern crate base64; +extern crate bytes; extern crate core; #[macro_use] extern crate failure; extern crate xml; -pub mod oob; -pub mod xml_support; \ No newline at end of file +mod provisioning; \ No newline at end of file diff --git a/src/oob.rs b/src/oob.rs deleted file mode 100644 index 53ebe5db..00000000 --- a/src/oob.rs +++ /dev/null @@ -1,119 +0,0 @@ -// -// Support for the RFC8183 out-of-band setup requests and responses -// used to exchange identity and configuration between CAs and their -// parent CA and/or RPKI Publication Servers. -// - -use std::io; -use std::path::Path; -use base64; -use xml_support::{XmlReader, XmlReaderErr}; -use xml_support::AttributesError; -use base64::DecodeError; - -/// Type representing a -/// -/// For more info see: https://tools.ietf.org/html/rfc8183#section-5.2.3 -#[derive(Debug)] -pub struct PublisherRequest { - tag: Option, - publisher_handle: String, - encoded_cert: Vec, -} - -impl PublisherRequest { - - pub fn open>(path: P) - -> Result { - - let mut r = XmlReader::open(path)?; - r.start_document()?; - - let att = r.expect_element("publisher_request")?; - - match att.get_opt("version") { - Some(version) => { - if version != "1".to_string() { - return Err(PublisherRequestError::InvalidVersion) - } - }, - _ => return Err(PublisherRequestError::InvalidVersion) - } - - let tag = att.get_opt("tag"); - let publisher_handle = att.get_req("publisher_handle")?; - - r.expect_element("publisher_bpki_ta")?; - - let base64_cert = r.expect_characters()?; - let encoded_cert = base64::decode_config(&base64_cert, base64::MIME)?; - - r.expect_close("publisher_bpki_ta")?; - r.expect_close("publisher_request")?; - r.end_document()?; - - Ok(PublisherRequest{tag, publisher_handle, encoded_cert}) - } - -} - -#[derive(Debug, Fail)] -pub enum PublisherRequestError { - - #[fail(display = "Invalid XML for Publisher Request")] - InvalidXml, - - #[fail(display = "Invalid version for Publisher Request")] - InvalidVersion, - - #[fail(display = "Could not parse XML file: {}", _0)] - FileError(io::Error), - - #[fail(display = "Invalid XML file: {}", _0)] - XmlReadError(XmlReaderErr), - - #[fail(display = "Invalid XML file: {}", _0)] - XmlAttributesError(AttributesError), - - #[fail(display = "Invalid base64: {}", _0)] - Base64Error(DecodeError) - -} - -impl From for PublisherRequestError { - fn from(e: io::Error) -> PublisherRequestError{ - PublisherRequestError::FileError(e) - } -} - -impl From for PublisherRequestError { - fn from(e: XmlReaderErr) -> PublisherRequestError{ - PublisherRequestError::XmlReadError(e) - } -} - -impl From for PublisherRequestError { - fn from(e: AttributesError) -> PublisherRequestError{ - PublisherRequestError::XmlAttributesError(e) - } -} - -impl From for PublisherRequestError { - fn from(e: DecodeError) -> PublisherRequestError { - PublisherRequestError::Base64Error(e) - } -} - - -#[cfg(test)] -mod tests { - use super::*; - - # [test] - fn test_parse_publisher_request() { - let pr = PublisherRequest::open("test/publisher_request.xml").unwrap(); - - assert_eq!("Bob", pr.publisher_handle); - assert_eq!(Some("A0001".to_string()), pr.tag); - } -} \ No newline at end of file diff --git a/src/provisioning/mod.rs b/src/provisioning/mod.rs new file mode 100644 index 00000000..655fd0eb --- /dev/null +++ b/src/provisioning/mod.rs @@ -0,0 +1,7 @@ +use rpki::remote::idcert::IdCert; + +/// This type defines Client CAs that are allowed to publish. +pub struct Client { + id: IdCert +} + diff --git a/src/xml_support.rs b/src/xml_support.rs deleted file mode 100644 index c38e3c28..00000000 --- a/src/xml_support.rs +++ /dev/null @@ -1,154 +0,0 @@ -// Some convenience stuff for handling the RPKI xml structures - -use std::{fs, io}; -use std::path::Path; -use xml::EventReader; -use xml::ParserConfig; -use xml::reader::XmlEvent; -use xml::attribute::OwnedAttribute; - -/// Wrapper for convenient XML parsing -/// -/// This type only exposes things we need for the RPKI XML structures. -pub struct XmlReader { - reader: EventReader -} - -impl XmlReader { - - pub fn create(source: R) -> Result { - let mut config = ParserConfig::new(); - config.trim_whitespace = true; - config.ignore_comments = true; - let reader = config.create_reader(source); - Ok(XmlReader{reader}) - } - - pub fn start_document(&mut self) -> Result { - match self.reader.next() { - Ok(XmlEvent::StartDocument {..}) => { Ok(true)}, - _ => return Err(XmlReaderErr::ExpectedStartDocument) - } - } - - pub fn expect_element( - &mut self, - exp: &str) -> Result { - match self.reader.next() { - Ok(XmlEvent::StartElement { name, attributes, ..}) => { - if name.local_name == exp { - Ok(Attributes{attributes}) - } else { - Err(XmlReaderErr::ExpectedStart(exp.to_string())) - } - }, - _ => return Err(XmlReaderErr::ExpectedStart(exp.to_string())) - } - } - - pub fn expect_close(&mut self, exp: &str) -> Result { - match self.reader.next() { - Ok(XmlEvent::EndElement { name, ..}) => { - if name.local_name == exp { - Ok(true) - } else { - Err(XmlReaderErr::ExpectedClose(exp.to_string())) - } - } - _ => Err(XmlReaderErr::ExpectedClose(exp.to_string())) - } - } - - pub fn expect_characters(&mut self) -> Result { - match self.reader.next() { - Ok(XmlEvent::Characters(chars)) => { Ok(chars) } - _ => return Err(XmlReaderErr::ExpectedCharacters) - } - } - - pub fn end_document(&mut self) -> Result { - match self.reader.next() { - Ok(XmlEvent::EndDocument) => Ok(true), - _ => Err(XmlReaderErr::ExpectedEnd) - } - } - - -} - -impl XmlReader { - pub fn open>(path: P) -> Result { - Self::create(fs::File::open(path)?) - } -} - -#[derive(Debug, Fail)] -pub enum XmlReaderErr { - - #[fail(display = "Expected Start of Document")] - ExpectedStartDocument, - - #[fail(display = "Expected Start Element with name: {}", _0)] - ExpectedStart(String), - - #[fail(display = "Expected Characters Element")] - ExpectedCharacters, - - #[fail(display = "Expected Close Element with name: {}", _0)] - ExpectedClose(String), - - #[fail(display = "Expected End of Document")] - ExpectedEnd -} - -/// Wrapper for XML tag attributes -pub struct Attributes { - attributes: Vec -} - -impl Attributes { - pub fn get_opt(&self, name: &str) -> Option { - self.attributes.iter() - .find(|a| a.name.local_name == name) - .map(|a| a.value.to_string()) - } - - pub fn get_req(&self, name: &str) -> Result { - self.get_opt(name) - .ok_or(AttributesError::MissingAttribute(name.to_string())) - } -} - -#[derive(Debug, Fail)] -pub enum AttributesError { - #[fail(display = "Required attribute missing: {}", _0)] - MissingAttribute(String), -} - - - -#[cfg(test)] -mod tests { - use super::*; - - # [test] - fn test_parse_publisher_request() { - let mut r = XmlReader::open("test/publisher_request.xml").unwrap(); - r.start_document().unwrap(); - let att = r.expect_element("publisher_request").unwrap(); - assert_eq!(Some("1".to_string()), att.get_opt("version")); - assert_eq!(Some("A0001".to_string()), att.get_opt("tag")); - assert_eq!(Some("Bob".to_string()), att.get_opt("publisher_handle")); - - let ta_att = r.expect_element("publisher_bpki_ta").unwrap(); - assert_eq!(0, ta_att.attributes.len()); - - let chars = r.expect_characters().unwrap(); - assert!(chars.starts_with("MIIDIDCCAg")); - - r.expect_close("publisher_bpki_ta").unwrap(); - r.expect_close("publisher_request").unwrap(); - - r.end_document().unwrap(); - } -} \ No newline at end of file diff --git a/test/publisher_request.xml b/test/publisher_request.xml deleted file mode 100644 index 24b920aa..00000000 --- a/test/publisher_request.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - MIIDIDCCAgigAwIBAgIBATANBgkqhkiG9w0BAQsFADApMScwJQYDVQQDEx5Cb2Ig - QlBLSSBSZXNvdXJjZSBUcnVzdCBBbmNob3IwHhcNMTEwNzAxMDQwNzIzWhcNMTIw - NjMwMDQwNzIzWjApMScwJQYDVQQDEx5Cb2IgQlBLSSBSZXNvdXJjZSBUcnVzdCBB - bmNob3IwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDEk1f7cVzHu3r/ - fJ5gkBxnWMNJ1CP0kPtfP8oFOEVVH1lX0MHuFKhdKA4WCkGkeFtGb/4T/nGgsD+z - exZid6RR8zjHkwMLvAl0x6wdKa46XJbFu+wTSu+vlowVY9rGzH+ttv4Fj6E2Y3DG - 983/dVNJfXl00+Ts7rlvVcn9lI5dWvzsLoUOdhD4hsyKp53k8i4HexiD+0ugPeh9 - 4PKiyZOuMjSRNQSBUA3ElqJSRZz7nWvs/j6zhwHdFa+lN56575Mc5mrwr+KePwW5 - DLt3izYpjwKffVuxUKPTrhvnOOg5kBBv0ihync21LSLds6jusxaMYUwUElO8KQyn - NUAeGPd/AgMBAAGjUzBRMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFORFOC3G - PjYKn7V1/BJHDmZ4W7J+MB8GA1UdIwQYMBaAFORFOC3GPjYKn7V1/BJHDmZ4W7J+ - MA0GCSqGSIb3DQEBCwUAA4IBAQBqsP4ENtWTkNdsekYB+4hO/Afq20Ho0W8lyTkM - JO1UFDt/dzFAmTT4uM7pmwuQfqmCYjNDWon8nsdFno4tA0is3aiq6yIMAYzBE5ub - bnJMxldqLoWuakco1wYa3kZFzWPwecxgJ4ZlqTPGu0Loyjibt25IE9MfixyWDw+D - MhyfonLLgFb5jz7A3BTE63vlTp359uDbFb1nRdyoT31s3FUBK8jF4B5pWzPiLdct - bOMVjYUBs8aFC3fDXyGSr/RcjE4OOZQyTkYZn8zCPUJ4KqOPAUV9u9jx2FPvOcA3 - 1BjcmhYHqott+cnK1ITOjLe9EKejRZv/7/BFsmpzm2Zbq1KA - - \ No newline at end of file