synta 0.2.4

ASN.1 parser, decoder, and encoder library with DER/BER support and C FFI
Documentation
//! Tests for Object Identifier (OID)

use std::str::FromStr;
use synta::{Decoder, Encoder, Encoding, ObjectIdentifier};

#[test]
fn test_oid_creation() {
    let oid = ObjectIdentifier::new(&[1, 2, 840, 113549]).unwrap();
    assert_eq!(oid.components(), &[1, 2, 840, 113549]);
}

#[test]
fn test_oid_validation() {
    // Too few components
    assert!(ObjectIdentifier::new(&[1]).is_err());

    // Invalid first component
    assert!(ObjectIdentifier::new(&[3, 0]).is_err());

    // Invalid second component when first is 0 or 1
    assert!(ObjectIdentifier::new(&[1, 40]).is_err());
    assert!(ObjectIdentifier::new(&[0, 50]).is_err());

    // Valid
    assert!(ObjectIdentifier::new(&[2, 100]).is_ok());
}

#[test]
#[cfg(feature = "std")]
fn test_oid_string_conversion() {
    let oid = ObjectIdentifier::new(&[1, 2, 840, 113549]).unwrap();
    assert_eq!(oid.to_string(), "1.2.840.113549");

    let parsed = ObjectIdentifier::from_str("1.2.840.113549").unwrap();
    assert_eq!(parsed, oid);
}

#[test]
fn test_oid_roundtrip() {
    let test_oids = vec![
        vec![0, 0],
        vec![0, 39],
        vec![1, 0],
        vec![1, 39],
        vec![2, 0],
        vec![2, 100],
        vec![2, 999],
        vec![1, 2, 840, 113549],         // RSA encryption OID
        vec![2, 5, 4, 3],                // Common Name OID
        vec![1, 2, 840, 10045, 3, 1, 7], // secp256r1 OID
    ];

    for components in test_oids {
        let oid = ObjectIdentifier::new(&components).unwrap();

        // Encode
        let mut encoder = Encoder::new(Encoding::Der);
        encoder.encode(&oid).unwrap();
        let encoded = encoder.finish().unwrap();

        // Decode
        let mut decoder = Decoder::new(&encoded, Encoding::Der);
        let decoded: ObjectIdentifier = decoder.decode().unwrap();

        assert_eq!(
            decoded.components(),
            &components[..],
            "Roundtrip failed for OID {:?}",
            components
        );
    }
}

#[test]
fn test_oid_known_encodings() {
    // Test known OID encodings

    // 1.2.840.113549 (RSA encryption)
    // First byte: 1*40 + 2 = 42 = 0x2A
    // 840 = 0x348 = 0b110 1001000, encoded as: 0x86 0x48
    // 113549 = 0x1BB8D = 0b1 1011 1011 1000 1101, encoded as: 0x86 0xF7 0x0D
    // Full encoding: 0x06 (OID tag), 0x06 (length), 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D
    let oid = ObjectIdentifier::new(&[1, 2, 840, 113549]).unwrap();
    let mut encoder = Encoder::new(Encoding::Der);
    encoder.encode(&oid).unwrap();
    let encoded = encoder.finish().unwrap();
    assert_eq!(
        encoded,
        vec![0x06, 0x06, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D]
    );

    // Verify decoding
    let mut decoder = Decoder::new(
        &[0x06, 0x06, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D],
        Encoding::Der,
    );
    let decoded: ObjectIdentifier = decoder.decode().unwrap();
    assert_eq!(decoded.components(), &[1, 2, 840, 113549]);

    // 2.5.4.3 (Common Name)
    // First byte: 2*40 + 5 = 85 = 0x55
    // 4 = 0x04
    // 3 = 0x03
    // Full encoding: 0x06, 0x03, 0x55, 0x04, 0x03
    let oid = ObjectIdentifier::new(&[2, 5, 4, 3]).unwrap();
    let mut encoder = Encoder::new(Encoding::Der);
    encoder.encode(&oid).unwrap();
    let encoded = encoder.finish().unwrap();
    assert_eq!(encoded, vec![0x06, 0x03, 0x55, 0x04, 0x03]);

    // Verify decoding
    let mut decoder = Decoder::new(&[0x06, 0x03, 0x55, 0x04, 0x03], Encoding::Der);
    let decoded: ObjectIdentifier = decoder.decode().unwrap();
    assert_eq!(decoded.components(), &[2, 5, 4, 3]);
}

#[test]
fn test_oid_first_component_variations() {
    // Test different first component values (0, 1, 2)

    // First component = 0
    let oid = ObjectIdentifier::new(&[0, 0]).unwrap();
    let mut encoder = Encoder::new(Encoding::Der);
    encoder.encode(&oid).unwrap();
    let encoded = encoder.finish().unwrap();
    // 0*40 + 0 = 0
    assert_eq!(&encoded[2..], &[0x00]);

    let oid = ObjectIdentifier::new(&[0, 39]).unwrap();
    let mut encoder = Encoder::new(Encoding::Der);
    encoder.encode(&oid).unwrap();
    let encoded = encoder.finish().unwrap();
    // 0*40 + 39 = 39 = 0x27
    assert_eq!(&encoded[2..], &[0x27]);

    // First component = 1
    let oid = ObjectIdentifier::new(&[1, 0]).unwrap();
    let mut encoder = Encoder::new(Encoding::Der);
    encoder.encode(&oid).unwrap();
    let encoded = encoder.finish().unwrap();
    // 1*40 + 0 = 40 = 0x28
    assert_eq!(&encoded[2..], &[0x28]);

    let oid = ObjectIdentifier::new(&[1, 39]).unwrap();
    let mut encoder = Encoder::new(Encoding::Der);
    encoder.encode(&oid).unwrap();
    let encoded = encoder.finish().unwrap();
    // 1*40 + 39 = 79 = 0x4F
    assert_eq!(&encoded[2..], &[0x4F]);

    // First component = 2
    let oid = ObjectIdentifier::new(&[2, 0]).unwrap();
    let mut encoder = Encoder::new(Encoding::Der);
    encoder.encode(&oid).unwrap();
    let encoded = encoder.finish().unwrap();
    // 2*40 + 0 = 80 = 0x50
    assert_eq!(&encoded[2..], &[0x50]);

    let oid = ObjectIdentifier::new(&[2, 100]).unwrap();
    let mut encoder = Encoder::new(Encoding::Der);
    encoder.encode(&oid).unwrap();
    let encoded = encoder.finish().unwrap();
    // 2*40 + 100 = 180 = 0xB4
    assert_eq!(&encoded[2..], &[0x81, 0x34]);
}

#[test]
fn test_oid_large_components() {
    // Test with large component values that require multi-byte base-128 encoding

    // Component value 16384 = 0x4000 = 0b100 0000 0000 0000
    // Base-128 encoding: 0x81 0x80 0x00
    let oid = ObjectIdentifier::new(&[1, 2, 16384]).unwrap();
    let mut encoder = Encoder::new(Encoding::Der);
    encoder.encode(&oid).unwrap();
    let encoded = encoder.finish().unwrap();

    let mut decoder = Decoder::new(&encoded, Encoding::Der);
    let decoded: ObjectIdentifier = decoder.decode().unwrap();
    assert_eq!(decoded.components(), &[1, 2, 16384]);
}