Skip to main content

opcua_crypto/
thumbprint.rs

1// OPCUA for Rust
2// SPDX-License-Identifier: MPL-2.0
3// Copyright (C) 2017-2024 Adam Lock
4
5//! Functionality for holding a message digest.
6use serde::{Deserialize, Serialize};
7
8use opcua_types::ByteString;
9
10/// The thumbprint holds a 20 byte representation of a certificate that can be used as a hash,
11/// handshake comparison, a filename hint or similar purpose where a shortened representation
12/// of a cert is required. Thumbprint size is dictated by the OPC UA spec
13#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
14pub struct Thumbprint {
15    /// Thumbprint is relatively small and fixed size, so use array to hold value instead of a vec
16    /// just to save heap
17    value: [u8; Thumbprint::THUMBPRINT_SIZE],
18}
19
20impl From<Thumbprint> for ByteString {
21    fn from(value: Thumbprint) -> Self {
22        Self::from(&value.value)
23    }
24}
25
26impl Thumbprint {
27    /// Size of thumbprint.
28    pub const THUMBPRINT_SIZE: usize = 20;
29
30    /// Constructs a thumbprint from a message digest which is expected to be the proper length
31    pub fn new(digest: &[u8]) -> Thumbprint {
32        if digest.len() != Thumbprint::THUMBPRINT_SIZE {
33            panic!("Thumbprint is the wrong length, {}", digest.len());
34        }
35        let mut value = [0u8; Thumbprint::THUMBPRINT_SIZE];
36        value.clone_from_slice(digest);
37        Thumbprint { value }
38    }
39
40    /// Create a byte string from this thumbprint.
41    pub fn as_byte_string(&self) -> ByteString {
42        ByteString::from(&self.value)
43    }
44
45    /// Returns the thumbprint as a string using hexadecimal values for each byte
46    pub fn as_hex_string(&self) -> String {
47        let mut hex_string = String::with_capacity(self.value.len() * 2);
48        for b in self.value.iter() {
49            hex_string.push_str(&format!("{b:02x}"))
50        }
51        hex_string
52    }
53
54    /// Returns the thumbprint
55    pub fn value(&self) -> &[u8] {
56        &self.value[..]
57    }
58}