Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot decode X500DistinguishedName correctly with T61String. #25195

Closed
mousehuang opened this issue Feb 26, 2018 · 6 comments
Closed

Cannot decode X500DistinguishedName correctly with T61String. #25195

mousehuang opened this issue Feb 26, 2018 · 6 comments

Comments

@mousehuang
Copy link

In an ASP.NET CORE 2.0 project under MAC OS, we have a byte array which is the raw data of the x500 distinguished name, to decode it with the X500DistinguishedName class, the value can be decoded if it is a printable string, but the value CANNOT be decoded if it is a T61String.

It's OK in:

  1. Windows platform (all projects)
  2. MAC, .NET Framework project
    It's NOT OK in:
  3. MAC, ASP.NET CORE 2.0 project

Steps:

  1. Run the following codes in a ASP.NET CORE 2.0 project.
    // CN=GrapeCity inc., OU=Tools Development, O=GrapeCity inc., L=Sendai Izumi-ku, S=Miyagi, C=JP
    // the CN, OU, O value is T61String
    // the L, S, C value is printable string
    var base64 = "MIGGMQswCQYDVQQGEwJKUDEPMA0GA1UECBMGTWl5YWdpMRgwFgYDVQQHEw9TZW5kYWkgSXp1bWkta3UxFzAVBgNVBAoUDkdyYXBlQ2l0eSBpbmMuMRowGAYDVQQLFBFUb29scyBEZXZlbG9wbWVudDEXMBUGA1UEAxQOR3JhcGVDaXR5IGluYy4=";
    var bytes = System.Convert.FromBase64String(base64);
    var x500name = new System.Security.Cryptography.X509Certificates.X500DistinguishedName(bytes);
    var name = x500name.Name;
  2. get's the value of name.
    CN="", OU="", O="", L=Sendai Izumi-ku, S=Miyagi, C=JP
    CN=GrapeCity inc., OU=Tools Development, O=GrapeCity inc., L=Sendai Izumi-ku, S=Miyagi, C=JP
@bartonjs
Copy link
Member

IETF RFC 2459 (from 1999) recommends/recommended that only PrintableString, BMPString, and Utf8String be used (in that order of preference). It specifically calls TeletexString (aka T61String) out as "should not be used for new certificates".

IETF RFC3280 (from 2002) recommended that any certificates after 2003-12-31 just use Utf8String always.

OpenSSL seems to have never supported T61, and the .NET behavior of printing a quoted empty string comes from them.

That said, I'm not opposed to adding T61 decoding to X500DistinguishedName, but I've never been able to find a specification for the T61 encoding (or, if I did find it once, I didn't understand how to read it).

@mousehuang
Copy link
Author

The T61String encoding is as following:
codepage: 20261
name: x-cp20261
description: T.61

@bartonjs
Copy link
Member

bartonjs commented Feb 27, 2018

Okay, it looks like https://en.wikipedia.org/wiki/ITU_T.61 mostly explains the mostly standard parts, except that the Cx values are modifiers. 0xCA => "put a ring on it", so 0xCA 0x79 => LATIN SMALL LETTER Y (0x79) WITH RING ABOVE => \u1e99. Mainly because it meant "draw a ring, but don't seek forward".

T.61 allows for dynamically redefinable character sets (DRCS), which can be used to draw strokes for Japanese. And I have no idea how that's encoded... though I've finally figured out that in these datasheets 12/10 means 0xCA (top nybble: 12, bottom nybble: 10). So maybe one day I'll know what ESC 2/8 2/0 F means, other than it might involve 0x28 and 0x20.

It'll definitely require some edge case tests against Windows (like what happens if the last byte is 0xCA? is that an ASN decode failure? What happens if any of the "not defined" values is sent?)

@filipnavara
Copy link
Member

I just wrote the implementation based on http://std.dkuug.dk/i18n/charmaps/T.61-8BIT (modified to use combining characters) and the Wikipedia page. It matched code page 20261 on .NET Framework on Windows for my test data. However, in practice it was useless. Apparently there are some implementations which erroneously put in ISO 8859-1 encoded data and this seems to be quite widespread practice to the extent that it ended up in the Mono test suite.

@filipnavara
Copy link
Member

Here's the Mono test run on .NET Framework on Windows: https://dotnetfiddle.net/tO78Iw
The word in the output is 'Møbelhandel', where 'ø' is encoded as 0xF8 in the test data. If T.61 encoding was used it would be interpreted as 'ł'. In conclusion, on Windows the T.61 encoding is interpreted as ISO 8859-1 or one of its variations.

@filipnavara
Copy link
Member

For completeness here's the implementation of DerSequenceReader.ReadT61String that I am going to shelve: https://gist.github.com/filipnavara/3d5f36762808417bae420f23e51a3f73

@msftgits msftgits transferred this issue from dotnet/corefx Jan 31, 2020
@msftgits msftgits added this to the 3.0 milestone Jan 31, 2020
@ghost ghost locked as resolved and limited conversation to collaborators Dec 18, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

4 participants