oxedyne/fe2o3/fe2o3_iop_crypto/src/sign.rs
10.3 KiB, 47 runs
created by r1870400018:387, which is this file's identity for as long as the history lasts, whatever it is later renamed to
download · who wrote it · its history
| 1 | use crate::keys::KeyManager; |
| 2 | |
| 3 | use oxedyne_fe2o3_core::{ |
| 4 | prelude::*, |
| 5 | alt::{ |
| 6 | Alt, |
| 7 | DefAlt, |
| 8 | }, |
| 9 | }; |
| 10 | use oxedyne_fe2o3_namex::id::{ |
| 11 | LocalId, |
| 12 | InNamex, |
| 13 | NamexId, |
| 14 | }; |
| 15 | |
| 16 | /// One signature to check, in the form a batch wants it. |
| 17 | /// |
| 18 | /// Each item carries its own public key, because a batch is not a batch of one |
| 19 | /// signer: a version control history is signed by everyone who has written to |
| 20 | /// it, and the point of checking many at once is lost if they must first be |
| 21 | /// sorted by author. |
| 22 | #[derive(Clone, Copy, Debug)] |
| 23 | pub struct BatchItem<'a> { |
| 24 | /// The public key of whoever signed, as the scheme encodes it. |
| 25 | pub public: &'a [u8], |
| 26 | /// The bytes that were signed. |
| 27 | pub msg: &'a [u8], |
| 28 | /// The detached signature over `msg`. |
| 29 | pub sig: &'a [u8], |
| 30 | } |
| 31 | |
| 32 | pub trait Signer: |
| 33 | KeyManager |
| 34 | + Clone |
| 35 | + std::fmt::Debug |
| 36 | + InNamex |
| 37 | + Send |
| 38 | + Sync |
| 39 | { |
| 40 | /// Return a detached signature for the given message. |
| 41 | fn sign(&self, msg: &[u8]) -> Outcome<Vec<u8>>; |
| 42 | /// Verify the validity of the given detached signature for the given message. |
| 43 | fn verify(&self, msg: &[u8], sig: &[u8]) -> Outcome<bool>; |
| 44 | |
| 45 | /// Verify many signatures, each against the public key its item carries, |
| 46 | /// and report whether every one of them holds. |
| 47 | /// |
| 48 | /// This is an optimisation and nothing more. A scheme that has a batch |
| 49 | /// verification equation may check the whole set for far less than the sum |
| 50 | /// of the parts; the default here simply checks them one at a time, so an |
| 51 | /// implementation that has nothing better to offer need do nothing. |
| 52 | /// |
| 53 | /// # What a `false` does and does not tell the caller |
| 54 | /// |
| 55 | /// It says that the set does not hold. It does not say which member of it |
| 56 | /// failed, and a scheme verifying the set as a whole cannot say. A caller |
| 57 | /// that must name the culprit -- and one refusing a history should -- falls |
| 58 | /// back to [`Signer::verify`] over the items to find it. The same goes for |
| 59 | /// an error: a batch that could not be attempted says so without saying |
| 60 | /// which item could not be attempted. |
| 61 | /// |
| 62 | /// # An empty batch |
| 63 | /// |
| 64 | /// Holds, vacuously. There is nothing in it that does not verify. |
| 65 | fn verify_batch(&self, items: &[BatchItem<'_>]) |
| 66 | -> Outcome<bool> |
| 67 | where Self: Sized |
| 68 | { |
| 69 | verify_each(self, items) |
| 70 | } |
| 71 | } |
| 72 | |
| 73 | /// Verifies the items one at a time, stopping at the first that does not hold. |
| 74 | /// |
| 75 | /// The body of [`Signer::verify_batch`]'s default, exposed so that an |
| 76 | /// implementation which is faster for some of its schemes and not for others |
| 77 | /// can hand the rest here rather than writing the loop again. |
| 78 | pub fn verify_each<S: Signer>(scheme: &S, items: &[BatchItem<'_>]) |
| 79 | -> Outcome<bool> |
| 80 | { |
| 81 | for item in items { |
| 82 | let bound = res!(scheme.clone_with_keys(Some(item.public), None)); |
| 83 | if !res!(bound.verify(item.msg, item.sig)) { |
| 84 | return Ok(false); |
| 85 | } |
| 86 | } |
| 87 | Ok(true) |
| 88 | } |
| 89 | |
| 90 | #[derive(Clone, Debug, Default)] |
| 91 | pub struct SignerDefAlt< |
| 92 | D: Signer, |
| 93 | G: Signer, |
| 94 | >( |
| 95 | pub DefAlt<D, G>, |
| 96 | ); |
| 97 | |
| 98 | impl< |
| 99 | D: Signer, |
| 100 | G: Signer, |
| 101 | > |
| 102 | std::ops::Deref for SignerDefAlt<D, G> |
| 103 | { |
| 104 | type Target = DefAlt<D, G>; |
| 105 | fn deref(&self) -> &Self::Target { &self.0 } |
| 106 | } |
| 107 | |
| 108 | impl< |
| 109 | D: Signer, |
| 110 | G: Signer, |
| 111 | > |
| 112 | From<Option<G>> for SignerDefAlt<D, G> |
| 113 | { |
| 114 | fn from(opt: Option<G>) -> Self { |
| 115 | Self( |
| 116 | DefAlt::from(opt), |
| 117 | ) |
| 118 | } |
| 119 | } |
| 120 | |
| 121 | impl< |
| 122 | D: Signer, |
| 123 | G: Signer, |
| 124 | > |
| 125 | From<Alt<G>> for SignerDefAlt<D, G> |
| 126 | { |
| 127 | fn from(alt: Alt<G>) -> Self { |
| 128 | Self( |
| 129 | DefAlt::from(alt), |
| 130 | ) |
| 131 | } |
| 132 | } |
| 133 | |
| 134 | impl< |
| 135 | D: Signer, |
| 136 | G: Signer, |
| 137 | > |
| 138 | InNamex for SignerDefAlt<D, G> |
| 139 | { |
| 140 | fn name_id(&self) -> Outcome<NamexId> { |
| 141 | match &self.0 { |
| 142 | DefAlt::Default(inner) => inner.name_id(), |
| 143 | DefAlt::Given(inner) => inner.name_id(), |
| 144 | DefAlt::None => Err(err!( |
| 145 | "No Namex id can be specified for DefAlt::None."; |
| 146 | Missing, Bug)), |
| 147 | } |
| 148 | } |
| 149 | |
| 150 | fn local_id(&self) -> LocalId { |
| 151 | match &self.0 { |
| 152 | DefAlt::Default(inner) => inner.local_id(), |
| 153 | DefAlt::Given(inner) => inner.local_id(), |
| 154 | DefAlt::None => LocalId::default(), |
| 155 | } |
| 156 | } |
| 157 | |
| 158 | fn assoc_names_base64( |
| 159 | gname: &'static str, |
| 160 | ) |
| 161 | -> Outcome<Option<Vec<( |
| 162 | &'static str, |
| 163 | &'static str, |
| 164 | )>>> |
| 165 | { |
| 166 | match res!(D::assoc_names_base64(gname)) { |
| 167 | Some(mut vd) => match res!(G::assoc_names_base64(gname)) { |
| 168 | Some(vg) => { |
| 169 | vd.extend(vg); |
| 170 | Ok(Some(vd)) |
| 171 | }, |
| 172 | None => Ok(Some(vd)), |
| 173 | }, |
| 174 | None => match res!(G::assoc_names_base64(gname)) { |
| 175 | Some(vg) => Ok(Some(vg)), |
| 176 | None => Ok(None), |
| 177 | }, |
| 178 | } |
| 179 | } |
| 180 | } |
| 181 | |
| 182 | impl< |
| 183 | G: Signer, |
| 184 | D: Signer, |
| 185 | > |
| 186 | Signer for SignerDefAlt<D, G> |
| 187 | { |
| 188 | fn sign(&self, msg: &[u8]) -> Outcome<Vec<u8>> { |
| 189 | match &self.0 { |
| 190 | DefAlt::Default(inner) => inner.sign(msg), |
| 191 | DefAlt::Given(inner) => inner.sign(msg), |
| 192 | DefAlt::None => Err(err!( |
| 193 | "Can't sign, signature not specified."; |
| 194 | Configuration, Missing)), |
| 195 | } |
| 196 | } |
| 197 | |
| 198 | fn verify(&self, msg: &[u8], sig: &[u8]) -> Outcome<bool> { |
| 199 | match &self.0 { |
| 200 | DefAlt::Default(inner) => inner.verify(msg, sig), |
| 201 | DefAlt::Given(inner) => inner.verify(msg, sig), |
| 202 | DefAlt::None => Err(err!( |
| 203 | "Can't verify, signature not specified."; |
| 204 | Configuration, Missing)), |
| 205 | } |
| 206 | } |
| 207 | |
| 208 | /// Hands the batch to whichever scheme is in force, rather than taking the |
| 209 | /// default, so that an inner scheme's batch equation is not lost behind the |
| 210 | /// wrapper. |
| 211 | fn verify_batch(&self, items: &[BatchItem<'_>]) |
| 212 | -> Outcome<bool> |
| 213 | where Self: Sized |
| 214 | { |
| 215 | match &self.0 { |
| 216 | DefAlt::Default(inner) => inner.verify_batch(items), |
| 217 | DefAlt::Given(inner) => inner.verify_batch(items), |
| 218 | DefAlt::None => Err(err!( |
| 219 | "Can't verify, signature not specified."; |
| 220 | Configuration, Missing)), |
| 221 | } |
| 222 | } |
| 223 | |
| 224 | } |
| 225 | |
| 226 | impl< |
| 227 | G: Signer, |
| 228 | D: Signer, |
| 229 | > |
| 230 | KeyManager for SignerDefAlt<D, G> |
| 231 | { |
| 232 | fn clone_with_keys(&self, pk: Option<&[u8]>, sk: Option<&[u8]>) -> Outcome<Self> { |
| 233 | Ok(match &self.0 { |
| 234 | DefAlt::Default(inner) => Self( |
| 235 | DefAlt::Default(res!(inner.clone_with_keys(pk, sk))), |
| 236 | ), |
| 237 | DefAlt::Given(inner) => Self( |
| 238 | DefAlt::Given(res!(inner.clone_with_keys(pk, sk))), |
| 239 | ), |
| 240 | DefAlt::None => Self( |
| 241 | DefAlt::None, // TODO should this be an error? |
| 242 | ), |
| 243 | }) |
| 244 | } |
| 245 | |
| 246 | fn get_public_key(&self) -> Outcome<Option<&[u8]>> { |
| 247 | match &self.0 { |
| 248 | DefAlt::Default(inner) => inner.get_public_key(), |
| 249 | DefAlt::Given(inner) => inner.get_public_key(), |
| 250 | DefAlt::None => Err(err!( |
| 251 | "Can't get public key, signature not specified."; |
| 252 | Configuration, Missing)), |
| 253 | } |
| 254 | } |
| 255 | |
| 256 | fn get_secret_key(&self) -> Outcome<Option<&[u8]>> { |
| 257 | match &self.0 { |
| 258 | DefAlt::Default(inner) => inner.get_secret_key(), |
| 259 | DefAlt::Given(inner) => inner.get_secret_key(), |
| 260 | DefAlt::None => Err(err!( |
| 261 | "Can't get secret key, signature not specified."; |
| 262 | Configuration, Missing)), |
| 263 | } |
| 264 | } |
| 265 | |
| 266 | fn set_public_key(self, pk: Option<&[u8]>) -> Outcome<Self> { |
| 267 | match self.0 { |
| 268 | DefAlt::Default(inner) => Ok(Self( |
| 269 | DefAlt::Default(res!(inner.set_public_key(pk))), |
| 270 | )), |
| 271 | DefAlt::Given(inner) => Ok(Self( |
| 272 | DefAlt::Given(res!(inner.set_public_key(pk))), |
| 273 | )), |
| 274 | DefAlt::None => Err(err!( |
| 275 | "Can't set public key, signature not specified."; |
| 276 | Configuration, Missing)), |
| 277 | } |
| 278 | } |
| 279 | |
| 280 | fn set_secret_key(self, sk: Option<&[u8]>) -> Outcome<Self> { |
| 281 | match self.0 { |
| 282 | DefAlt::Default(inner) => Ok(Self( |
| 283 | DefAlt::Default(res!(inner.set_secret_key(sk))), |
| 284 | )), |
| 285 | DefAlt::Given(inner) => Ok(Self( |
| 286 | DefAlt::Given(res!(inner.set_secret_key(sk))), |
| 287 | )), |
| 288 | DefAlt::None => Err(err!( |
| 289 | "Can't set secret key, signature not specified."; |
| 290 | Configuration, Missing)), |
| 291 | } |
| 292 | } |
| 293 | } |
| 294 | |
| 295 | impl< |
| 296 | D: Signer, |
| 297 | G: Signer, |
| 298 | > |
| 299 | SignerDefAlt<D, G> { |
| 300 | |
| 301 | /// Use the given `Alt` `Signer` to override the `DefAlt` for encryption, if it is |
| 302 | /// specified. If not, use the `DefAlt` `Signer`. This gives the user access to up to |
| 303 | /// three different types of `Signer`. |
| 304 | pub fn or_sign<OR: Signer>(&self, msg: &[u8], alt: &Alt<OR>) -> Outcome<Vec<u8>> { |
| 305 | match alt { |
| 306 | Alt::Specific(Some(inner)) => inner.sign(msg), // Type OR Signer |
| 307 | Alt::Specific(None) => Err(err!( |
| 308 | "Can't sign, signature not specified."; |
| 309 | Configuration, Missing)), |
| 310 | Alt::Unspecified => match &self.0 { |
| 311 | DefAlt::Default(inner) => inner.sign(msg), // Type D Signer |
| 312 | DefAlt::Given(inner) => inner.sign(msg), // Type G Signer |
| 313 | DefAlt::None => Err(err!( |
| 314 | "Can't sign, signature not specified."; |
| 315 | Configuration, Missing)), |
| 316 | }, |
| 317 | } |
| 318 | } |
| 319 | |
| 320 | /// Use the given `Alt` `Signer` to override the `DefAlt` for decryption, if it is |
| 321 | /// specified. If not, use the `DefAlt` `Signer`. This gives the user access to up to |
| 322 | /// three different types of `Signer`. |
| 323 | pub fn or_verify<OR: Signer>(&self, msg: &[u8], sig: &[u8], alt: &Alt<OR>) -> Outcome<bool> { |
| 324 | match alt { |
| 325 | Alt::Specific(Some(inner)) => inner.verify(msg, sig), // Type OR Signer |
| 326 | Alt::Specific(None) => Err(err!( |
| 327 | "Can't verify, signature not specified."; |
| 328 | Configuration, Missing)), |
| 329 | Alt::Unspecified => match &self.0 { |
| 330 | DefAlt::Default(inner) => inner.verify(msg, sig), // Type D Signer |
| 331 | DefAlt::Given(inner) => inner.verify(msg, sig), // Type G Signer |
| 332 | DefAlt::None => Err(err!( |
| 333 | "Can't verify, signature not specified."; |
| 334 | Configuration, Missing)), |
| 335 | }, |
| 336 | } |
| 337 | } |
| 338 | } |