Enum Identity
pub enum Identity {
PubKey(Vec<u8>),
Token(u64),
EcmaKey(Vec<u8>),
}Expand description
Assembly identity representation for .NET CIL assemblies.
Represents the cryptographic identity of a .NET assembly using one of three standardized identity mechanisms defined by ECMA-335. This enum supports all primary assembly identification types used throughout the .NET ecosystem.
§Variants
Identity::PubKey: Stores the complete RSA public key data for strong-named assembliesIdentity::Token: Stores an 8-byte hash of the public key for compact representationIdentity::EcmaKey: Stores a 16-byte ECMA key used by framework assemblies
§Usage in .NET
- Strong-named assemblies: Use public keys for cryptographic verification
- Assembly references: Often use tokens for compact storage in metadata
- GAC storage: Uses tokens as part of the unique assembly identifier
- Security policies: May require full public key validation
§Examples
use dotscope::metadata::identity::Identity;
use dotscope::metadata::tables::AssemblyHashAlgorithm;
// Full public key identity
let pubkey_data = vec![0x30, 0x82, 0x01, 0x0A]; // RSA public key start
let identity = Identity::from(&pubkey_data, true)?;
// Generate token for compact representation
match identity {
Identity::PubKey(ref key_data) => {
let token = identity.to_token(AssemblyHashAlgorithm::SHA1)?;
println!("Key length: {} bytes, Token: 0x{:016X}", key_data.len(), token);
}
Identity::Token(token) => {
println!("Direct token: 0x{:016X}", token);
}
_ => {}
}Variants§
PubKey(Vec<u8>)
Complete RSA public key data for strong-named assemblies.
Contains the full binary representation of an RSA public key as stored in .NET assembly metadata. This data can be used for cryptographic verification of assembly signatures and strong name validation.
§Format
The data typically follows the standard RSA public key format used by .NET:
- ASN.1 DER encoding for the public key structure
- May include additional .NET-specific metadata
- Variable length depending on key size (typically 1024-4096 bits)
Token(u64)
Compact 8-byte token derived from hashing the public key.
The token is computed as the last 8 bytes of the hash (MD5 or SHA1) of the public key data. This provides a compact identifier while maintaining reasonable uniqueness for assembly identification purposes.
§Token Generation
- Hash the complete public key using the specified algorithm
- Extract the last 8 bytes of the hash result
- Interpret as little-endian 64-bit unsigned integer
§Collision Resistance
While 8 bytes provides only 64 bits of collision resistance, this is considered sufficient for .NET assembly identification in practice.
EcmaKey(Vec<u8>)
ECMA standard 16-byte key for framework assemblies.
ECMA keys are special shortened cryptographic identities used by core framework assemblies as defined in ECMA-335. These 16-byte keys provide a standardized identity mechanism for system assemblies while being more compact than full RSA public keys.
§Usage Context
- Framework assemblies: mscorlib, System.Core, System.dll, etc.
- Standard libraries: Core .NET framework components
- Platform assemblies: Mono framework assemblies
- Compatibility: Legacy and cross-platform .NET implementations
§Format
ECMA keys are exactly 16 bytes in length and follow the ECMA-335 specification for standard assembly identification. Unlike full public keys, they cannot be used for cryptographic verification but provide reliable assembly identification.
§Examples
Common ECMA key patterns found in framework assemblies:
- Fixed byte sequences for standard framework components
- Platform-specific variations for Mono/Unity implementations
- Standardized keys for cross-platform compatibility
Implementations§
§impl Identity
impl Identity
pub fn from(data: &[u8], is_pub: bool) -> Result<Self>
pub fn from(data: &[u8], is_pub: bool) -> Result<Self>
Create an Identity from raw binary data.
Constructs the appropriate identity type based on data length and the is_pub flag.
This method automatically detects ECMA keys and provides the primary constructor
for identity objects parsed from .NET metadata.
§Arguments
data- Raw binary data from assembly metadatais_pub-truefor public key data,falsefor token data
§Detection Logic
- 8 bytes +
is_pub=false:Identity::Token(standard token) - 16 bytes +
is_pub=true:Identity::EcmaKey(ECMA framework key) - Other sizes +
is_pub=true:Identity::PubKey(full RSA public key)
§Returns
Identity::Tokenfor 8-byte token dataIdentity::EcmaKeyfor 16-byte ECMA keysIdentity::PubKeyfor other public key sizes
§Errors
Returns [crate::Error::OutOfBounds] if:
- Token creation requested but data has fewer than 8 bytes
- Data cannot be read as little-endian
u64
§Examples
use dotscope::metadata::identity::Identity;
// Create full RSA public key identity (>16 bytes)
let pubkey_data = vec![0x30, 0x82, 0x01, 0x0A, /* ... rest of 160+ byte key ... */];
let pubkey_identity = Identity::from(&pubkey_data, true)?;
// Create ECMA key identity (exactly 16 bytes)
let ecma_data = vec![0x06, 0x28, 0xAC, 0x03, 0x00, 0x06, 0x7A, 0x06,
0x6F, 0xAB, 0x02, 0x00, 0x0A, 0x0B, 0x17, 0x6A];
let ecma_identity = Identity::from(&ecma_data, true)?;
// Create token identity (8 bytes)
let token_data = vec![0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0];
let token_identity = Identity::from(&token_data, false)?;
match ecma_identity {
Identity::EcmaKey(ref key) => println!("ECMA key: {} bytes", key.len()),
Identity::PubKey(ref key) => println!("Public key: {} bytes", key.len()),
Identity::Token(token) => println!("Token: 0x{:016X}", token),
}§Thread Safety
This method is thread-safe and can be called concurrently from multiple threads.
pub fn to_token(&self, algo: u32) -> Result<u64>
pub fn to_token(&self, algo: u32) -> Result<u64>
Generate a token from this identity using the specified hash algorithm.
Computes an 8-byte token that uniquely identifies this assembly. For public key identities, this involves hashing the key data. For token identities, this returns the stored token value regardless of the algorithm specified.
§Algorithm Support
- MD5 (
crate::metadata::tables::AssemblyHashAlgorithm::MD5): Legacy algorithm, 16-byte hash - SHA1 (
crate::metadata::tables::AssemblyHashAlgorithm::SHA1): Standard algorithm, 20-byte hash - Others: Returns an error for unsupported algorithms
§Token Extraction
The token is always the last 8 bytes of the hash result, interpreted as a little-endian 64-bit unsigned integer. This follows the .NET runtime convention.
§Arguments
algo- Hash algorithm identifier fromcrate::metadata::tables::AssemblyHashAlgorithm
§Returns
64-bit token value suitable for assembly identification and comparison.
§Errors
Returns an error if:
- The hash algorithm is not supported (only MD5 and SHA1 are implemented)
- The hash result cannot be read as a little-endian u64
§Examples
use dotscope::metadata::identity::Identity;
use dotscope::metadata::tables::AssemblyHashAlgorithm;
let pubkey_data = vec![0x30, 0x82, /* ... public key data ... */];
let identity = Identity::from(&pubkey_data, true)?;
// Generate token using SHA1 (recommended)
let sha1_token = identity.to_token(AssemblyHashAlgorithm::SHA1)?;
println!("SHA1 token: 0x{:016X}", sha1_token);
// Generate token using MD5 (legacy)
let md5_token = identity.to_token(AssemblyHashAlgorithm::MD5)?;
println!("MD5 token: 0x{:016X}", md5_token);
// Different algorithms produce different tokens
assert_ne!(sha1_token, md5_token);§Thread Safety
This method is thread-safe and can be called concurrently from multiple threads. Hash operations are stateless and do not modify the identity instance.
Trait Implementations§
impl Eq for Identity
impl StructuralPartialEq for Identity
Auto Trait Implementations§
impl Freeze for Identity
impl RefUnwindSafe for Identity
impl Send for Identity
impl Sync for Identity
impl Unpin for Identity
impl UnsafeUnpin for Identity
impl UnwindSafe for Identity
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> Downcast for T
impl<T> Downcast for T
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.impl<T> ErasedDestructor for Twhere
T: 'static,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§impl<F, T> IntoSample<T> for Fwhere
T: FromSample<F>,
impl<F, T> IntoSample<T> for Fwhere
T: FromSample<F>,
fn into_sample(self) -> T
Source§impl<T> Pointable for T
impl<T> Pointable for T
Source§impl<T> PolicyExt for Twhere
T: ?Sized,
impl<T> PolicyExt for Twhere
T: ?Sized,
impl<T> Read<Exclusive, BecauseExclusive> for Twhere
T: ?Sized,
impl<T> Scalar for T
Source§impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
Source§fn to_subset(&self) -> Option<SS>
fn to_subset(&self) -> Option<SS>
self from the equivalent element of its
superset. Read moreSource§fn is_in_subset(&self) -> bool
fn is_in_subset(&self) -> bool
self is actually part of its subset T (and can be converted to it).Source§fn to_subset_unchecked(&self) -> SS
fn to_subset_unchecked(&self) -> SS
self.to_subset but without any property checks. Always succeeds.Source§fn from_subset(element: &SS) -> SP
fn from_subset(element: &SS) -> SP
self to the equivalent element of its superset.