X509Certificate2/OpenSSL: Subject includes incorrectly-encoded UID attribute
#18,256 opened on Aug 22, 2016
Repository metrics
- Stars
- (17,886 stars)
- PR merge metrics
- (Avg merge 12d 11h) (661 merged PRs in 30d)
Description
If the Subject of a certificate includes a UID (OID 0.9.2342.19200300.100.1.1) attribute, this attribute is encoded incorrectly in the string representation of the Subject DN as userId instead of UID.
dotnet run
Project certificates (.NETCoreApp,Version=v1.0) was previously compiled. Skipping compilation.
C=US, O=Quamotion sprl, OU=PWWS5TKNBM, CN=iPhone Distribution: Quamotion sprl (PWWS5TKNBM), userId=PWWS5TKNBM
Valid representations are those returned by X509Certificate2.Subject on full .NET:
dotnet run
Project certificates (.NETCoreApp,Version=v1.0) was previously compiled. Skipping compilation.
C=US, O=Quamotion sprl, OU=PWWS5TKNBM, CN=iPhone Distribution: Quamotion sprl (PWWS5TKNBM), OID.0.9.2342.19200300.100.1.1=PWWS5TKNBM
and by openssl.exe:
openssl x509 -inform der -in rawdata.bin -subject
subject= /UID=PWWS5TKNBM/CN=iPhone Distribution: Quamotion sprl (PWWS5TKNBM)/OU=PWWS5TKNBM/O=Quamotion sprl/C=US
I believe that RFC4514 String Representation of Distinguished Names describes how the subject of a certificate should be represented, and it states the following:
2.3. Converting AttributeTypeAndValue If the AttributeType is defined to have a short name (descriptor) [RFC4512] and that short name is known to be registered [REGISTRY] [RFC4520] as identifying the AttributeType, that short name, a , is used. Otherwise the AttributeType is encoded as the dotted-decimal encoding, a , of its OBJECT IDENTIFIER. The and are defined in [RFC4512].
and section 3 contains the following:
Implementations MUST recognize AttributeType name strings (descriptors) listed in the following table, but MAY recognize other name strings.
String X.500 AttributeType UID userId (0.9.2342.19200300.100.1.1)
and RFC4519 finally defines the UID attribute:
0.9.2342.19200300.100.1.1 NAME 'uid' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
(userId was used in RFC 1274 which RFC 4519 supersedes).
This program can be used to reproduce the behavior:
using System;
using System.IO;
using System.Security.Cryptography.X509Certificates;
namespace ConsoleApplication
{
public class Program
{
public static void Main(string[] args)
{
byte[] rawData = Convert.FromBase64String("MIIFnzCCBIegAwIBAgIIdo+s3oP49T8wDQYJKoZIhvcNAQEFBQAwgZYxCzAJBgNVBAYTAlVTMRMwEQYDVQQKDApBcHBsZSBJbmMuMSwwKgYDVQQLDCNBcHBsZSBXb3JsZHdpZGUgRGV2ZWxvcGVyIFJlbGF0aW9uczFEMEIGA1UEAww7QXBwbGUgV29ybGR3aWRlIERldmVsb3BlciBSZWxhdGlvbnMgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTYwMjA4MTU0MzQwWhcNMTcwMjA3MTU0MzQwWjCBkjEaMBgGCgmSJomT8ixk" +
"AQEMClBXV1M1VEtOQk0xOTA3BgNVBAMMMGlQaG9uZSBEaXN0cmlidXRpb246IFF1YW1vdGlvbiBzcHJsIChQV1dTNVRLTkJNKTETMBEGA1UECwwKUFdXUzVUS05CTTEXMBUGA1UECgwOUXVhbW90aW9uIHNwcmwxCzAJBgNVBAYTAlVTMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsZRJE85+iTE/tODPi98Xn82C/oCtB97dTHToWoaQRA4kNCNmreedVnTFLGHa5JnKIBtMao+0qPkWxn/o76PuzlRa0r1oXcwwkgAYUE6S8Okzd9PmOGeXhunpuwPNRmyBJ0+oeo0UTg" +
"UY97YUvypvrg6z8ZJpcXGICP6bCaHm8XjPaNPJRH8HCL56HPULtq+9Vt+xMCcCgt4joRFtvzEA8m3vItenUQvVrHI6kyjYcfQh/ANvSXWZyAkDQ1T1AqrljZ1SK/BTH4uIENWu32GglLFJj3UVed3FWO2uy6GYjarhcRkwmYbztJcMc5vLHyBesPPDqpWPmTjk5CvY8qYxTwIDAQABo4IB8TCCAe0wHQYDVR0OBBYEFMXm/a/Rf5kzjcap9LxSO7aYNzVdMAwGA1UdEwEB/wQCMAAwHwYDVR0jBBgwFoAUiCcXCam2GGCL7Ou69kdZxVJUo7cwggEPBgNVHSAEggEGMIIBAjCB/wYJKoZI" +
"hvdjZAUBMIHxMIHDBggrBgEFBQcCAjCBtgyBs1JlbGlhbmNlIG9uIHRoaXMgY2VydGlmaWNhdGUgYnkgYW55IHBhcnR5IGFzc3VtZXMgYWNjZXB0YW5jZSBvZiB0aGUgdGhlbiBhcHBsaWNhYmxlIHN0YW5kYXJkIHRlcm1zIGFuZCBjb25kaXRpb25zIG9mIHVzZSwgY2VydGlmaWNhdGUgcG9saWN5IGFuZCBjZXJ0aWZpY2F0aW9uIHByYWN0aWNlIHN0YXRlbWVudHMuMCkGCCsGAQUFBwIBFh1odHRwOi8vd3d3LmFwcGxlLmNvbS9hcHBsZWNhLzBNBgNVHR8ERjBEMEKgQKA+hj" +
"xodHRwOi8vZGV2ZWxvcGVyLmFwcGxlLmNvbS9jZXJ0aWZpY2F0aW9uYXV0aG9yaXR5L3d3ZHJjYS5jcmwwDgYDVR0PAQH/BAQDAgeAMBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMDMBMGCiqGSIb3Y2QGAQQBAf8EAgUAMA0GCSqGSIb3DQEBBQUAA4IBAQCPqzl6lemCu/TUdag7qnCP81c++y6E29gFy+dWJ1sYx/heytn5TX+Byd3OdEz2/DoSkhbNswLwuZ1SLfjJs1L/1FC5y8D9W5oaMTnbToqIcYY6jLLIkV3ALvBf08ReKdh+875yvE9vsPC0Uzfljh/nrZ/1104POJiTYLHrbIAa" +
"5sEOxrn/lGhH6hGPkmMKHRqMh7v++Z12tat63Ul0mZNCqrShBQi+mH7jV7nik/gZVZW+knxtfcGuDsSZZHLRSGpa6JUe7qCJQ8Y8r5QZqXJGdue11VFGq7/H+L/bQ4X0QxYq9IweD12DoTGWu/UXaL62w868wec808VNOKynDFBS");
File.WriteAllBytes("rawdata.bin", rawData);
var certificate = new X509Certificate2(
rawData: rawData,
password: null,
keyStorageFlags: X509KeyStorageFlags.Exportable);
Console.WriteLine(certificate.Subject);
}
}
}