Skip to main content

csv_rs/crypto/
mod.rs

1// Copyright (C) Hygon Info Technologies Ltd.
2//
3// SPDX-License-Identifier: Apache-2.0
4
5//! Interfaces for cryptography.
6
7pub mod key;
8pub(crate) mod sig;
9pub mod sm;
10
11use crate::{
12    certs::{Algorithm, Usage},
13    crypto::key::ecc,
14    Body,
15};
16use openssl::hash;
17use openssl_sys::EC_KEY;
18use std::io::{Error, ErrorKind, Result};
19
20#[derive(Debug)]
21pub struct Signature {
22    pub id: Option<[u8; 16]>,
23    pub sig: Vec<u8>,
24    pub algo: Option<Algorithm>,
25    pub usage: Usage,
26}
27
28/// Represents a private key.
29pub struct PrivateKey<U> {
30    pub id: Option<[u8; 16]>,
31    pub key: *mut EC_KEY,
32    pub hash: hash::MessageDigest,
33    pub usage: U,
34}
35
36#[derive(Debug)]
37pub struct PublicKey {
38    pub id: Option<[u8; 16]>,
39    pub key: ecc::PubKey,
40    pub algo: Option<Algorithm>,
41    pub usage: Usage,
42}
43
44impl PublicKey {
45    pub fn verify(
46        &self,
47        msg: &impl codicon::Encoder<Body, Error = Error>,
48        uid: &[u8],
49        sig: &Signature,
50    ) -> Result<()> {
51        let usage_valid = sig.usage == self.usage;
52        let algo_valid = sig.algo.is_none() || sig.algo == self.algo;
53        let id_valid = sig.id.is_none() || sig.id == self.id;
54        if !usage_valid || !algo_valid || !id_valid {
55            return Err(ErrorKind::InvalidInput.into());
56        }
57
58        let mut buf: Vec<u8> = Vec::new();
59        msg.encode(&mut buf, Body)?;
60        sm::SM2::verify(self.key, &sig.sig, &Vec::from(uid), &buf).map(|ok| {
61            // SM2 verify will return Ok(true) if the signature
62            // is verified and Ok(false) if not. This patches the result
63            // to return Err if SM2 returns Ok(false).
64            if ok {
65                Ok(())
66            } else {
67                Err(ErrorKind::NotFound.into())
68            }
69        })?
70    }
71
72    pub fn encrypt(&self, data: &[u8]) -> Result<Vec<u8>> {
73        sm::SM2::encrypt(data, self.key)
74    }
75}