1 //! Data structures for the API, shared between client and server. 2 3 mod admin; 4 pub use self::admin::*; 5 6 mod aspa; 7 pub use self::aspa::*; 8 9 mod ca; 10 pub use self::ca::*; 11 12 mod history; 13 pub use self::history::*; 14 15 mod provisioning; 16 pub use self::provisioning::*; 17 18 mod publication; 19 pub use self::publication::*; 20 21 mod roas; 22 pub use self::roas::*; 23 24 pub mod rrdp; 25 26 use std::{collections::HashMap, fmt, sync::Arc}; 27 28 use bytes::Bytes; 29 use serde::{Deserialize, Deserializer, Serialize, Serializer}; 30 31 use rpki::repository::{ 32 aspa::Aspa, cert::Cert, crl::Crl, crypto::KeyIdentifier, manifest::Manifest, resources::AsId, roa::Roa, 33 }; 34 35 use crate::{ 36 commons::{error::RoaDeltaError, util::sha256}, 37 daemon::ca::RouteAuthorization, 38 }; 39 40 // Some syntactic sugar to help this old coder's brain deal with the mess of Strings 41 pub type Message = String; 42 pub type Label = String; 43 pub type ArgKey = String; 44 pub type ArgVal = String; 45 46 //------------ Base64 -------------------------------------------------------- 47 48 /// This type contains a base64 encoded structure. The publication protocol 49 /// deals with objects in their base64 encoded form. 50 /// 51 /// Note that we store this in a Bytes to make it cheap to clone this. 52 #[derive(Clone, Debug, Eq, PartialEq)] 53 pub struct Base64(Bytes); 54 55 impl Base64 { from_content(content: &[u8]) -> Self56 pub fn from_content(content: &[u8]) -> Self { 57 Base64::from(base64::encode(content)) 58 } 59 60 /// Decodes into bytes (e.g. for saving to disk for rsync) to_bytes(&self) -> Bytes61 pub fn to_bytes(&self) -> Bytes { 62 Bytes::from(base64::decode(&self.0).unwrap()) 63 } 64 to_hex_hash(&self) -> String65 pub fn to_hex_hash(&self) -> String { 66 hex::encode(sha256(&self.to_bytes())) 67 } 68 to_encoded_hash(&self) -> HexEncodedHash69 pub fn to_encoded_hash(&self) -> HexEncodedHash { 70 HexEncodedHash::from(self.to_hex_hash()) 71 } 72 size(&self) -> usize73 pub fn size(&self) -> usize { 74 self.0.len() 75 } 76 } 77 78 impl AsRef<str> for Base64 { as_ref(&self) -> &str79 fn as_ref(&self) -> &str { 80 use std::str; 81 str::from_utf8(&self.0).unwrap() 82 } 83 } 84 85 impl From<String> for Base64 { from(s: String) -> Self86 fn from(s: String) -> Self { 87 Base64(Bytes::from(s)) 88 } 89 } 90 91 impl From<&Cert> for Base64 { from(cert: &Cert) -> Self92 fn from(cert: &Cert) -> Self { 93 Base64::from_content(&cert.to_captured().into_bytes()) 94 } 95 } 96 97 impl From<&Roa> for Base64 { from(roa: &Roa) -> Self98 fn from(roa: &Roa) -> Self { 99 Base64::from_content(&roa.to_captured().into_bytes()) 100 } 101 } 102 103 impl From<&Aspa> for Base64 { from(aspa: &Aspa) -> Self104 fn from(aspa: &Aspa) -> Self { 105 Base64::from_content(&aspa.to_captured().into_bytes()) 106 } 107 } 108 109 impl From<&Manifest> for Base64 { from(mft: &Manifest) -> Self110 fn from(mft: &Manifest) -> Self { 111 Base64::from_content(&mft.to_captured().into_bytes()) 112 } 113 } 114 115 impl From<&Crl> for Base64 { from(crl: &Crl) -> Self116 fn from(crl: &Crl) -> Self { 117 Base64::from_content(&crl.to_captured().into_bytes()) 118 } 119 } 120 121 impl fmt::Display for Base64 { fmt(&self, f: &mut fmt::Formatter) -> fmt::Result122 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 123 write!(f, "{}", unsafe { std::str::from_utf8_unchecked(self.0.as_ref()) }) 124 } 125 } 126 127 impl Serialize for Base64 { serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer,128 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> 129 where 130 S: Serializer, 131 { 132 self.to_string().serialize(serializer) 133 } 134 } 135 136 impl<'de> Deserialize<'de> for Base64 { deserialize<D>(deserializer: D) -> Result<Base64, D::Error> where D: Deserializer<'de>,137 fn deserialize<D>(deserializer: D) -> Result<Base64, D::Error> 138 where 139 D: Deserializer<'de>, 140 { 141 let string = String::deserialize(deserializer)?; 142 Ok(Base64::from(string)) 143 } 144 } 145 146 //------------ HexEncodedHash ------------------------------------------------ 147 148 /// This type contains a hex encoded sha256 hash. 149 #[derive(Clone, Debug, Eq, Hash, PartialEq)] 150 pub struct HexEncodedHash(Arc<str>); 151 152 impl HexEncodedHash { from_content(content: &[u8]) -> Self153 pub fn from_content(content: &[u8]) -> Self { 154 let sha256 = sha256(content); 155 let hex = hex::encode(sha256); 156 HexEncodedHash(hex.into()) 157 } 158 as_bytes(&self) -> Bytes159 pub fn as_bytes(&self) -> Bytes { 160 Bytes::from(self.to_string()) 161 } 162 } 163 164 impl AsRef<str> for HexEncodedHash { as_ref(&self) -> &str165 fn as_ref(&self) -> &str { 166 &self.0 167 } 168 } 169 170 impl AsRef<[u8]> for HexEncodedHash { as_ref(&self) -> &[u8]171 fn as_ref(&self) -> &[u8] { 172 self.0.as_bytes() 173 } 174 } 175 176 impl From<&Crl> for HexEncodedHash { from(crl: &Crl) -> Self177 fn from(crl: &Crl) -> Self { 178 Self::from_content(crl.to_captured().as_slice()) 179 } 180 } 181 182 impl From<&Manifest> for HexEncodedHash { from(mft: &Manifest) -> Self183 fn from(mft: &Manifest) -> Self { 184 Self::from_content(mft.to_captured().as_slice()) 185 } 186 } 187 188 impl From<&Cert> for HexEncodedHash { from(cert: &Cert) -> Self189 fn from(cert: &Cert) -> Self { 190 Self::from_content(cert.to_captured().as_slice()) 191 } 192 } 193 194 impl From<String> for HexEncodedHash { from(s: String) -> Self195 fn from(s: String) -> Self { 196 HexEncodedHash(s.into()) 197 } 198 } 199 200 impl Serialize for HexEncodedHash { serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer,201 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> 202 where 203 S: Serializer, 204 { 205 self.0.serialize(serializer) 206 } 207 } 208 209 impl<'de> Deserialize<'de> for HexEncodedHash { deserialize<D>(deserializer: D) -> Result<HexEncodedHash, D::Error> where D: Deserializer<'de>,210 fn deserialize<D>(deserializer: D) -> Result<HexEncodedHash, D::Error> 211 where 212 D: Deserializer<'de>, 213 { 214 let string = String::deserialize(deserializer)?; 215 Ok(HexEncodedHash(string.into())) 216 } 217 } 218 219 impl fmt::Display for HexEncodedHash { fmt(&self, f: &mut fmt::Formatter) -> fmt::Result220 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 221 write!(f, "{}", self.0) 222 } 223 } 224 225 //------------ ErrorResponse -------------------------------------------------- 226 227 /// Defines an error response. Codes are unique and documented here: 228 /// https://rpki.readthedocs.io/en/latest/krill/pub/api.html#error-responses 229 #[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)] 230 pub struct ErrorResponse { 231 label: String, 232 msg: String, 233 args: HashMap<String, String>, 234 #[serde(skip_serializing_if = "Option::is_none")] 235 delta_error: Option<RoaDeltaError>, 236 #[serde(skip_serializing_if = "Option::is_none")] 237 aspa_providers_update_conflict: Option<AspaProvidersUpdateConflict>, 238 } 239 240 impl ErrorResponse { new(label: &str, msg: impl fmt::Display) -> Self241 pub fn new(label: &str, msg: impl fmt::Display) -> Self { 242 ErrorResponse { 243 label: label.to_string(), 244 msg: msg.to_string(), 245 args: HashMap::new(), 246 delta_error: None, 247 aspa_providers_update_conflict: None, 248 } 249 } 250 delta_error(&self) -> Option<&RoaDeltaError>251 pub fn delta_error(&self) -> Option<&RoaDeltaError> { 252 self.delta_error.as_ref() 253 } 254 with_arg(mut self, key: &str, value: impl fmt::Display) -> Self255 fn with_arg(mut self, key: &str, value: impl fmt::Display) -> Self { 256 self.args.insert(key.to_string(), value.to_string()); 257 self 258 } 259 with_cause(self, cause: impl fmt::Display) -> Self260 pub fn with_cause(self, cause: impl fmt::Display) -> Self { 261 self.with_arg("cause", cause) 262 } 263 with_publisher(self, publisher: &PublisherHandle) -> Self264 pub fn with_publisher(self, publisher: &PublisherHandle) -> Self { 265 self.with_arg("publisher", publisher) 266 } 267 with_uri(self, uri: impl fmt::Display) -> Self268 pub fn with_uri(self, uri: impl fmt::Display) -> Self { 269 self.with_arg("uri", uri) 270 } 271 with_base_uri(self, base_uri: impl fmt::Display) -> Self272 pub fn with_base_uri(self, base_uri: impl fmt::Display) -> Self { 273 self.with_arg("base_uri", base_uri) 274 } 275 with_ca(self, ca: &Handle) -> Self276 pub fn with_ca(self, ca: &Handle) -> Self { 277 self.with_arg("ca", ca) 278 } 279 with_parent(self, parent: &ParentHandle) -> Self280 pub fn with_parent(self, parent: &ParentHandle) -> Self { 281 self.with_arg("parent", parent) 282 } 283 with_child(self, child: &ChildHandle) -> Self284 pub fn with_child(self, child: &ChildHandle) -> Self { 285 self.with_arg("child", child) 286 } 287 with_auth(self, auth: &RouteAuthorization) -> Self288 pub fn with_auth(self, auth: &RouteAuthorization) -> Self { 289 let mut res = self.with_arg("prefix", auth.prefix()).with_arg("asn", auth.asn()); 290 291 if let Some(max) = auth.max_length() { 292 res = res.with_arg("max_length", max) 293 } 294 295 res 296 } 297 with_asn(self, asn: AsId) -> Self298 pub fn with_asn(self, asn: AsId) -> Self { 299 self.with_arg("asn", asn) 300 } 301 with_roa_delta_error(mut self, roa_delta_error: &RoaDeltaError) -> Self302 pub fn with_roa_delta_error(mut self, roa_delta_error: &RoaDeltaError) -> Self { 303 self.delta_error = Some(roa_delta_error.clone()); 304 self 305 } 306 with_aspa_providers_conflict(mut self, conflict: &AspaProvidersUpdateConflict) -> Self307 pub fn with_aspa_providers_conflict(mut self, conflict: &AspaProvidersUpdateConflict) -> Self { 308 self.aspa_providers_update_conflict = Some(conflict.clone()); 309 self 310 } 311 with_key_identifier(self, ki: &KeyIdentifier) -> Self312 pub fn with_key_identifier(self, ki: &KeyIdentifier) -> Self { 313 self.with_arg("key_id", ki) 314 } 315 with_resource_class(self, class_name: &ResourceClassName) -> Self316 pub fn with_resource_class(self, class_name: &ResourceClassName) -> Self { 317 self.with_arg("class_name", class_name) 318 } 319 label(&self) -> &str320 pub fn label(&self) -> &str { 321 &self.label 322 } msg(&self) -> &str323 pub fn msg(&self) -> &str { 324 &self.msg 325 } 326 } 327 328 impl fmt::Display for ErrorResponse { fmt(&self, f: &mut fmt::Formatter) -> fmt::Result329 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 330 write!(f, "{}", &serde_json::to_string(&self).unwrap()) 331 } 332 } 333