pub fn deserialize_json_with_selector<'a, F>(
        &self,
        input: impl AsRef<[u8]>,
        selector: F,
    ) -> Result<(Vec<u8>, JwsHeader), JoseError>
    where
        F: Fn(&JwsHeader) -> Result<Option<&'a dyn JwsVerifier>, JoseError>,
    {
        (|| -> anyhow::Result<(Vec<u8>, JwsHeader)> {
            let input = input.as_ref();
            let mut map: Map<String, Value> = serde_json::from_slice(input)?;

            let payload_b64 = match map.remove("payload") {
                Some(Value::String(val)) => val,
                Some(_) => bail!("The payload field must be string."),
                None => bail!("The payload field is required."),
            };

            let signatures = match map.remove("signatures") {
                Some(Value::Array(vals)) => {
                    let mut vec = Vec::with_capacity(vals.len());
                    for val in vals {
                        if let Value::Object(val) = val {
                            vec.push(val);
                        } else {
                            bail!("The signatures field must be a array of object.");
                        }
                    }
                    vec
                }
                Some(_) => bail!("The signatures field must be a array."),
                None => {
                    let mut vec = Vec::with_capacity(1);
                    vec.push(map);
                    vec
                }
            };

            for mut sig in signatures {
                let header = sig.remove("header");

                let protected_b64 = match sig.get("protected") {
                    Some(Value::String(val)) => val,
                    Some(_) => bail!("The protected field must be a string."),
                    None => bail!("The JWS alg header claim must be in protected."),
                };

                let protected_vec = base64::decode_config(&protected_b64, base64::URL_SAFE_NO_PAD)?;
                let protected_map: Map<String, Value> = serde_json::from_slice(&protected_vec)?;

                let mut b64 = true;
                if let Some(Value::Array(vals)) = protected_map.get("critical") {
                    for val in vals {
                        match val {
                            Value::String(name) => {
                                if !self.is_acceptable_critical(name) {
                                    bail!("The critical name '{}' is not supported.", name);
                                }

                                if name == "b64" {
                                    match protected_map.get("b64") {
                                        Some(Value::Bool(b64_val)) => {
                                            b64 = *b64_val;
                                        }
                                        Some(_) => bail!("The JWS b64 header claim must be bool."),
                                        None => {}
                                    }
                                }
                            }
                            _ => bail!("The JWS critical header claim must be a array of string."),
                        }
                    }
                }

                let merged_map = match header {
                    Some(Value::Object(mut val)) => {
                        for (key, value) in protected_map {
                            if val.contains_key(&key) {
                                bail!("A duplicate key exists: {}", key);
                            } else {
                                val.insert(key.clone(), value.clone());
                            }
                        }
                        val
                    }
                    Some(_) => bail!("The protected field must be a object."),
                    None => protected_map.clone(),
                };

                if let None = merged_map.get("alg") {
                    bail!("The JWS alg header claim must be in protected.");
                }

                let signature = match sig.get("signature") {
                    Some(Value::String(val)) => {
                        base64::decode_config(val, base64::URL_SAFE_NO_PAD)?
                    }
                    Some(_) => bail!("The signature field must be string."),
                    None => bail!("The signature field is required."),
                };

                let merged = JwsHeader::from_map(merged_map)?;
                let verifier = match selector(&merged)? {
                    Some(val) => val,
                    None => continue,
                };

                match merged.claim("alg") {
                    Some(Value::String(val)) => {
                        let expected_alg = verifier.algorithm().name();
                        if val != expected_alg {
                            bail!("The JWS alg header claim is not {}: {}", expected_alg, val);
                        }
                    }
                    Some(_) => bail!("The JWS alg header claim must be a string."),
                    None => bail!("The JWS alg header claim is required."),
                }

                match verifier.key_id() {
                    Some(expected) => match merged.key_id() {
                        Some(actual) if expected == actual => {}
                        Some(actual) => bail!("The JWS kid header claim is mismatched: {}", actual),
                        None => bail!("The JWS kid header claim is required."),
                    },
                    None => {}
                }

                let message = format!("{}.{}", &protected_b64, &payload_b64);
                verifier.verify(message.as_bytes(), &signature)?;

                let payload = if b64 {
                    base64::decode_config(&payload_b64, base64::URL_SAFE_NO_PAD)?
                } else {
                    payload_b64.into_bytes()
                };

                return Ok((payload, merged));
            }

            bail!("A signature that matched the header claims is not found.");
        })()
        .map_err(|err| match err.downcast::<JoseError>() {
            Ok(err) => err,
            Err(err) => JoseError::InvalidJwsFormat(err),
        })
    }
