Compare commits
4 Commits
1c689b3535
...
4b37146f96
Author | SHA1 | Date |
---|---|---|
occheung | 4b37146f96 | |
occheung | f0e0b3d434 | |
occheung | d241e93d8e | |
occheung | ed2b73389a |
10
Cargo.toml
10
Cargo.toml
|
@ -53,4 +53,12 @@ features = [ "alloc" ]
|
|||
[dependencies.nom]
|
||||
version = "5.1.2"
|
||||
default-features = false
|
||||
features= []
|
||||
features = []
|
||||
|
||||
[dependencies.simple_logger]
|
||||
version = "1.11.0"
|
||||
optional = true
|
||||
|
||||
[features]
|
||||
default = []
|
||||
std_logger = ["simple_logger"]
|
|
@ -3,23 +3,25 @@ use num_enum::TryFromPrimitive;
|
|||
|
||||
use alloc::vec::Vec;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Certificate<'a> {
|
||||
tbs_certificate: TBSCertificate<'a>,
|
||||
signature_algorithm: AlgorithmIdentifier<'a>,
|
||||
signature_value: &'a [u8]
|
||||
pub tbs_certificate: TBSCertificate<'a>,
|
||||
pub signature_algorithm: AlgorithmIdentifier<'a>,
|
||||
pub signature_value: &'a [u8]
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct TBSCertificate<'a> {
|
||||
version: Version,
|
||||
serial_number: &'a [u8],
|
||||
signature: AlgorithmIdentifier<'a>,
|
||||
issuer: &'a [u8],
|
||||
validity: Validity<'a>,
|
||||
subject: &'a [u8],
|
||||
subject_public_key_info: SubjectPublicKeyInfo<'a>,
|
||||
issuer_unique_id: Option<&'a [u8]>,
|
||||
subject_unique_id: Option<&'a [u8]>,
|
||||
extensions: Extensions<'a>,
|
||||
pub version: Version,
|
||||
pub serial_number: &'a [u8],
|
||||
pub signature: AlgorithmIdentifier<'a>,
|
||||
pub issuer: &'a [u8],
|
||||
pub validity: Validity<'a>,
|
||||
pub subject: &'a [u8],
|
||||
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>,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Copy, IntoPrimitive, TryFromPrimitive)]
|
||||
|
@ -31,44 +33,98 @@ pub enum Version {
|
|||
v3 = 2,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Validity<'a> {
|
||||
pub not_before: Time<'a>,
|
||||
pub not_after: Time<'a>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum Time<'a> {
|
||||
UTCTime(&'a [u8]),
|
||||
GeneralizedTime(&'a [u8]),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct SubjectPublicKeyInfo<'a> {
|
||||
pub algorithm: AlgorithmIdentifier<'a>,
|
||||
pub subject_public_key: &'a [u8],
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Extensions<'a> {
|
||||
extensions: Vec<Extension<'a>>
|
||||
// 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>>
|
||||
}
|
||||
|
||||
pub enum Extension<'a> {
|
||||
#[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> {
|
||||
KeyUsage {
|
||||
// Acceptable usage of this certificate
|
||||
// Cross verify with ExtendedKeyUsage
|
||||
usage: u8
|
||||
// MSb is bit 0
|
||||
usage: u16
|
||||
},
|
||||
|
||||
CertificatePolicies {
|
||||
// Policies listed in an extension
|
||||
// Need to verify its validity
|
||||
policies: Vec<&'a [u8]>
|
||||
// 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>>
|
||||
},
|
||||
SubjectAlternativeName,
|
||||
|
||||
// Permitted subtrees and excluded subtrees are not implemented
|
||||
// SubjectAlternativeName,
|
||||
|
||||
BasicConstraints {
|
||||
is_ca: bool,
|
||||
path_len_constraint: Option<u8>,
|
||||
},
|
||||
|
||||
// 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],
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct AlgorithmIdentifier<'a> {
|
||||
pub algorithm: &'a [u8],
|
||||
pub parameters: &'a [u8],
|
||||
|
|
50
src/main.rs
50
src/main.rs
|
@ -77,16 +77,56 @@ fn main() {
|
|||
).unwrap();
|
||||
|
||||
// tls_socket.tls_connect(&mut sockets).unwrap();
|
||||
let (rest, result) = parse_asn1_der_certificate(&CERT).unwrap();
|
||||
simple_logger::SimpleLogger::new().init().unwrap();
|
||||
|
||||
// let (rest, result) = parse_asn1_der_extension(&KEY_USAGE).unwrap();
|
||||
// println!(
|
||||
// "{:X?}\n{:X?}",
|
||||
// rest,
|
||||
// result
|
||||
// );
|
||||
|
||||
// let (rest, result) = parse_asn1_der_extension(&EXTENDED_KEY_USAGE).unwrap();
|
||||
// println!(
|
||||
// "{:X?}\n{:X?}",
|
||||
// rest,
|
||||
// result
|
||||
// );
|
||||
|
||||
// let (rest, result) = parse_asn1_der_extensions(&EXTENSIONS).unwrap();
|
||||
// println!(
|
||||
// "{:X?}\n{:X?}",
|
||||
// rest,
|
||||
// result
|
||||
// );
|
||||
|
||||
let (rest, result) = parse_asn1_der_certificate(&CERTIFICATE).unwrap();
|
||||
println!(
|
||||
"{:X?}\n{:X?}\n{:X?}\n{:X?}",
|
||||
"{:X?}\n{:X?}",
|
||||
rest,
|
||||
result.0,
|
||||
result.1,
|
||||
result.2
|
||||
result
|
||||
);
|
||||
}
|
||||
|
||||
const CERT: [u8; 805] = [
|
||||
0x30, 0x82, 0x03, 0x21, 0x30, 0x82, 0x02, 0x09, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x08, 0x15, 0x5a, 0x92, 0xad, 0xc2, 0x04, 0x8f, 0x90, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x22, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0a, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x38, 0x31, 0x30, 0x30, 0x35, 0x30, 0x31, 0x33, 0x38, 0x31, 0x37, 0x5a, 0x17, 0x0d, 0x31, 0x39, 0x31, 0x30, 0x30, 0x35, 0x30, 0x31, 0x33, 0x38, 0x31, 0x37, 0x5a, 0x30, 0x2b, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x1c, 0x30, 0x1a, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x13, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x75, 0x6c, 0x66, 0x68, 0x65, 0x69, 0x6d, 0x2e, 0x6e, 0x65, 0x74, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xc4, 0x80, 0x36, 0x06, 0xba, 0xe7, 0x47, 0x6b, 0x08, 0x94, 0x04, 0xec, 0xa7, 0xb6, 0x91, 0x04, 0x3f, 0xf7, 0x92, 0xbc, 0x19, 0xee, 0xfb, 0x7d, 0x74, 0xd7, 0xa8, 0x0d, 0x00, 0x1e, 0x7b, 0x4b, 0x3a, 0x4a, 0xe6, 0x0f, 0xe8, 0xc0, 0x71, 0xfc, 0x73, 0xe7, 0x02, 0x4c, 0x0d, 0xbc, 0xf4, 0xbd, 0xd1, 0x1d, 0x39, 0x6b, 0xba, 0x70, 0x46, 0x4a, 0x13, 0xe9, 0x4a, 0xf8, 0x3d, 0xf3, 0xe1, 0x09, 0x59, 0x54, 0x7b, 0xc9, 0x55, 0xfb, 0x41, 0x2d, 0xa3, 0x76, 0x52, 0x11, 0xe1, 0xf3, 0xdc, 0x77, 0x6c, 0xaa, 0x53, 0x37, 0x6e, 0xca, 0x3a, 0xec, 0xbe, 0xc3, 0xaa, 0xb7, 0x3b, 0x31, 0xd5, 0x6c, 0xb6, 0x52, 0x9c, 0x80, 0x98, 0xbc, 0xc9, 0xe0, 0x28, 0x18, 0xe2, 0x0b, 0xf7, 0xf8, 0xa0, 0x3a, 0xfd, 0x17, 0x04, 0x50, 0x9e, 0xce, 0x79, 0xbd, 0x9f, 0x39, 0xf1, 0xea, 0x69, 0xec, 0x47, 0x97, 0x2e, 0x83, 0x0f, 0xb5, 0xca, 0x95, 0xde, 0x95, 0xa1, 0xe6, 0x04, 0x22, 0xd5, 0xee, 0xbe, 0x52, 0x79, 0x54, 0xa1, 0xe7, 0xbf, 0x8a, 0x86, 0xf6, 0x46, 0x6d, 0x0d, 0x9f, 0x16, 0x95, 0x1a, 0x4c, 0xf7, 0xa0, 0x46, 0x92, 0x59, 0x5c, 0x13, 0x52, 0xf2, 0x54, 0x9e, 0x5a, 0xfb, 0x4e, 0xbf, 0xd7, 0x7a, 0x37, 0x95, 0x01, 0x44, 0xe4, 0xc0, 0x26, 0x87, 0x4c, 0x65, 0x3e, 0x40, 0x7d, 0x7d, 0x23, 0x07, 0x44, 0x01, 0xf4, 0x84, 0xff, 0xd0, 0x8f, 0x7a, 0x1f, 0xa0, 0x52, 0x10, 0xd1, 0xf4, 0xf0, 0xd5, 0xce, 0x79, 0x70, 0x29, 0x32, 0xe2, 0xca, 0xbe, 0x70, 0x1f, 0xdf, 0xad, 0x6b, 0x4b, 0xb7, 0x11, 0x01, 0xf4, 0x4b, 0xad, 0x66, 0x6a, 0x11, 0x13, 0x0f, 0xe2, 0xee, 0x82, 0x9e, 0x4d, 0x02, 0x9d, 0xc9, 0x1c, 0xdd, 0x67, 0x16, 0xdb, 0xb9, 0x06, 0x18, 0x86, 0xed, 0xc1, 0xba, 0x94, 0x21, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x52, 0x30, 0x50, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x05, 0xa0, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, 0x16, 0x30, 0x14, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x01, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x89, 0x4f, 0xde, 0x5b, 0xcc, 0x69, 0xe2, 0x52, 0xcf, 0x3e, 0xa3, 0x00, 0xdf, 0xb1, 0x97, 0xb8, 0x1d, 0xe1, 0xc1, 0x46, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x59, 0x16, 0x45, 0xa6, 0x9a, 0x2e, 0x37, 0x79, 0xe4, 0xf6, 0xdd, 0x27, 0x1a, 0xba, 0x1c, 0x0b, 0xfd, 0x6c, 0xd7, 0x55, 0x99, 0xb5, 0xe7, 0xc3, 0x6e, 0x53, 0x3e, 0xff, 0x36, 0x59, 0x08, 0x43, 0x24, 0xc9, 0xe7, 0xa5, 0x04, 0x07, 0x9d, 0x39, 0xe0, 0xd4, 0x29, 0x87, 0xff, 0xe3, 0xeb, 0xdd, 0x09, 0xc1, 0xcf, 0x1d, 0x91, 0x44, 0x55, 0x87, 0x0b, 0x57, 0x1d, 0xd1, 0x9b, 0xdf, 0x1d, 0x24, 0xf8, 0xbb, 0x9a, 0x11, 0xfe, 0x80, 0xfd, 0x59, 0x2b, 0xa0, 0x39, 0x8c, 0xde, 0x11, 0xe2, 0x65, 0x1e, 0x61, 0x8c, 0xe5, 0x98, 0xfa, 0x96, 0xe5, 0x37, 0x2e, 0xef, 0x3d, 0x24, 0x8a, 0xfd, 0xe1, 0x74, 0x63, 0xeb, 0xbf, 0xab, 0xb8, 0xe4, 0xd1, 0xab, 0x50, 0x2a, 0x54, 0xec, 0x00, 0x64, 0xe9, 0x2f, 0x78, 0x19, 0x66, 0x0d, 0x3f, 0x27, 0xcf, 0x20, 0x9e, 0x66, 0x7f, 0xce, 0x5a, 0xe2, 0xe4, 0xac, 0x99, 0xc7, 0xc9, 0x38, 0x18, 0xf8, 0xb2, 0x51, 0x07, 0x22, 0xdf, 0xed, 0x97, 0xf3, 0x2e, 0x3e, 0x93, 0x49, 0xd4, 0xc6, 0x6c, 0x9e, 0xa6, 0x39, 0x6d, 0x74, 0x44, 0x62, 0xa0, 0x6b, 0x42, 0xc6, 0xd5, 0xba, 0x68, 0x8e, 0xac, 0x3a, 0x01, 0x7b, 0xdd, 0xfc, 0x8e, 0x2c, 0xfc, 0xad, 0x27, 0xcb, 0x69, 0xd3, 0xcc, 0xdc, 0xa2, 0x80, 0x41, 0x44, 0x65, 0xd3, 0xae, 0x34, 0x8c, 0xe0, 0xf3, 0x4a, 0xb2, 0xfb, 0x9c, 0x61, 0x83, 0x71, 0x31, 0x2b, 0x19, 0x10, 0x41, 0x64, 0x1c, 0x23, 0x7f, 0x11, 0xa5, 0xd6, 0x5c, 0x84, 0x4f, 0x04, 0x04, 0x84, 0x99, 0x38, 0x71, 0x2b, 0x95, 0x9e, 0xd6, 0x85, 0xbc, 0x5c, 0x5d, 0xd6, 0x45, 0xed, 0x19, 0x90, 0x94, 0x73, 0x40, 0x29, 0x26, 0xdc, 0xb4, 0x0e, 0x34, 0x69, 0xa1, 0x59, 0x41, 0xe8, 0xe2, 0xcc, 0xa8, 0x4b, 0xb6, 0x08, 0x46, 0x36, 0xa0
|
||||
];
|
||||
|
||||
const KEY_USAGE: [u8; 16] = [
|
||||
0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x05, 0xa0
|
||||
];
|
||||
|
||||
const EXTENDED_KEY_USAGE: [u8; 31] = [
|
||||
0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04,
|
||||
0x16, 0x30, 0x14, 0x06, 0x08, 0x2b, 0x06, 0x01,
|
||||
0x05, 0x05, 0x07, 0x03, 0x02, 0x06, 0x08, 0x2b,
|
||||
0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x01
|
||||
];
|
||||
|
||||
const EXTENSIONS: [u8; 360] = [
|
||||
0xa3, 0x52, 0x30, 0x50, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x05, 0xa0, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, 0x16, 0x30, 0x14, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x01, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x89, 0x4f, 0xde, 0x5b, 0xcc, 0x69, 0xe2, 0x52, 0xcf, 0x3e, 0xa3, 0x00, 0xdf, 0xb1, 0x97, 0xb8, 0x1d, 0xe1, 0xc1, 0x46, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x59, 0x16, 0x45, 0xa6, 0x9a, 0x2e, 0x37, 0x79, 0xe4, 0xf6, 0xdd, 0x27, 0x1a, 0xba, 0x1c, 0x0b, 0xfd, 0x6c, 0xd7, 0x55, 0x99, 0xb5, 0xe7, 0xc3, 0x6e, 0x53, 0x3e, 0xff, 0x36, 0x59, 0x08, 0x43, 0x24, 0xc9, 0xe7, 0xa5, 0x04, 0x07, 0x9d, 0x39, 0xe0, 0xd4, 0x29, 0x87, 0xff, 0xe3, 0xeb, 0xdd, 0x09, 0xc1, 0xcf, 0x1d, 0x91, 0x44, 0x55, 0x87, 0x0b, 0x57, 0x1d, 0xd1, 0x9b, 0xdf, 0x1d, 0x24, 0xf8, 0xbb, 0x9a, 0x11, 0xfe, 0x80, 0xfd, 0x59, 0x2b, 0xa0, 0x39, 0x8c, 0xde, 0x11, 0xe2, 0x65, 0x1e, 0x61, 0x8c, 0xe5, 0x98, 0xfa, 0x96, 0xe5, 0x37, 0x2e, 0xef, 0x3d, 0x24, 0x8a, 0xfd, 0xe1, 0x74, 0x63, 0xeb, 0xbf, 0xab, 0xb8, 0xe4, 0xd1, 0xab, 0x50, 0x2a, 0x54, 0xec, 0x00, 0x64, 0xe9, 0x2f, 0x78, 0x19, 0x66, 0x0d, 0x3f, 0x27, 0xcf, 0x20, 0x9e, 0x66, 0x7f, 0xce, 0x5a, 0xe2, 0xe4, 0xac, 0x99, 0xc7, 0xc9, 0x38, 0x18, 0xf8, 0xb2, 0x51, 0x07, 0x22, 0xdf, 0xed, 0x97, 0xf3, 0x2e, 0x3e, 0x93, 0x49, 0xd4, 0xc6, 0x6c, 0x9e, 0xa6, 0x39, 0x6d, 0x74, 0x44, 0x62, 0xa0, 0x6b, 0x42, 0xc6, 0xd5, 0xba, 0x68, 0x8e, 0xac, 0x3a, 0x01, 0x7b, 0xdd, 0xfc, 0x8e, 0x2c, 0xfc, 0xad, 0x27, 0xcb, 0x69, 0xd3, 0xcc, 0xdc, 0xa2, 0x80, 0x41, 0x44, 0x65, 0xd3, 0xae, 0x34, 0x8c, 0xe0, 0xf3, 0x4a, 0xb2, 0xfb, 0x9c, 0x61, 0x83, 0x71, 0x31, 0x2b, 0x19, 0x10, 0x41, 0x64, 0x1c, 0x23, 0x7f, 0x11, 0xa5, 0xd6, 0x5c, 0x84, 0x4f, 0x04, 0x04, 0x84, 0x99, 0x38, 0x71, 0x2b, 0x95, 0x9e, 0xd6, 0x85, 0xbc, 0x5c, 0x5d, 0xd6, 0x45, 0xed, 0x19, 0x90, 0x94, 0x73, 0x40, 0x29, 0x26, 0xdc, 0xb4, 0x0e, 0x34, 0x69, 0xa1, 0x59, 0x41, 0xe8, 0xe2, 0xcc, 0xa8, 0x4b, 0xb6, 0x08, 0x46, 0x36, 0xa0
|
||||
];
|
||||
|
||||
const CERTIFICATE: [u8; 0x325] = [
|
||||
0x30, 0x82, 0x03, 0x21, 0x30, 0x82, 0x02, 0x09, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x08, 0x15, 0x5a, 0x92, 0xad, 0xc2, 0x04, 0x8f, 0x90, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x22, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0a, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x38, 0x31, 0x30, 0x30, 0x35, 0x30, 0x31, 0x33, 0x38, 0x31, 0x37, 0x5a, 0x17, 0x0d, 0x31, 0x39, 0x31, 0x30, 0x30, 0x35, 0x30, 0x31, 0x33, 0x38, 0x31, 0x37, 0x5a, 0x30, 0x2b, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x1c, 0x30, 0x1a, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x13, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x75, 0x6c, 0x66, 0x68, 0x65, 0x69, 0x6d, 0x2e, 0x6e, 0x65, 0x74, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xc4, 0x80, 0x36, 0x06, 0xba, 0xe7, 0x47, 0x6b, 0x08, 0x94, 0x04, 0xec, 0xa7, 0xb6, 0x91, 0x04, 0x3f, 0xf7, 0x92, 0xbc, 0x19, 0xee, 0xfb, 0x7d, 0x74, 0xd7, 0xa8, 0x0d, 0x00, 0x1e, 0x7b, 0x4b, 0x3a, 0x4a, 0xe6, 0x0f, 0xe8, 0xc0, 0x71, 0xfc, 0x73, 0xe7, 0x02, 0x4c, 0x0d, 0xbc, 0xf4, 0xbd, 0xd1, 0x1d, 0x39, 0x6b, 0xba, 0x70, 0x46, 0x4a, 0x13, 0xe9, 0x4a, 0xf8, 0x3d, 0xf3, 0xe1, 0x09, 0x59, 0x54, 0x7b, 0xc9, 0x55, 0xfb, 0x41, 0x2d, 0xa3, 0x76, 0x52, 0x11, 0xe1, 0xf3, 0xdc, 0x77, 0x6c, 0xaa, 0x53, 0x37, 0x6e, 0xca, 0x3a, 0xec, 0xbe, 0xc3, 0xaa, 0xb7, 0x3b, 0x31, 0xd5, 0x6c, 0xb6, 0x52, 0x9c, 0x80, 0x98, 0xbc, 0xc9, 0xe0, 0x28, 0x18, 0xe2, 0x0b, 0xf7, 0xf8, 0xa0, 0x3a, 0xfd, 0x17, 0x04, 0x50, 0x9e, 0xce, 0x79, 0xbd, 0x9f, 0x39, 0xf1, 0xea, 0x69, 0xec, 0x47, 0x97, 0x2e, 0x83, 0x0f, 0xb5, 0xca, 0x95, 0xde, 0x95, 0xa1, 0xe6, 0x04, 0x22, 0xd5, 0xee, 0xbe, 0x52, 0x79, 0x54, 0xa1, 0xe7, 0xbf, 0x8a, 0x86, 0xf6, 0x46, 0x6d, 0x0d, 0x9f, 0x16, 0x95, 0x1a, 0x4c, 0xf7, 0xa0, 0x46, 0x92, 0x59, 0x5c, 0x13, 0x52, 0xf2, 0x54, 0x9e, 0x5a, 0xfb, 0x4e, 0xbf, 0xd7, 0x7a, 0x37, 0x95, 0x01, 0x44, 0xe4, 0xc0, 0x26, 0x87, 0x4c, 0x65, 0x3e, 0x40, 0x7d, 0x7d, 0x23, 0x07, 0x44, 0x01, 0xf4, 0x84, 0xff, 0xd0, 0x8f, 0x7a, 0x1f, 0xa0, 0x52, 0x10, 0xd1, 0xf4, 0xf0, 0xd5, 0xce, 0x79, 0x70, 0x29, 0x32, 0xe2, 0xca, 0xbe, 0x70, 0x1f, 0xdf, 0xad, 0x6b, 0x4b, 0xb7, 0x11, 0x01, 0xf4, 0x4b, 0xad, 0x66, 0x6a, 0x11, 0x13, 0x0f, 0xe2, 0xee, 0x82, 0x9e, 0x4d, 0x02, 0x9d, 0xc9, 0x1c, 0xdd, 0x67, 0x16, 0xdb, 0xb9, 0x06, 0x18, 0x86, 0xed, 0xc1, 0xba, 0x94, 0x21, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x52, 0x30, 0x50, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x05, 0xa0, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, 0x16, 0x30, 0x14, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x01, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x89, 0x4f, 0xde, 0x5b, 0xcc, 0x69, 0xe2, 0x52, 0xcf, 0x3e, 0xa3, 0x00, 0xdf, 0xb1, 0x97, 0xb8, 0x1d, 0xe1, 0xc1, 0x46, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x59, 0x16, 0x45, 0xa6, 0x9a, 0x2e, 0x37, 0x79, 0xe4, 0xf6, 0xdd, 0x27, 0x1a, 0xba, 0x1c, 0x0b, 0xfd, 0x6c, 0xd7, 0x55, 0x99, 0xb5, 0xe7, 0xc3, 0x6e, 0x53, 0x3e, 0xff, 0x36, 0x59, 0x08, 0x43, 0x24, 0xc9, 0xe7, 0xa5, 0x04, 0x07, 0x9d, 0x39, 0xe0, 0xd4, 0x29, 0x87, 0xff, 0xe3, 0xeb, 0xdd, 0x09, 0xc1, 0xcf, 0x1d, 0x91, 0x44, 0x55, 0x87, 0x0b, 0x57, 0x1d, 0xd1, 0x9b, 0xdf, 0x1d, 0x24, 0xf8, 0xbb, 0x9a, 0x11, 0xfe, 0x80, 0xfd, 0x59, 0x2b, 0xa0, 0x39, 0x8c, 0xde, 0x11, 0xe2, 0x65, 0x1e, 0x61, 0x8c, 0xe5, 0x98, 0xfa, 0x96, 0xe5, 0x37, 0x2e, 0xef, 0x3d, 0x24, 0x8a, 0xfd, 0xe1, 0x74, 0x63, 0xeb, 0xbf, 0xab, 0xb8, 0xe4, 0xd1, 0xab, 0x50, 0x2a, 0x54, 0xec, 0x00, 0x64, 0xe9, 0x2f, 0x78, 0x19, 0x66, 0x0d, 0x3f, 0x27, 0xcf, 0x20, 0x9e, 0x66, 0x7f, 0xce, 0x5a, 0xe2, 0xe4, 0xac, 0x99, 0xc7, 0xc9, 0x38, 0x18, 0xf8, 0xb2, 0x51, 0x07, 0x22, 0xdf, 0xed, 0x97, 0xf3, 0x2e, 0x3e, 0x93, 0x49, 0xd4, 0xc6, 0x6c, 0x9e, 0xa6, 0x39, 0x6d, 0x74, 0x44, 0x62, 0xa0, 0x6b, 0x42, 0xc6, 0xd5, 0xba, 0x68, 0x8e, 0xac, 0x3a, 0x01, 0x7b, 0xdd, 0xfc, 0x8e, 0x2c, 0xfc, 0xad, 0x27, 0xcb, 0x69, 0xd3, 0xcc, 0xdc, 0xa2, 0x80, 0x41, 0x44, 0x65, 0xd3, 0xae, 0x34, 0x8c, 0xe0, 0xf3, 0x4a, 0xb2, 0xfb, 0x9c, 0x61, 0x83, 0x71, 0x31, 0x2b, 0x19, 0x10, 0x41, 0x64, 0x1c, 0x23, 0x7f, 0x11, 0xa5, 0xd6, 0x5c, 0x84, 0x4f, 0x04, 0x04, 0x84, 0x99, 0x38, 0x71, 0x2b, 0x95, 0x9e, 0xd6, 0x85, 0xbc, 0x5c, 0x5d, 0xd6, 0x45, 0xed, 0x19, 0x90, 0x94, 0x73, 0x40, 0x29, 0x26, 0xdc, 0xb4, 0x0e, 0x34, 0x69, 0xa1, 0x59, 0x41, 0xe8, 0xe2, 0xcc, 0xa8, 0x4b, 0xb6, 0x08, 0x46, 0x36, 0xa0
|
||||
];
|
||||
|
|
401
src/parse.rs
401
src/parse.rs
|
@ -3,6 +3,7 @@ use nom::bytes::complete::take;
|
|||
use nom::bytes::complete::tag;
|
||||
use nom::bytes::complete::take_till;
|
||||
use nom::combinator::complete;
|
||||
use nom::combinator::opt;
|
||||
use nom::sequence::preceded;
|
||||
use nom::sequence::tuple;
|
||||
use nom::error::make_error;
|
||||
|
@ -13,13 +14,20 @@ use smoltcp::Result;
|
|||
use byteorder::{ByteOrder, NetworkEndian, BigEndian};
|
||||
|
||||
use crate::tls_packet::*;
|
||||
use crate::certificate::Certificate as Asn1DerCertificate;
|
||||
use crate::certificate::Version as Asn1DerVersion;
|
||||
use crate::certificate::AlgorithmIdentifier as Asn1DerAlgId;
|
||||
use crate::certificate::Time as Asn1DerTime;
|
||||
use crate::certificate::Validity as Asn1DerValidity;
|
||||
use crate::certificate::SubjectPublicKeyInfo as Asn1DerSubjectPublicKeyInfo;
|
||||
use crate::certificate::Extensions as Asn1DerExtensions;
|
||||
|
||||
use crate::certificate::{
|
||||
Certificate as Asn1DerCertificate,
|
||||
Version as Asn1DerVersion,
|
||||
AlgorithmIdentifier as Asn1DerAlgId,
|
||||
Time as Asn1DerTime,
|
||||
Validity as Asn1DerValidity,
|
||||
SubjectPublicKeyInfo as Asn1DerSubjectPublicKeyInfo,
|
||||
Extensions as Asn1DerExtensions,
|
||||
Extension as Asn1DerExtension,
|
||||
ExtensionValue as Asn1DerExtensionValue,
|
||||
PolicyInformation as Asn1DerPolicyInformation,
|
||||
TBSCertificate as Asn1DerTBSCertificate,
|
||||
};
|
||||
|
||||
use core::convert::TryFrom;
|
||||
use core::convert::TryInto;
|
||||
|
@ -120,6 +128,9 @@ pub(crate) fn parse_handshake(bytes: &[u8]) -> IResult<&[u8], HandshakeRepr> {
|
|||
)(rest)?;
|
||||
|
||||
Ok((&[], repr))
|
||||
},
|
||||
Certificate => {
|
||||
todo!()
|
||||
}
|
||||
_ => todo!()
|
||||
}
|
||||
|
@ -362,28 +373,80 @@ pub fn parse_asn1_der_header(bytes: &[u8]) -> IResult<&[u8], (u8, usize)> {
|
|||
for array_index in 0..length_slice.len() {
|
||||
length_array[array_index + 8 - length_slice.len()] = length_slice[array_index];
|
||||
}
|
||||
Ok((rem, (tag[0], usize::from_be_bytes(length_array))))
|
||||
let (_, length_array) = length_array.split_at(8 - core::mem::size_of::<usize>());
|
||||
Ok((rem, (tag[0], usize::from_be_bytes((*length_array).try_into().unwrap()))))
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Not return length
|
||||
// It is quite useless when the value slice of the exact same length is returned
|
||||
// i.e. `length` can be replaced by `value.len()`
|
||||
pub fn parse_asn1_der_object(bytes: &[u8]) -> IResult<&[u8], (u8, usize, &[u8])> {
|
||||
let (rest, (tag, length)) = parse_asn1_der_header(bytes)?;
|
||||
let (rest, value) = take(length)(rest)?;
|
||||
Ok((rest, (tag, length, value)))
|
||||
}
|
||||
|
||||
pub fn parse_asn1_der_certificate(bytes: &[u8]) -> IResult<&[u8], (&[u8], &[u8], &[u8])> {
|
||||
let (_, (_, _, rest)) = parse_asn1_der_object(bytes)?;
|
||||
let (rest, (_, _, tbscertificate_slice)) = parse_asn1_der_object(rest)?;
|
||||
let (rest, (_, _, signature_alg)) = parse_asn1_der_object(rest)?;
|
||||
let (rest, (_, _, sig_val)) = parse_asn1_der_object(rest)?;
|
||||
Ok((rest, (tbscertificate_slice, signature_alg, sig_val)))
|
||||
pub fn parse_asn1_der_certificate(bytes: &[u8]) -> IResult<&[u8], Asn1DerCertificate> {
|
||||
let (excluded, (_, _, rest)) = parse_asn1_der_object(bytes)?;
|
||||
let (_, (tbs_certificate, sig_alg, sig_value)) = complete(
|
||||
tuple((
|
||||
parse_asn1_der_tbs_certificate,
|
||||
parse_asn1_der_algorithm_identifier,
|
||||
parse_asn1_der_bit_string
|
||||
))
|
||||
)(rest)?;
|
||||
Ok((
|
||||
excluded,
|
||||
Asn1DerCertificate {
|
||||
tbs_certificate,
|
||||
signature_algorithm: sig_alg,
|
||||
signature_value: sig_value,
|
||||
}
|
||||
))
|
||||
}
|
||||
|
||||
pub fn parse_asn1_der_tbs_certificate(bytes: &[u8]) -> IResult<&[u8], Vec<&[u8]>> {
|
||||
todo!()
|
||||
// Parser for TBSCertificate (Sequence: 0x30)
|
||||
pub fn parse_asn1_der_tbs_certificate(bytes: &[u8]) -> IResult<&[u8], Asn1DerTBSCertificate> {
|
||||
let (rest, (tag_val, length, value)) = parse_asn1_der_object(bytes)?;
|
||||
// Verify the tag is indeed 0x30
|
||||
if tag_val != 0x30 {
|
||||
return Err(nom::Err::Failure((&[], ErrorKind::Verify)));
|
||||
}
|
||||
|
||||
let (_, (
|
||||
version, serial_number, signature, issuer, validity, subject,
|
||||
subject_public_key_info, issuer_unique_id, subject_unique_id, extensions
|
||||
)) = complete(
|
||||
tuple((
|
||||
parse_asn1_der_version,
|
||||
parse_asn1_der_serial_number,
|
||||
parse_asn1_der_algorithm_identifier,
|
||||
parse_asn1_der_sequence,
|
||||
parse_asn1_der_validity,
|
||||
parse_asn1_der_sequence,
|
||||
parse_asn1_der_subject_key_public_info,
|
||||
opt(parse_asn1_der_bit_string),
|
||||
opt(parse_asn1_der_bit_string),
|
||||
parse_asn1_der_extensions
|
||||
))
|
||||
)(value)?;
|
||||
|
||||
Ok((
|
||||
rest,
|
||||
Asn1DerTBSCertificate {
|
||||
version,
|
||||
serial_number,
|
||||
signature,
|
||||
issuer,
|
||||
validity,
|
||||
subject,
|
||||
subject_public_key_info,
|
||||
issuer_unique_id,
|
||||
subject_unique_id,
|
||||
extensions,
|
||||
}
|
||||
))
|
||||
}
|
||||
|
||||
// version: [0] EXPLICIT Version DEFAULT V1
|
||||
|
@ -398,9 +461,7 @@ pub fn parse_asn1_der_version(bytes: &[u8]) -> IResult<&[u8], Asn1DerVersion> {
|
|||
// Parse the encapsulated INTEGER, force completeness
|
||||
let (_, integer) = complete(parse_asn1_der_integer)(value)?;
|
||||
// Either 0, 1, or 2, take the last byte and assert all former bytes to be 0
|
||||
let (zeroes, version_byte) = take(integer.len()-1)(integer)?;
|
||||
complete(take_till(|byte| byte != 0))(zeroes)?;
|
||||
Ok((rest, Asn1DerVersion::try_from(version_byte[0]).unwrap()))
|
||||
Ok((rest, Asn1DerVersion::try_from(integer[0]).unwrap()))
|
||||
}
|
||||
|
||||
// INTEGER: tag: 0x02
|
||||
|
@ -410,8 +471,6 @@ pub fn parse_asn1_der_integer(bytes: &[u8]) -> IResult<&[u8], &[u8]> {
|
|||
if tag_val != 0x02 {
|
||||
return Err(nom::Err::Failure((&[], ErrorKind::Verify)));
|
||||
}
|
||||
// Consume the leading 0x00 byte
|
||||
let (value, _) = tag(&[0x00])(value)?;
|
||||
Ok((rest, value))
|
||||
}
|
||||
|
||||
|
@ -422,12 +481,35 @@ pub fn parse_asn1_der_bit_string(bytes: &[u8]) -> IResult<&[u8], &[u8]> {
|
|||
let (rest, (tag_val, length, value)) = parse_asn1_der_object(bytes)?;
|
||||
// Verify the tag is indeed 0x03
|
||||
if tag_val != 0x03 {
|
||||
return Err(nom::Err::Failure((&[], ErrorKind::Verify)));
|
||||
return Err(nom::Err::Error((bytes, ErrorKind::Verify)));
|
||||
}
|
||||
// Dump `unused_bit` field
|
||||
let (value, unused_bit_byte) = take(1_usize)(value)?;
|
||||
// Assert no unused bits, otherwise it is a malformatted key
|
||||
if value[0] != 0 {
|
||||
if unused_bit_byte[0] != 0 {
|
||||
return Err(nom::Err::Error((bytes, ErrorKind::Verify)));
|
||||
}
|
||||
Ok((rest, value))
|
||||
}
|
||||
|
||||
// BOOLEAN: tag: 0x01
|
||||
// Length should be 1
|
||||
// 0x00 -> false; 0xFF -> true
|
||||
pub fn parse_asn1_der_boolean(bytes: &[u8]) -> IResult<&[u8], bool> {
|
||||
let (rest, (tag_val, length, value)) = parse_asn1_der_object(bytes)?;
|
||||
// Verify the tag is indeed 0x01 and the length is 1
|
||||
// The value should be 0x00 or 0xFF
|
||||
if tag_val != 0x01 || length != 1 || (value[0] != 0x00 && value[0] != 0xFF) {
|
||||
return Err(nom::Err::Error((bytes, ErrorKind::Verify)));
|
||||
}
|
||||
Ok((rest, value[0] == 0xFF))
|
||||
}
|
||||
|
||||
// SEQUENCE: tag: 0x30
|
||||
pub fn parse_asn1_der_sequence(bytes: &[u8]) -> IResult<&[u8], &[u8]> {
|
||||
let (rest, (tag_val, length, value)) = parse_asn1_der_object(bytes)?;
|
||||
// Verify the tag is indeed 0x03
|
||||
if tag_val != 0x30 {
|
||||
return Err(nom::Err::Failure((&[], ErrorKind::Verify)));
|
||||
}
|
||||
Ok((rest, value))
|
||||
|
@ -537,12 +619,281 @@ pub fn parse_asn1_der_subject_key_public_info(bytes: &[u8]) -> IResult<&[u8], As
|
|||
))
|
||||
}
|
||||
|
||||
// Parser for extensions (Sequence: 0xA3)
|
||||
// Parser for extensions (Context-specific Sequence: 0xA3, then universal Sequence: 0x30)
|
||||
pub fn parse_asn1_der_extensions(bytes: &[u8]) -> IResult<&[u8], Asn1DerExtensions> {
|
||||
let (rest, (tag_val, length, value)) = parse_asn1_der_object(bytes)?;
|
||||
// Verify the tag_val is indeed 0xA3
|
||||
if tag_val != 0xA3 {
|
||||
return Err(nom::Err::Failure((&[], ErrorKind::Verify)));
|
||||
}
|
||||
todo!()
|
||||
|
||||
let (_, (tag_val, length, mut value)) = complete(
|
||||
parse_asn1_der_object
|
||||
)(value)?;
|
||||
// Verify the tag_val is indeed 0x30
|
||||
if tag_val != 0x30 {
|
||||
return Err(nom::Err::Failure((&[], ErrorKind::Verify)));
|
||||
}
|
||||
|
||||
let mut extensions = Vec::new();
|
||||
while value.len() != 0 {
|
||||
let (rem, extension) = parse_asn1_der_extension(value)?;
|
||||
value = rem;
|
||||
extensions.push(extension);
|
||||
}
|
||||
|
||||
Ok((
|
||||
rest,
|
||||
Asn1DerExtensions { extensions }
|
||||
))
|
||||
}
|
||||
|
||||
// Parser for an extension (Sequence: 0x30)
|
||||
pub fn parse_asn1_der_extension(bytes: &[u8]) -> IResult<&[u8], Asn1DerExtension> {
|
||||
let (rest, (tag_val, length, value)) = parse_asn1_der_object(bytes)?;
|
||||
// Verify the tag_val is indeed 0x30
|
||||
if tag_val != 0x30 {
|
||||
return Err(nom::Err::Failure((&[], ErrorKind::Verify)));
|
||||
}
|
||||
|
||||
// Parse an appropriate extension according to OID and critical-ness
|
||||
let (_, (oid, critical, rem_ext_data)) = complete(
|
||||
tuple((
|
||||
parse_asn1_der_oid,
|
||||
opt(parse_asn1_der_boolean),
|
||||
parse_asn1_der_octet_string
|
||||
))
|
||||
)(value)?;
|
||||
|
||||
let extension_value = match oid {
|
||||
oid::CERT_KEY_USAGE => {
|
||||
let (_, extension_value) = complete(
|
||||
parse_asn1_der_key_usage
|
||||
)(rem_ext_data)?;
|
||||
extension_value
|
||||
},
|
||||
oid::CERT_POLICIES => {
|
||||
let (_, extension_value) = complete(
|
||||
parse_asn1_der_certificate_policies
|
||||
)(rem_ext_data)?;
|
||||
extension_value
|
||||
},
|
||||
oid::CERT_BASIC_CONSTRAINTS => {
|
||||
let (_, extension_value) = complete(
|
||||
parse_asn1_der_basic_constraints
|
||||
)(rem_ext_data)?;
|
||||
extension_value
|
||||
},
|
||||
oid::CERT_EXT_KEY_USAGE => {
|
||||
let (_, extension_value) = complete(
|
||||
parse_asn1_der_extended_key_usage
|
||||
)(rem_ext_data)?;
|
||||
extension_value
|
||||
},
|
||||
oid::CERT_INHIBIT_ANY_POLICY => {
|
||||
let (_, extension_value) = complete(
|
||||
parse_inhibit_any_policy
|
||||
)(rem_ext_data)?;
|
||||
extension_value
|
||||
},
|
||||
// TODO: Parse extension value for recognized extensions
|
||||
_ => Asn1DerExtensionValue::Unrecognized
|
||||
};
|
||||
Ok((
|
||||
rest,
|
||||
Asn1DerExtension {
|
||||
extension_id: oid,
|
||||
critical: critical.map_or(false, |b| b),
|
||||
extension_value
|
||||
}
|
||||
))
|
||||
}
|
||||
|
||||
// Parser for KeyUsage Extension, may have bit padding
|
||||
// Do not use parse_asn1_der_bit_string, that assumes no bit padding
|
||||
pub fn parse_asn1_der_key_usage(bytes: &[u8]) -> IResult<&[u8], Asn1DerExtensionValue> {
|
||||
let (rest, (tag_val, length, value)) = parse_asn1_der_object(bytes)?;
|
||||
// Verify the tag_val represents a bitstring, and it must have length 2
|
||||
// i.e. bit-padding | bit-string
|
||||
if tag_val != 0x03 || (length != 2 && length != 3) {
|
||||
return Err(nom::Err::Failure((&[], ErrorKind::Verify)));
|
||||
}
|
||||
// Erase the padded bits
|
||||
let padding = value[0];
|
||||
let usage_array: [u8; 2] = if length == 2 {
|
||||
[value[1], 0]
|
||||
} else {
|
||||
[value[1], value[2]]
|
||||
};
|
||||
let usage = (NetworkEndian::read_u16(&usage_array) >> padding) << padding;
|
||||
Ok((
|
||||
rest,
|
||||
Asn1DerExtensionValue::KeyUsage {
|
||||
usage
|
||||
}
|
||||
))
|
||||
}
|
||||
|
||||
// Parser for CertificatePolicies Extension (sequence: 0x30)
|
||||
pub fn parse_asn1_der_certificate_policies(bytes: &[u8]) -> IResult<&[u8], Asn1DerExtensionValue> {
|
||||
let (rest, (tag_val, length, mut value)) = parse_asn1_der_object(bytes)?;
|
||||
// Verify tag value
|
||||
if tag_val != 0x30 {
|
||||
return Err(nom::Err::Failure((&[], ErrorKind::Verify)));
|
||||
}
|
||||
|
||||
let mut vec: Vec<Asn1DerPolicyInformation> = Vec::new();
|
||||
|
||||
while value.len() != 0 {
|
||||
let (rem, info) = parse_asn1_der_policy_information(value)?;
|
||||
value = rem;
|
||||
vec.push(info);
|
||||
}
|
||||
|
||||
Ok((
|
||||
rest,
|
||||
Asn1DerExtensionValue::CertificatePolicies {
|
||||
info: vec,
|
||||
}
|
||||
))
|
||||
}
|
||||
|
||||
// Parser for PolicyInformation (Sequence: 0x30)
|
||||
pub fn parse_asn1_der_policy_information(bytes: &[u8]) -> IResult<&[u8], Asn1DerPolicyInformation> {
|
||||
let (rest, (tag_val, length, value)) = parse_asn1_der_object(bytes)?;
|
||||
// Verify tag value
|
||||
if tag_val != 0x30 {
|
||||
return Err(nom::Err::Failure((&[], ErrorKind::Verify)));
|
||||
}
|
||||
|
||||
let (_, (oid, (_, _, qualifier))) = complete(
|
||||
tuple((
|
||||
parse_asn1_der_oid,
|
||||
parse_asn1_der_object
|
||||
))
|
||||
)(value)?;
|
||||
|
||||
Ok((
|
||||
rest,
|
||||
Asn1DerPolicyInformation {
|
||||
id: oid,
|
||||
qualifier
|
||||
}
|
||||
))
|
||||
}
|
||||
|
||||
// Parser for BasicConstraints (Sequence: 0x30)
|
||||
pub fn parse_asn1_der_basic_constraints(bytes: &[u8]) -> IResult<&[u8], Asn1DerExtensionValue> {
|
||||
let (rest, (tag_val, length, value)) = parse_asn1_der_object(bytes)?;
|
||||
// Verify tag value
|
||||
if tag_val != 0x30 {
|
||||
return Err(nom::Err::Failure((&[], ErrorKind::Verify)));
|
||||
}
|
||||
let (_, (is_ca, path_len_constraint)) = complete(
|
||||
tuple((
|
||||
opt(parse_asn1_der_boolean),
|
||||
opt(parse_asn1_der_integer)
|
||||
))
|
||||
)(value)?;
|
||||
let is_ca = is_ca.map_or(false, |b| b);
|
||||
let path_len_constraint = path_len_constraint.map(
|
||||
|slice| {
|
||||
if slice.len() != 1 {
|
||||
255
|
||||
} else {
|
||||
slice[0]
|
||||
}
|
||||
}
|
||||
);
|
||||
Ok((
|
||||
rest,
|
||||
Asn1DerExtensionValue::BasicConstraints {
|
||||
is_ca,
|
||||
path_len_constraint
|
||||
}
|
||||
))
|
||||
}
|
||||
|
||||
// Parser for Extended Key Usage Extension (Sequence: 0x30)
|
||||
pub fn parse_asn1_der_extended_key_usage(bytes: &[u8]) -> IResult<&[u8], Asn1DerExtensionValue> {
|
||||
let (rest, (tag_val, length, mut value)) = parse_asn1_der_object(bytes)?;
|
||||
// Verify tag value
|
||||
if tag_val != 0x30 {
|
||||
return Err(nom::Err::Failure((&[], ErrorKind::Verify)));
|
||||
}
|
||||
|
||||
let mut flags: [bool; 7] = [false; 7];
|
||||
|
||||
while value.len() != 0 {
|
||||
let (rem, oid_val) = parse_asn1_der_oid(value)?;
|
||||
value = rem;
|
||||
match oid_val {
|
||||
oid::ANY_EXTENDED_KEY_USAGE => flags[0] = true,
|
||||
oid::ID_KP_SERVER_AUTH => flags[1] = true,
|
||||
oid::ID_KP_CLIENT_AUTH => flags[2] = true,
|
||||
oid::ID_KP_CODE_SIGNING => flags[3] = true,
|
||||
oid::ID_KP_EMAIL_PROTECTION => flags[4] = true,
|
||||
oid::ID_KP_TIME_STAMPING => flags[5] = true,
|
||||
oid::ID_KP_OCSP_SIGNING => flags[6] = true,
|
||||
_ => {},
|
||||
}
|
||||
}
|
||||
|
||||
Ok((
|
||||
rest,
|
||||
Asn1DerExtensionValue::ExtendedKeyUsage {
|
||||
any_extended_key_usage: flags[0],
|
||||
id_kp_server_auth: flags[1],
|
||||
id_kp_client_auth: flags[2],
|
||||
id_kp_code_signing: flags[3],
|
||||
id_kp_email_protection: flags[4],
|
||||
id_kp_time_stamping: flags[5],
|
||||
id_kp_oscp_signing: flags[6],
|
||||
}
|
||||
))
|
||||
}
|
||||
|
||||
// Parser for inhibit anyPolicy extension (integer)
|
||||
pub fn parse_inhibit_any_policy(bytes: &[u8]) -> IResult<&[u8], Asn1DerExtensionValue> {
|
||||
let (rest, integer_slice) = parse_asn1_der_integer(bytes)?;
|
||||
Ok((
|
||||
rest,
|
||||
Asn1DerExtensionValue::InhibitAnyPolicy {
|
||||
skip_certs: {
|
||||
if integer_slice.len() == 1 {
|
||||
integer_slice[0]
|
||||
} else {
|
||||
255
|
||||
}
|
||||
}
|
||||
}
|
||||
))
|
||||
}
|
||||
|
||||
|
||||
// Parser for octet string (tag: 0x04)
|
||||
pub fn parse_asn1_der_octet_string(bytes: &[u8]) -> IResult<&[u8], &[u8]> {
|
||||
let (rest, (tag_val, length, value)) = parse_asn1_der_object(bytes)?;
|
||||
// Verify tag value
|
||||
if tag_val != 0x04 {
|
||||
return Err(nom::Err::Failure((&[], ErrorKind::Verify)));
|
||||
}
|
||||
Ok((rest, value))
|
||||
}
|
||||
|
||||
mod oid {
|
||||
// Extensions
|
||||
pub const CERT_KEY_USAGE: &'static [u8] = &[85, 29, 15]; // 2.5.29.15
|
||||
pub const CERT_POLICIES: &'static [u8] = &[85, 29, 32]; // 2.5.29.32
|
||||
pub const CERT_BASIC_CONSTRAINTS: &'static [u8] = &[85, 29, 19]; // 2.5.29.19
|
||||
pub const CERT_EXT_KEY_USAGE: &'static [u8] = &[85, 29, 37]; // 2.5.29.37
|
||||
pub const CERT_INHIBIT_ANY_POLICY: &'static [u8] = &[85, 29, 54]; // 2.5.29.54
|
||||
// Extended Key Extensions
|
||||
pub const ANY_EXTENDED_KEY_USAGE: &'static [u8] = &[85, 29, 37, 0]; // 2.5.29.37.0
|
||||
pub const ID_KP_SERVER_AUTH: &'static [u8] = &[43, 6, 1, 5, 5, 7, 3, 1]; // 1.3.6.1.5.5.7.3.1
|
||||
pub const ID_KP_CLIENT_AUTH: &'static [u8] = &[43, 6, 1, 5, 5, 7, 3, 2]; // 1.3.6.1.5.5.7.3.2
|
||||
pub const ID_KP_CODE_SIGNING: &'static [u8] = &[43, 6, 1, 5, 5, 7, 3, 3]; // 1.3.6.1.5.5.7.3.3
|
||||
pub const ID_KP_EMAIL_PROTECTION: &'static [u8] = &[43, 6, 1, 5, 5, 7, 3, 4]; // 1.3.6.1.5.5.7.3.4
|
||||
pub const ID_KP_TIME_STAMPING: &'static [u8] = &[43, 6, 1, 5, 5, 7, 3, 8]; // 1.3.6.1.5.5.7.3.8
|
||||
pub const ID_KP_OCSP_SIGNING: &'static [u8] = &[43, 6, 1, 5, 5, 7, 3, 9]; // 1.3.6.1.5.5.7.3.9
|
||||
}
|
||||
|
|
|
@ -650,10 +650,12 @@ pub(crate) struct ServerName {
|
|||
// This TLS implementation still yet to support certificate negotiation
|
||||
#[derive(Debug, Clone)]
|
||||
pub(crate) enum CertificateEntryInfo<'a> {
|
||||
// Ideally, this enum variant should never be touched
|
||||
RawPublicKey {
|
||||
ASN1_subjectPublicKeyInfo_length: u32, // Only 24 bits
|
||||
ASN1_subjectPublicKeyInfo: &'a [u8],
|
||||
},
|
||||
|
||||
X509 {
|
||||
cert_data_length: u32, // Only 24 bits
|
||||
cert_data: &'a [u8],
|
||||
|
|
Loading…
Reference in New Issue