asn1parse genstr question

classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|

asn1parse genstr question

Dmitry Belyavsky-3
Hello,

I try to create an extension containing an utf8 string. 

When I use a command 

openssl asn1parse -genstr "UTF8String:ф" -out content

I get a 6-byte file. If I understand correctly, it starts with a 2-byte header indicating the content length and then contains an encoded letter 'ф' I want. But the encoding of it is not UTF8, as the utf8 encoding of a cyrillic letter is 2 bytes long. 

Am I wrong? If the behavior I see is desired one, how can I convert the result of the encoding to UTF8 using openssl internal API?

--
SY, Dmitry Belyavsky
Reply | Threaded
Open this post in threaded view
|

Re: asn1parse genstr question

Viktor Dukhovni
On Sun, Apr 21, 2019 at 06:58:53PM +0300, Dmitry Belyavsky wrote:

> When I use a command
>
> openssl asn1parse -genstr "UTF8String:ф" -out content
>
> I get a 6-byte file. If I understand correctly, it starts with a 2-byte
> header indicating the content length and then contains an encoded letter
> 'ф' I want. But the encoding of it is not UTF8, as the utf8 encoding of a
> cyrillic letter is 2 bytes long.
>
> Am I wrong? If the behavior I see is desired one, how can I convert the
> result of the encoding to UTF8 using openssl internal API?

By default the input string is assumed to contain single-byte octets,
which are individually encoded as UTF-8.  This is rarely what you
want if your input is not ASCII.  For actual UTF-8 input, you can
use:

    $ openssl asn1parse -out content -genstr 'FORMAT:UTF8,UTF8String:Он врет! Он не знает, КАК НАДО!' # [1]
        0:d=0  hl=2 l=  53 prim: UTF8STRING        :Он врет! Он не знает, КАК НАДО!

The "genstr" format is described in, for example:

    https://www.openssl.org/docs/man1.0.2/man3/ASN1_generate_nconf.html

--
        Viktor.

[1]. http://www.mnemosyne.ru/homo/galich-6.html
Reply | Threaded
Open this post in threaded view
|

Re: asn1parse genstr question

Wim Lewis-3
In reply to this post by Dmitry Belyavsky-3

On Apr 21, 2019, at 8:58 AM, Dmitry Belyavsky <[hidden email]> wrote:
> openssl asn1parse -genstr "UTF8String:ф" -out content
>
> I get a 6-byte file. If I understand correctly, it starts with a 2-byte header indicating the content length and then contains an encoded letter 'ф' I want. But the encoding of it is not UTF8, as the utf8 encoding of a cyrillic letter is 2 bytes long.

When I do that I get the 6-byte file "0c 04 c3 91 c2 84", which looks like 'ф' is getting UTF-8 encoded twice (more exactly, asn1parse is receiving a utf8-encoded value but interpreting it as Latin-1, and then encoding that as UTF8, which produces nonsense).

The format of the "genstr" option is described in the ASN1_generate_nconf man page, which says you can prepend the format modifier "UTF8" to the specifier in order to tell genstr to interpret the value correctly. So this produces the output you want:

   FORMAT:UTF8,UTF8String:ф

(Oddly, you can't use HEX with UTF8String. It seems like it would be convenient to be able to do so.)


Reply | Threaded
Open this post in threaded view
|

Re: asn1parse genstr question

Dmitry Belyavsky-3
In reply to this post by Viktor Dukhovni
Dear Victor, 

On Mon, Apr 22, 2019 at 9:23 PM Viktor Dukhovni <[hidden email]> wrote:
On Sun, Apr 21, 2019 at 06:58:53PM +0300, Dmitry Belyavsky wrote:

> When I use a command
>
> openssl asn1parse -genstr "UTF8String:ф" -out content
>
> I get a 6-byte file. If I understand correctly, it starts with a 2-byte
> header indicating the content length and then contains an encoded letter
> 'ф' I want. But the encoding of it is not UTF8, as the utf8 encoding of a
> cyrillic letter is 2 bytes long.
>
> Am I wrong? If the behavior I see is desired one, how can I convert the
> result of the encoding to UTF8 using openssl internal API?

By default the input string is assumed to contain single-byte octets,
which are individually encoded as UTF-8.  This is rarely what you
want if your input is not ASCII.  For actual UTF-8 input, you can
use:

    $ openssl asn1parse -out content -genstr 'FORMAT:UTF8,UTF8String:Он врет! Он не знает, КАК НАДО!' # [1]
        0:d=0  hl=2 l=  53 prim: UTF8STRING        :Он врет! Он не знает, КАК НАДО!

The "genstr" format is described in, for example:

    https://www.openssl.org/docs/man1.0.2/man3/ASN1_generate_nconf.html

Thank you very much for your answer and especially for a brilliant example :)

