2020-10-21 18:17:55 +08:00
|
|
|
use num_enum::IntoPrimitive;
|
|
|
|
use num_enum::TryFromPrimitive;
|
|
|
|
|
2020-11-03 17:02:26 +08:00
|
|
|
use generic_array::GenericArray;
|
|
|
|
|
2020-10-28 17:33:00 +08:00
|
|
|
use crate::parse::parse_asn1_der_rsa_public_key;
|
2020-11-04 17:45:23 +08:00
|
|
|
use crate::parse::parse_rsa_ssa_pss_parameters;
|
2020-11-05 14:04:21 +08:00
|
|
|
use crate::parse::parse_ecdsa_signature;
|
|
|
|
use crate::parse::parse_asn1_der_oid;
|
2020-11-04 17:45:23 +08:00
|
|
|
|
2020-10-28 17:33:00 +08:00
|
|
|
use crate::Error as TlsError;
|
2020-11-03 17:02:26 +08:00
|
|
|
use crate::session::CertificatePublicKey;
|
2020-11-04 17:45:23 +08:00
|
|
|
use crate::oid::*;
|
|
|
|
use crate::fake_rng::FakeRandom;
|
2020-10-28 17:33:00 +08:00
|
|
|
|
|
|
|
use sha1::{Sha1, Digest};
|
2020-11-04 17:45:23 +08:00
|
|
|
use sha2::{Sha224, Sha256, Sha384, Sha512};
|
2020-10-28 17:33:00 +08:00
|
|
|
use rsa::{PublicKey, RSAPublicKey, PaddingScheme, BigUint, Hash};
|
|
|
|
|
2020-11-05 14:04:21 +08:00
|
|
|
use p256::ecdsa::signature::{Verifier, DigestVerifier};
|
|
|
|
|
2020-10-22 17:41:33 +08:00
|
|
|
use alloc::vec::Vec;
|
2020-11-04 17:45:23 +08:00
|
|
|
use heapless::{ Vec as HeaplessVec, consts::* };
|
2020-10-22 17:41:33 +08:00
|
|
|
|
2020-11-05 14:04:21 +08:00
|
|
|
use core::convert::TryFrom;
|
|
|
|
|
2020-10-23 17:06:31 +08:00
|
|
|
#[derive(Debug, Clone)]
|
2020-10-21 18:17:55 +08:00
|
|
|
pub struct Certificate<'a> {
|
2020-10-23 17:06:31 +08:00
|
|
|
pub tbs_certificate: TBSCertificate<'a>,
|
|
|
|
pub signature_algorithm: AlgorithmIdentifier<'a>,
|
2020-10-28 17:33:00 +08:00
|
|
|
pub signature_value: &'a [u8],
|
|
|
|
pub tbs_certificate_encoded: &'a [u8],
|
2020-10-21 18:17:55 +08:00
|
|
|
}
|
|
|
|
|
2020-10-23 17:06:31 +08:00
|
|
|
#[derive(Debug, Clone)]
|
2020-10-21 18:17:55 +08:00
|
|
|
pub struct TBSCertificate<'a> {
|
2020-10-23 17:06:31 +08:00
|
|
|
pub version: Version,
|
|
|
|
pub serial_number: &'a [u8],
|
|
|
|
pub signature: AlgorithmIdentifier<'a>,
|
2020-11-06 14:19:07 +08:00
|
|
|
pub issuer: Name<'a>,
|
2020-10-23 17:06:31 +08:00
|
|
|
pub validity: Validity<'a>,
|
2020-11-06 14:19:07 +08:00
|
|
|
pub subject: Name<'a>,
|
2020-10-23 17:06:31 +08:00
|
|
|
pub subject_public_key_info: SubjectPublicKeyInfo<'a>,
|
|
|
|
pub issuer_unique_id: Option<&'a [u8]>,
|
|
|
|
pub subject_unique_id: Option<&'a [u8]>,
|
|
|
|
pub extensions: Extensions<'a>,
|
2020-10-21 18:17:55 +08:00
|
|
|
}
|
|
|
|
|
2020-11-02 17:19:02 +08:00
|
|
|
#[allow(non_camel_case_types)]
|
2020-10-21 18:17:55 +08:00
|
|
|
#[derive(Debug, PartialEq, Eq, Clone, Copy, IntoPrimitive, TryFromPrimitive)]
|
|
|
|
#[repr(u8)]
|
|
|
|
pub enum Version {
|
|
|
|
#[num_enum(default)]
|
|
|
|
v1 = 0,
|
|
|
|
v2 = 1,
|
|
|
|
v3 = 2,
|
|
|
|
}
|
|
|
|
|
2020-10-23 17:06:31 +08:00
|
|
|
#[derive(Debug, Clone)]
|
2020-10-21 18:17:55 +08:00
|
|
|
pub struct Validity<'a> {
|
2020-10-22 17:41:33 +08:00
|
|
|
pub not_before: Time<'a>,
|
|
|
|
pub not_after: Time<'a>,
|
2020-10-21 18:17:55 +08:00
|
|
|
}
|
|
|
|
|
2020-10-23 17:06:31 +08:00
|
|
|
#[derive(Debug, Clone)]
|
2020-10-21 18:17:55 +08:00
|
|
|
pub enum Time<'a> {
|
|
|
|
UTCTime(&'a [u8]),
|
|
|
|
GeneralizedTime(&'a [u8]),
|
|
|
|
}
|
|
|
|
|
2020-10-23 17:06:31 +08:00
|
|
|
#[derive(Debug, Clone)]
|
2020-10-21 18:17:55 +08:00
|
|
|
pub struct SubjectPublicKeyInfo<'a> {
|
2020-10-22 17:41:33 +08:00
|
|
|
pub algorithm: AlgorithmIdentifier<'a>,
|
|
|
|
pub subject_public_key: &'a [u8],
|
|
|
|
}
|
|
|
|
|
2020-10-23 17:06:31 +08:00
|
|
|
#[derive(Debug, Clone)]
|
2020-10-22 17:41:33 +08:00
|
|
|
pub struct Extensions<'a> {
|
2020-10-23 17:06:31 +08:00
|
|
|
// TODO: Give a limit to the number of policies, migrate to heapless vec
|
|
|
|
// An arbitrary upper limit does not violate RFC5280
|
|
|
|
pub extensions: Vec<Extension<'a>>
|
2020-10-21 18:17:55 +08:00
|
|
|
}
|
|
|
|
|
2020-10-23 17:06:31 +08:00
|
|
|
#[derive(Debug, Clone)]
|
|
|
|
pub struct Extension<'a> {
|
|
|
|
pub extension_id: &'a [u8],
|
|
|
|
pub critical: bool,
|
|
|
|
pub extension_value: ExtensionValue<'a>,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug, Clone)]
|
|
|
|
pub enum ExtensionValue<'a> {
|
2020-10-22 17:41:33 +08:00
|
|
|
KeyUsage {
|
|
|
|
// Acceptable usage of this certificate
|
|
|
|
// Cross verify with ExtendedKeyUsage
|
2020-10-23 17:06:31 +08:00
|
|
|
// MSb is bit 0
|
|
|
|
usage: u16
|
2020-10-22 17:41:33 +08:00
|
|
|
},
|
2020-10-23 17:06:31 +08:00
|
|
|
|
2020-10-22 17:41:33 +08:00
|
|
|
CertificatePolicies {
|
|
|
|
// Policies listed in an extension
|
|
|
|
// Need to verify its validity
|
2020-10-23 17:06:31 +08:00
|
|
|
// TODO: Give a limit to the number of policies, migrate to heapless vec
|
|
|
|
// An arbitrary upper limit does not violate RFC5280
|
|
|
|
info: Vec<PolicyInformation<'a>>
|
2020-10-22 17:41:33 +08:00
|
|
|
},
|
2020-10-23 17:06:31 +08:00
|
|
|
|
|
|
|
// Permitted subtrees and excluded subtrees are not implemented
|
|
|
|
// SubjectAlternativeName,
|
|
|
|
|
2020-10-22 17:41:33 +08:00
|
|
|
BasicConstraints {
|
|
|
|
is_ca: bool,
|
|
|
|
path_len_constraint: Option<u8>,
|
|
|
|
},
|
|
|
|
|
2020-10-23 17:06:31 +08:00
|
|
|
// Permitted subtrees and excluded subtrees are not implemented
|
|
|
|
// NameConstraints,
|
|
|
|
|
|
|
|
// Policy mapping will not be supported
|
|
|
|
// PolicyConstraints,
|
|
|
|
|
|
|
|
ExtendedKeyUsage {
|
|
|
|
// A list of all possible extended key usage in OID
|
|
|
|
// Cross check validity with regular KeyUsage
|
|
|
|
any_extended_key_usage: bool,
|
|
|
|
id_kp_server_auth: bool,
|
|
|
|
id_kp_client_auth: bool,
|
|
|
|
id_kp_code_signing: bool,
|
|
|
|
id_kp_email_protection: bool,
|
|
|
|
id_kp_time_stamping: bool,
|
|
|
|
id_kp_oscp_signing: bool,
|
|
|
|
},
|
|
|
|
|
|
|
|
InhibitAnyPolicy {
|
|
|
|
// Number of certificates in the path that may still allow AnyPolicy
|
|
|
|
// Certificate chain size should be limited to a small number
|
|
|
|
skip_certs: u8
|
|
|
|
},
|
|
|
|
|
|
|
|
// Extension data from an unsupported extension type
|
|
|
|
Unrecognized,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug, Clone)]
|
|
|
|
pub struct PolicyInformation<'a> {
|
|
|
|
pub id: &'a [u8],
|
|
|
|
pub qualifier: &'a [u8],
|
2020-10-21 18:17:55 +08:00
|
|
|
}
|
|
|
|
|
2020-10-23 17:06:31 +08:00
|
|
|
#[derive(Debug, Clone)]
|
2020-10-21 18:17:55 +08:00
|
|
|
pub struct AlgorithmIdentifier<'a> {
|
|
|
|
pub algorithm: &'a [u8],
|
|
|
|
pub parameters: &'a [u8],
|
|
|
|
}
|
2020-10-28 17:33:00 +08:00
|
|
|
|
2020-11-06 14:19:07 +08:00
|
|
|
#[derive(Debug, Clone)]
|
|
|
|
pub struct Name<'a> {
|
|
|
|
pub relative_distinguished_name: Vec<AttributeTypeAndValue<'a>>
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug, Clone)]
|
|
|
|
pub struct AttributeTypeAndValue<'a> {
|
|
|
|
pub attribute_type: &'a [u8], // OID
|
|
|
|
pub attribute_value: &'a str,
|
|
|
|
}
|
|
|
|
|
2020-10-28 17:33:00 +08:00
|
|
|
impl<'a> Certificate<'a> {
|
2020-11-03 17:02:26 +08:00
|
|
|
// General return public key method
|
|
|
|
pub(crate) fn get_cert_public_key(&self) -> Result<CertificatePublicKey, ()> {
|
|
|
|
let public_key_info = &self.tbs_certificate.subject_public_key_info;
|
|
|
|
let algorithm_identifier = &public_key_info.algorithm;
|
|
|
|
|
|
|
|
// 3 possibilities: RSA_ENCRYPTION, ID_EC_PUBLIC_KEY, and EdDSA25519
|
|
|
|
match algorithm_identifier.algorithm {
|
2020-11-04 17:45:23 +08:00
|
|
|
RSA_ENCRYPTION => {
|
|
|
|
log::info!("Chose rsa encryption");
|
|
|
|
log::info!("Entire key: {:X?}", self.tbs_certificate.subject_public_key_info.subject_public_key);
|
2020-11-03 17:02:26 +08:00
|
|
|
let (_, (modulus, exponent)) = parse_asn1_der_rsa_public_key(
|
|
|
|
self.tbs_certificate.subject_public_key_info.subject_public_key
|
|
|
|
).map_err(|_| ())?;
|
2020-11-04 17:45:23 +08:00
|
|
|
log::info!("Modulus: {:X?}\n, Exponent: {:X?}", modulus, exponent);
|
|
|
|
|
|
|
|
log::info!("Big int modulus: {:?}", BigUint::from_bytes_be(modulus));
|
2020-11-03 17:02:26 +08:00
|
|
|
|
|
|
|
let public_key = RSAPublicKey::new(
|
|
|
|
BigUint::from_bytes_be(modulus),
|
|
|
|
BigUint::from_bytes_be(exponent)
|
|
|
|
).map_err(|_| ())?;
|
2020-11-04 17:45:23 +08:00
|
|
|
log::info!("Got rsa key parts");
|
2020-11-03 17:02:26 +08:00
|
|
|
Ok(
|
|
|
|
CertificatePublicKey::RSA {
|
|
|
|
cert_rsa_public_key: public_key
|
|
|
|
}
|
|
|
|
)
|
|
|
|
},
|
2020-11-04 17:45:23 +08:00
|
|
|
ID_EC_PUBLIC_KEY => {
|
2020-11-05 14:04:21 +08:00
|
|
|
// Check the type of EC, only support secp256r1, parse as OID
|
|
|
|
// Other types of EC repreesntation (EC param) is not be supported
|
|
|
|
let (_, ec_oid) = parse_asn1_der_oid(algorithm_identifier.parameters)
|
|
|
|
.map_err(|_| ())?;
|
2020-11-03 17:02:26 +08:00
|
|
|
// Will definitely NOT support custom curve
|
2020-11-05 14:04:21 +08:00
|
|
|
if ec_oid != PRIME256V1 {
|
2020-11-03 17:02:26 +08:00
|
|
|
return Err(());
|
|
|
|
}
|
2020-11-05 14:04:21 +08:00
|
|
|
log::info!("Acceptable OID");
|
|
|
|
log::info!("Public key into slice: {:X?}", &public_key_info.subject_public_key[1..]);
|
2020-11-03 17:02:26 +08:00
|
|
|
let p256_verify_key = p256::ecdsa::VerifyKey::from_encoded_point(
|
|
|
|
&p256::EncodedPoint::from_untagged_bytes(
|
|
|
|
GenericArray::from_slice(
|
|
|
|
&public_key_info.subject_public_key[1..]
|
|
|
|
)
|
|
|
|
)
|
|
|
|
).map_err(|_| ())?;
|
2020-11-05 14:04:21 +08:00
|
|
|
log::info!("Have verify key");
|
2020-11-03 17:02:26 +08:00
|
|
|
Ok(
|
|
|
|
CertificatePublicKey::ECDSA_SECP256R1_SHA256 {
|
|
|
|
cert_verify_key: p256_verify_key
|
|
|
|
}
|
|
|
|
)
|
|
|
|
},
|
2020-11-04 17:45:23 +08:00
|
|
|
ID_EDDSA_25519 => {
|
2020-11-03 17:02:26 +08:00
|
|
|
let ed25519_public_key = ed25519_dalek::PublicKey::from_bytes(
|
|
|
|
public_key_info.subject_public_key
|
|
|
|
).map_err(|_| ())?;
|
|
|
|
Ok(
|
|
|
|
CertificatePublicKey::ED25519 {
|
|
|
|
cert_eddsa_key: ed25519_public_key
|
|
|
|
}
|
|
|
|
)
|
|
|
|
},
|
|
|
|
_ => Err(())
|
|
|
|
}
|
|
|
|
}
|
2020-10-28 17:33:00 +08:00
|
|
|
|
2020-11-05 14:04:21 +08:00
|
|
|
// Validate signature of self-signed certificate
|
2020-11-04 17:45:23 +08:00
|
|
|
// Do not be confused with TLS Certificate Verify
|
2020-11-05 14:04:21 +08:00
|
|
|
pub fn validate_self_signed_signature(&self) -> Result<(), TlsError> {
|
2020-11-06 13:14:40 +08:00
|
|
|
let cert_public_key = self.get_cert_public_key()
|
|
|
|
.map_err(|_| TlsError::SignatureValidationError)?;
|
|
|
|
self.validate_signature_with_trusted(&cert_public_key)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Validate signature of certificate signed by some CA's public key
|
|
|
|
// Do not be confused with TLS Certificate Verify
|
|
|
|
pub fn validate_signature_with_trusted(
|
|
|
|
&self,
|
|
|
|
trusted_public_key: &CertificatePublicKey
|
|
|
|
) -> Result<(), TlsError>
|
|
|
|
{
|
2020-11-04 17:45:23 +08:00
|
|
|
let sig_alg = self.signature_algorithm.algorithm;
|
|
|
|
|
|
|
|
// Prepare hash value
|
|
|
|
match sig_alg {
|
|
|
|
SHA1_WITH_RSA_ENCRYPTION => {
|
|
|
|
let padding = PaddingScheme::new_pkcs1v15_sign(Some(Hash::SHA1));
|
|
|
|
let hashed = Sha1::digest(self.tbs_certificate_encoded);
|
|
|
|
let sig = self.signature_value;
|
2020-11-06 13:14:40 +08:00
|
|
|
trusted_public_key.get_rsa_public_key()
|
2020-11-04 17:45:23 +08:00
|
|
|
.map_err(|_| TlsError::SignatureValidationError)?
|
|
|
|
.verify(padding, &hashed, sig)
|
|
|
|
.map_err(|_| TlsError::SignatureValidationError)
|
|
|
|
},
|
|
|
|
|
|
|
|
SHA224_WITH_RSA_ENCRYPTION => {
|
|
|
|
let padding = PaddingScheme::new_pkcs1v15_sign(Some(Hash::SHA2_224));
|
|
|
|
let hashed = Sha224::digest(self.tbs_certificate_encoded);
|
|
|
|
let sig = self.signature_value;
|
2020-11-06 13:14:40 +08:00
|
|
|
trusted_public_key.get_rsa_public_key()
|
2020-11-04 17:45:23 +08:00
|
|
|
.map_err(|_| TlsError::SignatureValidationError)?
|
|
|
|
.verify(padding, &hashed, sig)
|
|
|
|
.map_err(|_| TlsError::SignatureValidationError)
|
|
|
|
},
|
2020-10-28 17:33:00 +08:00
|
|
|
|
2020-11-04 17:45:23 +08:00
|
|
|
SHA256_WITH_RSA_ENCRYPTION => {
|
|
|
|
let padding = PaddingScheme::new_pkcs1v15_sign(Some(Hash::SHA2_256));
|
|
|
|
let hashed = Sha256::digest(self.tbs_certificate_encoded);
|
|
|
|
let sig = self.signature_value;
|
2020-11-06 13:14:40 +08:00
|
|
|
trusted_public_key.get_rsa_public_key()
|
2020-11-04 17:45:23 +08:00
|
|
|
.map_err(|_| TlsError::SignatureValidationError)?
|
|
|
|
.verify(padding, &hashed, sig)
|
|
|
|
.map_err(|_| TlsError::SignatureValidationError)
|
|
|
|
},
|
|
|
|
|
|
|
|
SHA384_WITH_RSA_ENCRYPTION => {
|
|
|
|
let padding = PaddingScheme::new_pkcs1v15_sign(Some(Hash::SHA2_384));
|
|
|
|
let hashed = Sha384::digest(self.tbs_certificate_encoded);
|
|
|
|
let sig = self.signature_value;
|
2020-11-06 13:14:40 +08:00
|
|
|
trusted_public_key.get_rsa_public_key()
|
2020-11-04 17:45:23 +08:00
|
|
|
.map_err(|_| TlsError::SignatureValidationError)?
|
|
|
|
.verify(padding, &hashed, sig)
|
|
|
|
.map_err(|_| TlsError::SignatureValidationError)
|
|
|
|
},
|
|
|
|
|
|
|
|
SHA512_WITH_RSA_ENCRYPTION => {
|
|
|
|
let padding = PaddingScheme::new_pkcs1v15_sign(Some(Hash::SHA2_512));
|
|
|
|
let hashed = Sha512::digest(self.tbs_certificate_encoded);
|
|
|
|
let sig = self.signature_value;
|
2020-11-06 13:14:40 +08:00
|
|
|
trusted_public_key.get_rsa_public_key()
|
2020-11-04 17:45:23 +08:00
|
|
|
.map_err(|_| TlsError::SignatureValidationError)?
|
|
|
|
.verify(padding, &hashed, sig)
|
|
|
|
.map_err(|_| TlsError::SignatureValidationError)
|
|
|
|
},
|
2020-11-05 14:04:21 +08:00
|
|
|
// Further process the signature algorithm of PSS before creating digests
|
2020-11-04 17:45:23 +08:00
|
|
|
ID_RSASSA_PSS => {
|
|
|
|
let (_, (hash_alg, salt_len)) = parse_rsa_ssa_pss_parameters(
|
|
|
|
self.signature_algorithm.parameters
|
|
|
|
).unwrap();
|
|
|
|
match hash_alg {
|
|
|
|
ID_SHA1 => {
|
|
|
|
let padding = PaddingScheme::new_pss_with_salt::<Sha1, FakeRandom>(
|
|
|
|
FakeRandom {},
|
|
|
|
salt_len
|
|
|
|
);
|
|
|
|
let hashed = Sha1::digest(self.tbs_certificate_encoded);
|
|
|
|
let sig = self.signature_value;
|
2020-11-06 13:14:40 +08:00
|
|
|
trusted_public_key.get_rsa_public_key()
|
2020-11-04 17:45:23 +08:00
|
|
|
.map_err(|_| TlsError::SignatureValidationError)?
|
|
|
|
.verify(padding, &hashed, sig)
|
|
|
|
.map_err(|_| TlsError::SignatureValidationError)
|
|
|
|
},
|
|
|
|
|
|
|
|
ID_SHA224 => {
|
|
|
|
let padding = PaddingScheme::new_pss_with_salt::<Sha224, FakeRandom>(
|
|
|
|
FakeRandom {},
|
|
|
|
salt_len
|
|
|
|
);
|
|
|
|
let hashed = Sha224::digest(self.tbs_certificate_encoded);
|
|
|
|
let sig = self.signature_value;
|
2020-11-06 13:14:40 +08:00
|
|
|
trusted_public_key.get_rsa_public_key()
|
2020-11-04 17:45:23 +08:00
|
|
|
.map_err(|_| TlsError::SignatureValidationError)?
|
|
|
|
.verify(padding, &hashed, sig)
|
|
|
|
.map_err(|_| TlsError::SignatureValidationError)
|
|
|
|
},
|
|
|
|
|
|
|
|
ID_SHA256 => {
|
|
|
|
let padding = PaddingScheme::new_pss_with_salt::<Sha256, FakeRandom>(
|
|
|
|
FakeRandom {},
|
|
|
|
salt_len
|
|
|
|
);
|
|
|
|
let hashed = Sha256::digest(self.tbs_certificate_encoded);
|
|
|
|
let sig = self.signature_value;
|
2020-11-06 13:14:40 +08:00
|
|
|
trusted_public_key.get_rsa_public_key()
|
2020-11-04 17:45:23 +08:00
|
|
|
.map_err(|_| TlsError::SignatureValidationError)?
|
|
|
|
.verify(padding, &hashed, sig)
|
|
|
|
.map_err(|_| TlsError::SignatureValidationError)
|
|
|
|
},
|
|
|
|
|
|
|
|
ID_SHA384 => {
|
|
|
|
let padding = PaddingScheme::new_pss_with_salt::<Sha384, FakeRandom>(
|
|
|
|
FakeRandom {},
|
|
|
|
salt_len
|
|
|
|
);
|
|
|
|
let hashed = Sha384::digest(self.tbs_certificate_encoded);
|
|
|
|
let sig = self.signature_value;
|
2020-11-06 13:14:40 +08:00
|
|
|
trusted_public_key.get_rsa_public_key()
|
2020-11-04 17:45:23 +08:00
|
|
|
.map_err(|_| TlsError::SignatureValidationError)?
|
|
|
|
.verify(padding, &hashed, sig)
|
|
|
|
.map_err(|_| TlsError::SignatureValidationError)
|
|
|
|
},
|
|
|
|
|
|
|
|
ID_SHA512 => {
|
|
|
|
let padding = PaddingScheme::new_pss_with_salt::<Sha512, FakeRandom>(
|
|
|
|
FakeRandom {},
|
|
|
|
salt_len
|
|
|
|
);
|
|
|
|
let hashed = Sha512::digest(self.tbs_certificate_encoded);
|
|
|
|
let sig = self.signature_value;
|
2020-11-06 13:14:40 +08:00
|
|
|
trusted_public_key.get_rsa_public_key()
|
2020-11-04 17:45:23 +08:00
|
|
|
.map_err(|_| TlsError::SignatureValidationError)?
|
|
|
|
.verify(padding, &hashed, sig)
|
|
|
|
.map_err(|_| TlsError::SignatureValidationError)
|
|
|
|
},
|
2020-11-05 14:04:21 +08:00
|
|
|
|
|
|
|
// TODO: SHA3 is not on the table, implement better error rejection
|
2020-11-04 17:45:23 +08:00
|
|
|
_ => todo!()
|
|
|
|
}
|
2020-11-05 14:04:21 +08:00
|
|
|
},
|
|
|
|
|
|
|
|
// ECDSA signature algorithm (support only `edcsa_secp256r1_sha256`)
|
|
|
|
ECDSA_WITH_SHA256 => {
|
|
|
|
let (_, (r, s)) = parse_ecdsa_signature(self.signature_value)
|
|
|
|
.map_err(|_| TlsError::SignatureValidationError)?;
|
|
|
|
let sig = p256::ecdsa::Signature::from_asn1(self.signature_value)
|
|
|
|
.map_err(|_| TlsError::SignatureValidationError)?;
|
2020-11-06 13:14:40 +08:00
|
|
|
trusted_public_key.get_ecdsa_secp256r1_sha256_verify_key()
|
2020-11-05 14:04:21 +08:00
|
|
|
.map_err(|_| TlsError::SignatureValidationError)?
|
|
|
|
.verify(self.tbs_certificate_encoded, &sig)
|
|
|
|
.map_err(|_| TlsError::SignatureValidationError)
|
|
|
|
},
|
|
|
|
|
|
|
|
// Ed25519 signature algorithm
|
|
|
|
ID_EDDSA_25519 => {
|
|
|
|
let sig = ed25519_dalek::Signature::try_from(
|
|
|
|
self.signature_value
|
|
|
|
).map_err(|_| TlsError::SignatureValidationError)?;
|
|
|
|
log::info!("Ed25519 signature: {:?}", sig);
|
2020-11-06 13:14:40 +08:00
|
|
|
trusted_public_key.get_ed25519_public_key()
|
2020-11-05 14:04:21 +08:00
|
|
|
.map_err(|_| TlsError::SignatureValidationError)?
|
|
|
|
.verify_strict(self.tbs_certificate_encoded, &sig)
|
|
|
|
.map_err(|_| TlsError::SignatureValidationError)
|
2020-11-06 13:14:40 +08:00
|
|
|
},
|
2020-11-05 14:04:21 +08:00
|
|
|
|
2020-11-04 17:45:23 +08:00
|
|
|
_ => todo!()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|