codec_multikey/
binding.rs1use crate::error::{
6 classify_binding_algorithm, classify_binding_type, classify_multikey_codec, MultikeyError,
7};
8use crate::parse::{parse_multikey, ParsedMultikey};
9
10pub fn validate_multikey_binding(
36 binding: KeyBindingInput<'_>,
37 encoded_multikey: &str,
38) -> Result<(), MultikeyError> {
39 let parsed = parse_multikey(encoded_multikey)?;
40 validate_binding_fields(binding, &parsed)
41}
42
43pub fn binding_type_matches_codec(binding_type: &str, codec_name: &str) -> bool {
51 match binding_type {
52 "Multikey" => matches!(
54 codec_name,
55 "ed25519-pub"
56 | "ed448-pub"
57 | "x25519-pub"
58 | "p256-pub"
59 | "p384-pub"
60 | "p521-pub"
61 | "rsa-pub"
62 | "secp256k1-pub"
63 | "mldsa-44-pub"
64 | "mldsa-65-pub"
65 | "mldsa-87-pub"
66 | "mlkem-512-pub"
67 | "mlkem-768-pub"
68 | "mlkem-1024-pub"
69 ),
70
71 "P256Key2024" => codec_name == "p256-pub",
73 "P384Key2024" => codec_name == "p384-pub",
74 "P521Key2024" => codec_name == "p521-pub",
75 "RsaVerificationKey2024" => codec_name == "rsa-pub",
76 "ML_DSA_44Key2024" => codec_name == "mldsa-44-pub",
77 "ML_DSA_65Key2024" => codec_name == "mldsa-65-pub",
78 "ML_DSA_87Key2024" => codec_name == "mldsa-87-pub",
79 "MLKEM512Key2024" => codec_name == "mlkem-512-pub",
80 "MLKEM768Key2024" => codec_name == "mlkem-768-pub",
81 "MLKEM1024Key2024" => codec_name == "mlkem-1024-pub",
82
83 _ => false,
84 }
85}
86
87pub struct KeyBindingInput<'a> {
89 pub binding_type: &'a str,
91 pub algorithm: Option<&'a str>,
93}
94
95pub fn validate_key_binding(
100 binding: KeyBindingInput<'_>,
101 parsed: &ParsedMultikey,
102) -> Result<(), MultikeyError> {
103 validate_binding_fields(binding, parsed)
104}
105
106fn validate_binding_fields(
107 binding: KeyBindingInput<'_>,
108 parsed: &ParsedMultikey,
109) -> Result<(), MultikeyError> {
110 if !binding_type_matches_codec(binding.binding_type, parsed.codec_name()) {
111 return Err(MultikeyError::BindingTypeCodecMismatch {
112 binding_type: classify_binding_type(binding.binding_type),
113 codec: classify_multikey_codec(parsed.codec_name()),
114 algorithm: classify_binding_algorithm(parsed.algorithm_name()),
115 });
116 }
117
118 if let Some(binding_alg) = binding.algorithm {
119 if binding_alg != parsed.algorithm_name() {
120 return Err(MultikeyError::BindingAlgorithmMismatch {
121 binding_alg: classify_binding_algorithm(binding_alg),
122 codec_algorithm: classify_binding_algorithm(parsed.algorithm_name()),
123 });
124 }
125 } else if binding.binding_type != "Multikey" {
126 return Err(MultikeyError::BindingAlgorithmMissing {
127 binding_type: classify_binding_type(binding.binding_type),
128 });
129 }
130
131 Ok(())
132}