I'm trying to implement RFC 8398 and I try to create a valid certificate with EAI email in otherName. 

I expected that a line in the config file 

subjectAltName=otherName:1.3.6.1.5.5.7.8.9;FORMAT:UTF8,UTF8:医生@大学.example.com

will do the trick.
But I get an error
140642093051968:error:0D0B20C2:asn1 encoding routines:ASN1_generate_v3:unknown tag:../crypto/asn1/asn1_gen.c:94:
140642093051968:error:220A4093:X509 V3 routines:a2i_GENERAL_NAME:othername error:../crypto/x509v3/v3_alt.c:456:
140642093051968:error:22098080:X509 V3 routines:X509V3_EXT_nconf:error in extension:../crypto/x509v3/v3_conf.c:47:name=subjectAltName, value=otherName:1.3.6.1.5.5.7.8.9;FORMAT:UTF8,UTF8:医生@大学.example.com

If I specify the otherName like
subjectAltName=otherName:1.3.6.1.5.5.7.8.9;UTF8:医生@大学.example.com

I do not get an error, but the encoding seems to be not UTF8, but ASCII.
Can this behavior be fixed?



--
        Viktor.

[1]. http://www.mnemosyne.ru/homo/galich-6.html


--
SY, Dmitry Belyavsky
Reply | Threaded
Open this post in threaded view
|

Re: asn1parse genstr question

Dmitry Belyavsky-3
Hello,

On Tue, Apr 23, 2019 at 12:21 AM Dmitry Belyavsky <[hidden email]> wrote:
Dear Victor, 

On Mon, Apr 22, 2019 at 9:23 PM Viktor Dukhovni <[hidden email]> wrote:
On Sun, Apr 21, 2019 at 06:58:53PM +0300, Dmitry Belyavsky wrote:

> When I use a command
>
> openssl asn1parse -genstr "UTF8String:ф" -out content
>
> I get a 6-byte file. If I understand correctly, it starts with a 2-byte
> header indicating the content length and then contains an encoded letter
> 'ф' I want. But the encoding of it is not UTF8, as the utf8 encoding of a
> cyrillic letter is 2 bytes long.
>
> Am I wrong? If the behavior I see is desired one, how can I convert the
> result of the encoding to UTF8 using openssl internal API?

By default the input string is assumed to contain single-byte octets,
which are individually encoded as UTF-8.  This is rarely what you
want if your input is not ASCII.  For actual UTF-8 input, you can
use:

    $ openssl asn1parse -out content -genstr 'FORMAT:UTF8,UTF8String:Он врет! Он не знает, КАК НАДО!' # [1]
        0:d=0  hl=2 l=  53 prim: UTF8STRING        :Он врет! Он не знает, КАК НАДО!

The "genstr" format is described in, for example:

    https://www.openssl.org/docs/man1.0.2/man3/ASN1_generate_nconf.html

Thank you very much for your answer and especially for a brilliant example :)

I'm trying to implement RFC 8398 and I try to create a valid certificate with EAI email in otherName. 

I expected that a line in the config file 

subjectAltName=otherName:1.3.6.1.5.5.7.8.9;FORMAT:UTF8,UTF8:医生@大学.example.com