/// Deserialize the input that is formatted by json serialization.
///
/// # Arguments
///
/// * `input` - The input data.
/// * `header` - The decoded JWS header claims.
/// * `selector` - a function for selecting the verifying algorithm.
Deserialize the input that is formatted by json serialization.
Deserialize the input that is formatted by json serialization .
pub fn deserialize_json_with_selector<'a, F>(
        &self,
        input: impl AsRef<[u8]>,
        selector: F,
    ) -> Result<(Vec<u8>, JwsHeader), JoseError>
    where
        F: Fn(&JwsHeader) -> Result<Option<&'a dyn JwsVerifier>, JoseError>,
    {
        (|| -> anyhow::Result<(Vec<u8>, JwsHeader)> {
            let input = input.as_ref();
            let mut map: Map<String, Value> = serde_json::from_slice(input)?;
            let payload_b64 = match map.remove("payload") {
                Some(Value::String(val)) => val,
                Some(_) => bail!("The payload field must be string."),
                None => bail!("The payload field is required."),
            };
            let signatures = match map.remove("signatures") {
                Some(Value::Array(vals)) => {
                    let mut vec = Vec::with_capacity(vals.len());
                    for val in vals {
                        if let Value::Object(val) = val {
                            vec.push(val);
                        } else {
                            bail!("The signatures field must be a array of object.");
                        }
                    }
                    vec
                }
                Some(_) => bail!("The signatures field must be a array."),
                None => {
                    let mut vec = Vec::with_capacity(1);
                    vec.push(map);
                    vec
                }
            };
            for mut sig in signatures {
                let header = sig.remove("header");
                let protected_b64 = match sig.get("protected") {
                    Some(Value::String(val)) => val,
                    Some(_) => bail!("The protected field must be a string."),
                    None => bail!("The JWS alg header claim must be in protected."),
                };
                let protected_vec = base64::decode_config(&protected_b64, base64::URL_SAFE_NO_PAD)?;
                let protected_map: Map<String, Value> = serde_json::from_slice(&protected_vec)?;
                let mut b64 = true;
                if let Some(Value::Array(vals)) = protected_map.get("critical") {
                    for val in vals {
                        match val {
                            Value::String(name) => {
                                if !self.is_acceptable_critical(name) {
                                    bail!("The critical name '{}' is not supported.", name);
                                }
                                if name == "b64" {
                                    match protected_map.get("b64") {
                                        Some(Value::Bool(b64_val)) => {
                                            b64 = *b64_val;
                                        }
                                        Some(_) => bail!("The JWS b64 header claim must be bool."),
                                        None => {}
                                    }
                                }
                            }
                            _ => bail!("The JWS critical header claim must be a array of string."),
                        }
                    }
                }
                let merged_map = match header {
                    Some(Value::Object(mut val)) => {
                        for (key, value) in protected_map {
                            if val.contains_key(&key) {
                                bail!("A duplicate key exists: {}", key);
                            } else {
                                val.insert(key.clone(), value.clone());
                            }
                        }
                        val
                    }
                    Some(_) => bail!("The protected field must be a object."),
                    None => protected_map.clone(),
                };
                if let None = merged_map.get("alg") {
                    bail!("The JWS alg header claim must be in protected.");
                }
                let signature = match sig.get("signature") {
                    Some(Value::String(val)) => {
                        base64::decode_config(val, base64::URL_SAFE_NO_PAD)?
                    }
                    Some(_) => bail!("The signature field must be string."),
                    None => bail!("The signature field is required."),
                };
                let merged = JwsHeader::from_map(merged_map)?;
                let verifier = match selector(&merged)? {
                    Some(val) => val,
                    None => continue,
                };
                match merged.claim("alg") {
                    Some(Value::String(val)) => {
                        let expected_alg = verifier.algorithm().name();
                        if val != expected_alg {
                            bail!("The JWS alg header claim is not {}: {}", expected_alg, val);
                        }
                    }
                    Some(_) => bail!("The JWS alg header claim must be a string."),
                    None => bail!("The JWS alg header claim is required."),
                }
                match verifier.key_id() {
                    Some(expected) => match merged.key_id() {
                        Some(actual) if expected == actual => {}
                        Some(actual) => bail!("The JWS kid header claim is mismatched: {}", actual),
                        None => bail!("The JWS kid header claim is required."),
                    },
                    None => {}
                }
                let message = format!("{}.{}", &protected_b64, &payload_b64);
                verifier.verify(message.as_bytes(), &signature)?;
                let payload = if b64 {
                    base64::decode_config(&payload_b64, base64::URL_SAFE_NO_PAD)?
                } else {
                    payload_b64.into_bytes()
                };
                return Ok((payload, merged));
            }
            bail!("A signature that matched the header claims is not found.");
        })()
        .map_err(|err| match err.downcast::<JoseError>() {
            Ok(err) => err,
            Err(err) => JoseError::InvalidJwsFormat(err),
        })
    }
