4

In RFC 5280 is written that for example the X520OrganizationName can use one of the following encodings:

X520OrganizationName ::= CHOICE {
      teletexString     TeletexString
                          (SIZE (1..ub-organization-name)),
      printableString   PrintableString
                          (SIZE (1..ub-organization-name)),
      universalString   UniversalString
                          (SIZE (1..ub-organization-name)),
      utf8String        UTF8String
                          (SIZE (1..ub-organization-name)),
      bmpString         BMPString
                          (SIZE (1..ub-organization-name))  }

How can i lookup the used encoding in a given X509 certificate? Is there any openssl command or similar software?

FireEmerald
  • 183
  • 5

2 Answers2

4

Use ASN.1 DER decoder software:

  • OpenSSL: openssl asn1parse -i -in Foo.crt

    (asn1parse expects Base64 "PEM" format, as do most other openssl subcommands, but you can use -inform DER to give it binary-format certificates.)

  • P.Gutmann's dumpasn1: dumpasn1 Foo.der

    (dumpasn1 requires the binary (non-Base64) format. Convert the certificate to binary DER using openssl x509 -in Foo.crt -out Foo.der -outform DER or even using base64 -d.)

  • asn1.js (online): https://lapo.it/asn1js/

    (another similar version at https://pkitools.net/pages/ca/asn1.html)

Subject DN is one of the first fields in the certificate (before after the two timestamps – the Issuer DN is after before timestamps); it's represented as a 'Sequence' with each RDN being a 'Set' (typically having one element, but the format allows multiple, e.g. CN=this+UID=that,OU=etc,O=etc).

For example:

$ openssl x509 -outform DER -in Telia_Root_CA_v2.pem -out /tmp/telia.crt
$ dumpasn1 /tmp/telia.crt
  0 1396: SEQUENCE {
  4  860:   SEQUENCE {
  8    3:     [0] {                         ← Version (X.509 v3)
 10    1:       INTEGER 2
        :       }                           ↙ Serial number
 13   15:     INTEGER 01 67 5F 27 D6 FE 7A E3 E4 AC BE 09 5B 05 9E
 30   13:     SEQUENCE {                    ← Algorithm
 32    9:       OBJECT IDENTIFIER sha256WithRSAEncryption (1 2 840 113549 1 1 11)
 43    0:       NULL
        :       }
 45   68:     SEQUENCE {                    Subject Issuer DN starts here
 47   11:       SET {
 49    9:         SEQUENCE {
 51    3:           OBJECT IDENTIFIER countryName (2 5 4 6)
 56    2:           PrintableString 'FI'
        :           }
        :         }
 60   26:       SET {                       ← the 'O=...' RDN
 62   24:         SEQUENCE {                ← the 'O=...' element of the RDN
 64    3:           OBJECT IDENTIFIER organizationName (2 5 4 0)
 69   17:           UTF8String 'Telia Finland Oyj'
        :           }
        :         }
 88   25:       SET {
 90   23:         SEQUENCE {
 92    3:           OBJECT IDENTIFIER commonName (2 5 4 3)
 97   16:           UTF8String 'Telia Root CA v2'
        :           }
        :         }
        :       }
115   30:     SEQUENCE {
117   13:       UTCTime 29/11/2018 11:55:54 GMT
grawity
  • 501,077
1

More specific and easier to read method with OpenSSL:

openssl x509 {<file | -in file} -noout -subject -nameopt oneline,show_type
# change -subject to -issuer (or use both!) if applicable 
# if DN is long or complex enough that single-line is hard to read 
# change oneline to multiline

for the cert currently used by www.example.com:

$ openssl x509 <temp -noout -subject # default does not show types subject=C = US, ST = California, L = Los Angeles, O = Internet\C2\A0Corporation\C2\A0for\C2\A0Assigned\C2\A0Names\C2\A0and\C2\A0Numbers, CN = www.example.org

$ openssl x509 <temp -noout -subject -nameopt oneline,show_type subject=C = PRINTABLESTRING:US, ST = PRINTABLESTRING:California, L = PRINTABLESTRING:Los Angeles, O = UTF8STRING:Internet\C2\A0Corporation\C2\A0for\C2\A0Assigned\C2\A0Names\C2\A0and\C2\A0Numbers, CN = PRINTABLESTRING:www.example.org

$ openssl x509 <temp -noout -subject -nameopt multiline,show_type subject= countryName = PRINTABLESTRING:US stateOrProvinceName = PRINTABLESTRING:California localityName = PRINTABLESTRING:Los Angeles organizationName = UTF8STRING:Internet\A0Corporation\A0for\A0Assigned\A0Names\A0and\A0Numbers commonName = PRINTABLESTRING:www.example.org $

In older versions of OpenSSL the default format is PEM and you must specify -inform DER (or abbreviated -inform d) if it applies. However in 3.0.0 up, which are now the only versions supported upstream, most commands including x509 accept input as either PEM or DER automatically. (asn1parse doesn't, because unlike other commands it doesn't look at or even require the PEM label lines; its 'PEM' format actually accepts any base64, unless you specify the new option -strictpem. Sometimes this is useful, sometimes not.)