will do the trick.
But I get an error
140642093051968:error:0D0B20C2:asn1 encoding routines:ASN1_generate_v3:unknown tag:../crypto/asn1/asn1_gen.c:94:
140642093051968:error:220A4093:X509 V3 routines:a2i_GENERAL_NAME:othername error:../crypto/x509v3/v3_alt.c:456:
140642093051968:error:22098080:X509 V3 routines:X509V3_EXT_nconf:error in extension:../crypto/x509v3/v3_conf.c:47:name=subjectAltName, value=otherName:1.3.6.1.5.5.7.8.9;FORMAT:UTF8,UTF8:医生@大学.example.com

If I specify the otherName like
subjectAltName=otherName:1.3.6.1.5.5.7.8.9;UTF8:医生@大学.example.com

I do not get an error, but the encoding seems to be not UTF8, but ASCII.
Can this behavior be fixed?

I've got the clue.

The config string is passed to the X509V3_parse_list() function, which treats comma as a separator, so the rest of the line is cut, and it causes an error.
I've done a quick-and-dirty patch for my purposes that enforces FORMAT:UTF8 for SMTPUTF8 and succeeded. 

 



--
        Viktor.

[1]. http://www.mnemosyne.ru/homo/galich-6.html


--
SY, Dmitry Belyavsky


--
SY, Dmitry Belyavsky
Reply | Threaded
Open this post in threaded view
|

Re: asn1parse genstr question

Viktor Dukhovni
In reply to this post by Dmitry Belyavsky-3
On Tue, Apr 23, 2019 at 12:21:21AM +0300, Dmitry Belyavsky wrote:

> > For actual UTF-8 input, you can use:
> >
> >     $ openssl asn1parse -out content -genstr 'FORMAT:UTF8,UTF8String:Он врет! Он не знает, КАК НАДО!' # [1]
> >         0:d=0  hl=2 l=  53 prim: UTF8STRING        :Он врет! Он не знает, КАК НАДО!
> >
> > The "genstr" format is described in, for example:
> >
> >     https://www.openssl.org/docs/man1.0.2/man3/ASN1_generate_nconf.html
>
> Thank you very much for your answer and especially for a brilliant example :)
>
> I'm trying to implement RFC 8398 and I try to create a valid certificate
> with EAI email in otherName.
>
> I expected that a line in the config file
>
> subjectAltName=otherName:1.3.6.1.5.5.7.8.9;FORMAT:UTF8,UTF8:医生@

