/* * Copyright (c) 2023 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ //! hsd is abbreviation for hash signed data use crate::evp; #[derive(Debug, PartialEq)] pub struct SingleSignedData { name: String, signature: String } #[derive(Debug, PartialEq)] pub struct HashSignedData { data: Vec } impl TryFrom<&str> for SingleSignedData { type Error = String; fn try_from(value: &str) -> Result { const KEY_STR : &str = "Name:"; const VALUE_STR : &str = "signed-data:"; let res: Vec<&str> = value.split('\n').filter(|&s| !s.is_empty()).collect(); if res.len() != 2 || !res[0].starts_with(KEY_STR) || !res[1].starts_with(VALUE_STR) { return Err(format!("format error for single signed data {}", value)); } Ok(SingleSignedData { name: res[0][KEY_STR.len()..].trim().to_owned(), signature: res[1][VALUE_STR.len()..].trim().to_owned()}) } } impl TryFrom<&str> for HashSignedData { type Error = String; fn try_from(value: &str) -> Result { if value.is_empty() { return Err("empty value not allowed".to_string()); } let all_hash_data: Vec<&str> = value.split("\n\n").filter(|&s| !s.is_empty()).collect(); let mut hash_signed_data = Vec::::new(); for single_hash_data in all_hash_data { hash_signed_data.push(SingleSignedData::try_from(single_hash_data)?); } Ok(HashSignedData { data: hash_signed_data }) } } #[allow(unused)] impl HashSignedData { pub fn get_sig_for_file(&self, file_name: &str) -> Result, String> { match self.data.iter().find(|&single_line| single_line.name == *file_name) { Some(single_data) => { let single_data = single_data.signature.as_bytes(); evp::evp_decode_block(single_data) }, None => { Err(format!("file name {} invalid, please check your input", file_name)) } } } }