pub fn deserialize_json_with_selector < ' a , F > ( & self , input : impl AsRef < [ u8 ] > , selector : F , ) -> Result < ( Vec < u8 > , JwsHeader ) , JoseError > where F : Fn ( & JwsHeader ) -> Result < Option < & ' a dyn JwsVerifier > , JoseError > , { ( | | -> anyhow :: Result < ( Vec < u8 > , JwsHeader ) > { let input = input . as_ref ( ) ; let mut map : Map < String , Value > = serde_json :: from_slice ( input ) ? ; let payload_b64 = match map . remove ( " " ) { Some ( Value :: String ( val ) ) => val , Some ( _ ) => bail ! ( " " ) , None => bail ! ( " " ) , } ; let signatures = match map . remove ( " " ) { Some ( Value :: Array ( vals ) ) => { let mut vec = Vec :: with_capacity ( vals . len ( ) ) ; for val in vals { if let Value :: Object ( val ) = val { vec . push ( val ) ; } else { bail ! ( " " ) ; } } vec } Some ( _ ) => bail ! ( " " ) , None => { let mut vec = Vec :: with_capacity ( 1 ) ; vec . push ( map ) ; vec } } ; for mut sig in signatures { let header = sig . remove ( " " ) ; let protected_b64 = match sig . get ( " " ) { Some ( Value :: String ( val ) ) => val , Some ( _ ) => bail ! ( " " ) , None => bail ! ( " " ) , } ; let protected_vec = base64 :: decode_config ( & protected_b64 , base64 :: URL_SAFE_NO_PAD ) ? ; let protected_map : Map < String , Value > = serde_json :: from_slice ( & protected_vec ) ? ; let mut b64 = true ; if let Some ( Value :: Array ( vals ) ) = protected_map . get ( " " ) { for val in vals { match val { Value :: String ( name ) => { if ! self . is_acceptable_critical ( name ) { bail ! ( " " name ) ; } if name == " " { match protected_map . get ( " " ) { Some ( Value :: Bool ( b64_val ) ) => { b64 = * b64_val ; } Some ( _ ) => bail ! ( " " ) , None => { } } } } _ => bail ! ( " " ) , } } } let merged_map = match header { Some ( Value :: Object ( mut val ) ) => { for ( key , value ) in protected_map { if val . contains_key ( & key ) { bail ! ( " " key ) ; } else { val . insert ( key . clone ( ) , value . clone ( ) ) ; } } val } Some ( _ ) => bail ! ( " " ) , None => protected_map . clone ( ) , } ; if let None = merged_map . get ( " " ) { bail ! ( " " ) ; } let signature = match sig . get ( " " ) { Some ( Value :: String ( val ) ) => { base64 :: decode_config ( val , base64 :: URL_SAFE_NO_PAD ) ? } Some ( _ ) => bail ! ( " " ) , None => bail ! ( " " ) , } ; let merged = JwsHeader :: from_map ( merged_map ) ? ; let verifier = match selector ( & merged ) ? { Some ( val ) => val , None => continue , } ; match merged . claim ( " " ) { Some ( Value :: String ( val ) ) => { let expected_alg = verifier . algorithm ( ) . name ( ) ; if val != expected_alg { bail ! ( " " expected_alg val ) ; } } Some ( _ ) => bail ! ( " " ) , None => bail ! ( " " ) , } match verifier . key_id ( ) { Some ( expected ) => match merged . key_id ( ) { Some ( actual ) if expected == actual => { } Some ( actual ) => bail ! ( " " actual ) , None => bail ! ( " " ) , } , None => { } } let message = format ! ( " " protected_b64 payload_b64 ) ; verifier . verify ( message . as_bytes ( ) , & signature ) ? ; let payload = if b64 { base64 :: decode_config ( & payload_b64 , base64 :: URL_SAFE_NO_PAD ) ? } else { payload_b64 . into_bytes ( ) } ; return Ok ( ( payload , merged ) ) ; } bail ! ( " " ) ; } ) ( ) . map_err ( | err | match err . downcast :: < JoseError > ( ) { Ok ( err ) => err , Err ( err ) => JoseError :: InvalidJwsFormat ( err ) , } ) }
Deserialize the input that is formatted by json serialization.
Deserialize the input that is formatted by json serialization .
&self
input
impl AsRef<[u8]>
selector
F
&self
input
impl AsRef<[u8]>
selector
F