The below worked for me:

        subjectName = @alts
        [alts]
        otherName = 1.3.6.1.5.5.7.8.9;FORMAT:UTF8,UTF8String:виктор@например.рф

    $ openssl asn1parse -in eecert.pem
        0:d=0  hl=4 l= 858 cons: SEQUENCE          
        4:d=1  hl=4 l= 578 cons: SEQUENCE          
        8:d=2  hl=2 l=   3 cons: cont [ 0 ]        
       10:d=3  hl=2 l=   1 prim: INTEGER           :02
       13:d=2  hl=2 l=   1 prim: INTEGER           :02
       16:d=2  hl=2 l=  13 cons: SEQUENCE          
       18:d=3  hl=2 l=   9 prim: OBJECT            :sha256WithRSAEncryption
       29:d=3  hl=2 l=   0 prim: NULL              
       31:d=2  hl=2 l=  20 cons: SEQUENCE          
       33:d=3  hl=2 l=  18 cons: SET              
       35:d=4  hl=2 l=  16 cons: SEQUENCE          
       37:d=5  hl=2 l=   3 prim: OBJECT            :commonName
       42:d=5  hl=2 l=   9 prim: UTF8STRING        :Issuer CA
       53:d=2  hl=2 l=  32 cons: SEQUENCE          
       55:d=3  hl=2 l=  13 prim: UTCTIME           :190422230331Z
       70:d=3  hl=2 l=  15 prim: GENERALIZEDTIME   :21190423230331Z
       87:d=2  hl=2 l=  40 cons: SEQUENCE          
       89:d=3  hl=2 l=  38 cons: SET              
       91:d=4  hl=2 l=  36 cons: SEQUENCE          
       93:d=5  hl=2 l=   3 prim: OBJECT            :commonName
       98:d=5  hl=2 l=  29 prim: UTF8STRING        :Виктор Духовный
      129:d=2  hl=4 l= 290 cons: SEQUENCE          
      133:d=3  hl=2 l=  13 cons: SEQUENCE          
      135:d=4  hl=2 l=   9 prim: OBJECT            :rsaEncryption
      146:d=4  hl=2 l=   0 prim: NULL              
      148:d=3  hl=4 l= 271 prim: BIT STRING        
      423:d=2  hl=3 l= 160 cons: cont [ 3 ]        
      426:d=3  hl=3 l= 157 cons: SEQUENCE          
      429:d=4  hl=2 l=  29 cons: SEQUENCE          
      431:d=5  hl=2 l=   3 prim: OBJECT            :X509v3 Subject Key Identifier
      436:d=5  hl=2 l=  22 prim: OCTET STRING      [HEX DUMP]:041487FF5D9C758FDB282922102D0696834BD296A39D
      460:d=4  hl=2 l=  31 cons: SEQUENCE          
      462:d=5  hl=2 l=   3 prim: OBJECT            :X509v3 Authority Key Identifier
      467:d=5  hl=2 l=  24 prim: OCTET STRING      [HEX DUMP]:30168014505CD4D6F75052F79EC51DA943AC099AD0079341
      493:d=4  hl=2 l=   9 cons: SEQUENCE          
      495:d=5  hl=2 l=   3 prim: OBJECT            :X509v3 Basic Constraints
      500:d=5  hl=2 l=   2 prim: OCTET STRING      [HEX DUMP]:3000
      504:d=4  hl=2 l=  19 cons: SEQUENCE          
      506:d=5  hl=2 l=   3 prim: OBJECT            :X509v3 Extended Key Usage
      511:d=5  hl=2 l=  12 prim: OCTET STRING      [HEX DUMP]:300A06082B06010505070301
      525:d=4  hl=2 l=  59 cons: SEQUENCE          
      527:d=5  hl=2 l=   3 prim: OBJECT            :X509v3 Subject Alternative Name
      532:d=5  hl=2 l=  52 prim: OCTET STRING      [HEX DUMP]:3032A03006082B06010505070809A0240C22D0B2D0B8D0BAD182D0BED18040D0BDD0B0D0BFD180D0B8D0BCD0B5D1802ED180D184
      586:d=1  hl=2 l=  13 cons: SEQUENCE          
      588:d=2  hl=2 l=   9 prim: OBJECT            :sha256WithRSAEncryption
      599:d=2  hl=2 l=   0 prim: NULL              
      601:d=1  hl=4 l= 257 prim: BIT STRING        

    $ openssl asn1parse -in eecert.pem -strparse 532
        0:d=0  hl=2 l=  50 cons: SEQUENCE
        2:d=1  hl=2 l=  48 cons: cont [ 0 ]
        4:d=2  hl=2 l=   8 prim: OBJECT            :1.3.6.1.5.5.7.8.9
       14:d=2  hl=2 l=  36 cons: cont [ 0 ]
       16:d=3  hl=2 l=  34 prim: UTF8STRING        :виктор@например.рф

--
        Viktor.
Reply | Threaded
Open this post in threaded view
|

Re: asn1parse genstr question

Dmitry Belyavsky-3
Dear Victor, 

The below worked for me:

        subjectName = @alts
        [alts]
        otherName = 1.3.6.1.5.5.7.8.9;FORMAT:UTF8,UTF8String:виктор@например.рф

Thank you! It works, though it should be subjectAltName instead of  subjectName

--
SY, Dmitry Belyavsky
Reply | Threaded
Open this post in threaded view
|

Re: asn1parse genstr question

Viktor Dukhovni
On Wed, Apr 24, 2019 at 10:09:52PM +0300, Dmitry Belyavsky wrote:

> The below worked for me:
> >
> >         subjectName = @alts
> >         [alts]
> >         otherName = 1.3.6.1.5.5.7.8.9;FORMAT:UTF8,UTF8String:виктор@например.рф
>
> Thank you!

You're very welcome.

> It works, though it should be subjectAltName instead of subjectName

Yes, of course, sorry about that... Should have pasted that too
from my script rather than retyping.

--
        Viktor.