Devolutions / Devolutions/picky-rs

DER Serialization Problem

Open
#249 2 comments 0 reactions 0 assignees View on GitHub
Dominant language
Rust
Stars
69
Forks
42
PR merge metrics
No merged PRs in 30d

Description

Hi all,

I noticed _two_ potential problems when serializing a custom SAN containing a directory name using the `picky_asn1_der` crate.
Please, read them below.

## Potential Problem 1

According to [RFC 5280](https://datatracker.ietf.org/doc/html/rfc5280#section-4.2.1.6), the SAN should follow:

```
id-ce-subjectAltName OBJECT IDENTIFIER ::= { id-ce 17 }

SubjectAltName ::= GeneralNames

GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName

GeneralName ::= CHOICE {
otherName [0] OtherName,
rfc822Name [1] IA5String,
dNSName [2] IA5String,
x400Address [3] ORAddress,
directoryName [4] Name,
ediPartyName [5] EDIPartyName,
uniformResourceIdentifier [6] IA5String,
iPAddress [7] OCTET STRING,
registeredID [8] OBJECT IDENTIFIER }

OtherName ::= SEQUENCE {
type-id OBJECT IDENTIFIER,
value [0] EXPLICIT ANY DEFINED BY type-id }

EDIPartyName ::= SEQUENCE {
nameAssigner [0] DirectoryString OPTIONAL,
partyName [1] DirectoryString }
```

and:

```
Name ::= CHOICE { -- only one possibility for now --
rdnSequence RDNSequence }

RDNSequence ::= SEQUENCE OF RelativeDistinguishedName

RelativeDistinguishedName ::=
SET SIZE (1..MAX) OF AttributeTypeAndValue

AttributeTypeAndValue ::= SEQUENCE {
type AttributeType,
value AttributeValue }

AttributeType ::= OBJECT IDENTIFIER

AttributeValue ::= ANY -- DEFINED BY AttributeType

DirectoryString ::= CHOICE {
teletexString TeletexString (SIZE (1..MAX)),
printableString PrintableString (SIZE (1..MAX)),
universalString UniversalString (SIZE (1..MAX)),
utf8String UTF8String (SIZE (1..MAX)),
bmpString BMPString (SIZE (1..MAX)) }
```

But when implementing it in Rust, the sequence tag for `RDNSequence` disappears. Please, see the code snippet below.

```rust
let rdn_sequence = RdnSequence::from(vec![RelativeDistinguishedName::from(vec![
AttributeTypeAndValue::new_common_name("test"),
])]);

let der_rdn_sequence = picky_asn1_der::to_vec(&rdn_sequence).unwrap();

println!("DER RDN sequence name: {}", hex::encode(der_rdn_sequence));

let der_general_names =
picky_asn1_der::to_vec(&GeneralNames::from(vec![GeneralName::DirectoryName(Name(
rdn_sequence,
))]))
.unwrap();

println!("DER general names: {}", hex::encode(der_general_names));
```

The output is:

```
DER RDN sequence name: 300f310d300b06035504030c0474657374
DER general names: 3011840f310d300b06035504030c0474657374
```

where `300f` disappeared from the serialized value. Did I miss anything?

## Potential Problem 2

Another question, as I'm constructing the SAN, shouldn't the tag for `Name` be `0xa4` instead of `0x84` in the output above?
If I try to visualize the SAN content with tag `0x84` using the openssl CLI, it dumps binary, but with tag `0xa4` it parses the DER content as expected.

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.