der-oid-macro-0.5.0/.cargo_vcs_info.json0000644000000001120000000000100134520ustar { "git": { "sha1": "658513e9518f792daf7ed7bf53db906ba3eccfed" } } der-oid-macro-0.5.0/Cargo.toml0000644000000020120000000000100114510ustar # THIS FILE IS AUTOMATICALLY GENERATED BY CARGO # # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies # to registry (e.g., crates.io) dependencies # # If you believe there's an error in this file please file an # issue against the rust-lang/cargo repository. If you're # editing this file be aware that the upstream Cargo.toml # will likely look very different (and much more reasonable) [package] edition = "2018" name = "der-oid-macro" version = "0.5.0" authors = ["Pierre Chifflier ", "Jannik Schürg "] description = "Macro to encode DER oids at compile time" homepage = "https://github.com/rusticata/der-parser" license = "MIT/Apache-2.0" repository = "https://github.com/rusticata/der-parser.git" [lib] proc-macro = true [dependencies.num-bigint] version = "0.4" [dependencies.num-traits] version = "0.2" [dependencies.syn] version = "1.0" der-oid-macro-0.5.0/Cargo.toml.orig000064400000000000000000000007060072674642500151720ustar 00000000000000[package] name = "der-oid-macro" description = "Macro to encode DER oids at compile time" version = "0.5.0" edition = "2018" license = "MIT/Apache-2.0" homepage = "https://github.com/rusticata/der-parser" repository = "https://github.com/rusticata/der-parser.git" authors = ["Pierre Chifflier ", "Jannik Schürg "] [lib] proc-macro = true [dependencies] num-bigint = "0.4" num-traits = "0.2" syn = "1.0" der-oid-macro-0.5.0/src/lib.rs000064400000000000000000000052020072674642500142020ustar 00000000000000use proc_macro::TokenStream; fn encode_components(components: &[num_bigint::BigUint], relative: bool) -> Vec { use num_traits::cast::ToPrimitive; let mut enc = Vec::new(); let mut dec = components; if !relative { if dec.len() < 2 { if dec.len() == 1 && dec[0] == 0u8.into() { return vec![0]; } panic!("Need at least two components for non-relative oid"); } if dec[0] >= 7u8.into() || dec[1] >= 40u8.into() { panic!("First components are too big"); } enc.push(dec[0].to_u8().unwrap() * 40 + dec[1].to_u8().unwrap()); dec = &dec[2..]; } for int in dec.iter() { let mut bytes = int.to_bytes_be(); if bytes[0] == 0 { enc.push(0u8); continue; } let total_bits = (8 - bytes[0].leading_zeros()) as usize + (bytes.len() - 1) * 8; let octects_needed = ((total_bits + 6) / 7).max(1); enc.resize_with(enc.len() + octects_needed, Default::default); let mut pos = enc.len() - 1; let mut extra = 0u8; let mut extra_size = 0u8; bytes.reverse(); let mut bytes_stored = 0; for byte in bytes.into_iter() { if extra_size == 7 { // there a seven bits in extra enc[pos] = extra | (1 << 7); bytes_stored += 1; pos -= 1; extra = 0; extra_size = 0; } // make space for the extra bits enc[pos] = (byte << extra_size) | extra | (1 << 7); bytes_stored += 1; if pos > 0 { pos -= 1; extra_size += 1; extra = byte >> (8 - extra_size); } } let last = enc.len() - 1; if bytes_stored != octects_needed { let first = last + 1 - octects_needed; enc[first] = extra | (1 << 7); } enc[last] ^= 1 << 7; } enc } #[proc_macro] pub fn encode_oid(input: TokenStream) -> TokenStream { let s = input.to_string(); let (rem, relative) = if s.starts_with("rel ") { (&s[4..], true) } else { (s.as_ref(), false) }; let ints: Vec = rem .split('.') .map(|segment| segment.trim()) .map(|s| s.parse().unwrap()) .collect(); let enc = encode_components(&ints, relative); let mut s = String::with_capacity(2 + 6 * enc.len()); s.push('['); for byte in enc.iter() { s.insert_str(s.len(), &format!("0x{:02x}, ", byte)); } s.push(']'); s.parse().unwrap() }