c2pa-rs

A fork of https://github.com/contentauth/c2pa-rs/
git clone git://archive.git.mtrnord.blog/mtrnords-photography-manager/c2pa-rs.git
Log | Files | Refs | README

signing_alg.rs (4615B)


      1 // Copyright 2022 Adobe. All rights reserved.
      2 // This file is licensed to you under the Apache License,
      3 // Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
      4 // or the MIT license (http://opensource.org/licenses/MIT),
      5 // at your option.
      6 
      7 // Unless required by applicable law or agreed to in writing,
      8 // this software is distributed on an "AS IS" BASIS, WITHOUT
      9 // WARRANTIES OR REPRESENTATIONS OF ANY KIND, either express or
     10 // implied. See the LICENSE-MIT and LICENSE-APACHE files for the
     11 // specific language governing permissions and limitations under
     12 // each license.
     13 
     14 #![deny(missing_docs)]
     15 
     16 use std::{fmt, str::FromStr};
     17 
     18 #[cfg(feature = "json_schema")]
     19 use schemars::JsonSchema;
     20 use serde::{Deserialize, Serialize};
     21 
     22 /// Describes the digital signature algorithms allowed by the C2PA spec.
     23 ///
     24 /// Per <https://c2pa.org/specifications/specifications/1.0/specs/C2PA_Specification.html#_digital_signatures>:
     25 ///
     26 /// > All digital signatures that are stored in a C2PA Manifest shall
     27 /// > be generated using one of the digital signature algorithms and
     28 /// > key types listed as described in this section.
     29 #[derive(Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
     30 #[cfg_attr(feature = "json_schema", derive(JsonSchema))]
     31 pub enum SigningAlg {
     32     /// ECDSA with SHA-256
     33     Es256,
     34 
     35     /// ECDSA with SHA-384
     36     Es384,
     37 
     38     /// ECDSA with SHA-512
     39     Es512,
     40 
     41     /// RSASSA-PSS using SHA-256 and MGF1 with SHA-256
     42     Ps256,
     43 
     44     /// RSASSA-PSS using SHA-384 and MGF1 with SHA-384
     45     Ps384,
     46 
     47     /// RSASSA-PSS using SHA-512 and MGF1 with SHA-512
     48     Ps512,
     49 
     50     /// Edwards-Curve DSA (Ed25519 instance only)
     51     Ed25519,
     52 }
     53 
     54 impl FromStr for SigningAlg {
     55     type Err = UnknownAlgorithmError;
     56 
     57     fn from_str(alg: &str) -> Result<Self, Self::Err> {
     58         match alg {
     59             "es256" => Ok(Self::Es256),
     60             "es384" => Ok(Self::Es384),
     61             "es512" => Ok(Self::Es512),
     62             "ps256" => Ok(Self::Ps256),
     63             "ps384" => Ok(Self::Ps384),
     64             "ps512" => Ok(Self::Ps512),
     65             "ed25519" => Ok(Self::Ed25519),
     66             _ => Err(UnknownAlgorithmError(alg.to_owned())),
     67         }
     68     }
     69 }
     70 
     71 impl fmt::Display for SigningAlg {
     72     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
     73         write!(
     74             f,
     75             "{}",
     76             match self {
     77                 Self::Es256 => "es256",
     78                 Self::Es384 => "es384",
     79                 Self::Es512 => "es512",
     80                 Self::Ps256 => "ps256",
     81                 Self::Ps384 => "ps384",
     82                 Self::Ps512 => "ps512",
     83                 Self::Ed25519 => "ed25519",
     84             }
     85         )
     86     }
     87 }
     88 
     89 #[derive(Debug, PartialEq, Eq)]
     90 /// This error is thrown when converting from a string to [`SigningAlg`]
     91 /// if the algorithm string is unrecognized.
     92 ///
     93 /// The string must be one of "es256", "es384", "es512", "ps256", "ps384",
     94 /// "ps512", or "ed25519".
     95 pub struct UnknownAlgorithmError(String);
     96 
     97 impl fmt::Display for UnknownAlgorithmError {
     98     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
     99         write!(f, "UnknownAlgorithmError({})", self.0)
    100     }
    101 }
    102 
    103 impl std::error::Error for UnknownAlgorithmError {}
    104 
    105 #[cfg(test)]
    106 mod tests {
    107     #![allow(clippy::expect_used)]
    108     #![allow(clippy::unwrap_used)]
    109 
    110     use super::*;
    111 
    112     #[test]
    113     fn alg_from_str() {
    114         assert_eq!("es256".parse(), Ok(SigningAlg::Es256));
    115         assert_eq!("es384".parse(), Ok(SigningAlg::Es384));
    116         assert_eq!("es512".parse(), Ok(SigningAlg::Es512));
    117         assert_eq!("ps256".parse(), Ok(SigningAlg::Ps256));
    118         assert_eq!("ps384".parse(), Ok(SigningAlg::Ps384));
    119         assert_eq!("ps512".parse(), Ok(SigningAlg::Ps512));
    120         assert_eq!("ed25519".parse(), Ok(SigningAlg::Ed25519));
    121 
    122         let r: Result<SigningAlg, UnknownAlgorithmError> = "bogus".parse();
    123         assert_eq!(r, Err(UnknownAlgorithmError("bogus".to_string())));
    124     }
    125 
    126     #[test]
    127     fn signing_alg_impl_display() {
    128         assert_eq!(format!("{}", SigningAlg::Es256), "es256");
    129         assert_eq!(format!("{}", SigningAlg::Es384), "es384");
    130         assert_eq!(format!("{}", SigningAlg::Es512), "es512");
    131         assert_eq!(format!("{}", SigningAlg::Ps256), "ps256");
    132         assert_eq!(format!("{}", SigningAlg::Ps384), "ps384");
    133         assert_eq!(format!("{}", SigningAlg::Ps512), "ps512");
    134         assert_eq!(format!("{}", SigningAlg::Ed25519), "ed25519");
    135     }
    136 
    137     #[test]
    138     fn err_impl_display() {
    139         assert_eq!(
    140             format!("{}", UnknownAlgorithmError("bogus".to_owned())),
    141             "UnknownAlgorithmError(bogus)"
    142         );
    143     }
    144 }