* 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.
*/
use crate::evp;
#[derive(Debug, PartialEq)]
pub struct SingleSignedData {
name: String,
signature: String
}
#[derive(Debug, PartialEq)]
pub struct HashSignedData {
data: Vec<SingleSignedData>
}
impl TryFrom<&str> for SingleSignedData {
type Error = String;
fn try_from(value: &str) -> Result<Self, Self::Error> {
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<Self, Self::Error> {
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::<SingleSignedData>::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<Vec<u8>, 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))
}
}
}
}