extern crate alloc;
use alloc::string::String;
use num_bigint::BigUint;
use super::hash::map_mbedtls_err;
use super::pk::Pk;
use super::rng::{CtrDrbg, OsEntropy};
use crate::crypto::key_parse::{sm2_scalar_fixed32_be, sm2_secret_from_pkcs8_pem_with_pass};
use crate::crypto::CryptoError;
pub fn sm2_pk_from_pkcs8_pem_with_pass(pem: &str, pass: &str) -> Result<Pk, CryptoError> {
let sk = sm2_secret_from_pkcs8_pem_with_pass(pem, pass)?;
sm2_pk_from_scalar(&sk)
}
pub fn sm2_pk_from_scalar(sk: &BigUint) -> Result<Pk, CryptoError> {
use mbedtls::bignum::Mpi;
use mbedtls::ecp::EcGroup;
use mbedtls::pk::{EcGroupId, Type as PkType};
use std::sync::Arc;
let sk_bytes = sm2_scalar_fixed32_be(sk)?;
let curve = EcGroup::new(EcGroupId::SM2P256R1).map_err(map_mbedtls_err)?;
let d = Mpi::from_binary(&sk_bytes).map_err(map_mbedtls_err)?;
let entropy = Arc::new(OsEntropy::new());
let mut rng = CtrDrbg::new(entropy, None).map_err(map_mbedtls_err)?;
mbedtls::pk::Pk::private_from_ec_scalar_with_rng_extend(
curve,
d,
&mut rng,
PkType::SM2.into(),
)
.map_err(map_mbedtls_err)
}
pub fn sm2_pk_from_scalar_bytes(scalar: &[u8; 32]) -> Result<Pk, CryptoError> {
use num_bigint::BigUint;
sm2_pk_from_scalar(&BigUint::from_bytes_be(scalar))
}
pub fn pk_from_cert_der(cert_der: &[u8]) -> Result<Pk, CryptoError> {
sm2_pk_from_cert_der(cert_der)
}
pub fn pk_parse_keyfile(path: &str, password: Option<String>) -> Result<Pk, CryptoError> {
use alloc::string::ToString;
Pk::parse_keyfile(path.to_string(), password).map_err(map_mbedtls_err)
}
pub fn sm2_pk_from_cert_der(cert_der: &[u8]) -> Result<Pk, CryptoError> {
let mut cert =
mbedtls::x509::Certificate::from_der(cert_der).map_err(map_mbedtls_err)?;
let pub_der = cert
.public_key_mut()
.write_public_der_vec()
.map_err(map_mbedtls_err)?;
Pk::from_public_key(&pub_der).map_err(map_mbedtls_err)
}