Re: Why does openssl accept multiple keys after BEGIN PUBLIC KEY?

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, Oct 10, 2023 at 12:07:51PM +0200, David Bürgin wrote:

> When you inspect the following key with ‘openssl pkey’, it works fine:
> 
> -----BEGIN PUBLIC KEY-----
> MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC9oaro18Mt4FITtXvhy/v2N0d0
> aQJ285MgstG5QSgvFnXA+7Bww20hnLQZD4vOZbeIhdu4g5s8S6LWczqswDjVyD97
> 9j+RcZM+JcnHPEIvkn7YCKYnM3mvSQKmeRtm9kDVL0waKf+iZ5ZDYiLcfXCSIDnT
> 2SMxp3D9UNEfEZDMoQIDAQABMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDK
> A5hv8tKZBw3cx+j0NMrbsOY5QfoUtxGeXjmGI89q63iFxBdSgrJW5wpthZfHcVHl
> roPW885ToeSrEdyUIVCokR7L8PP7Up0PGXUDPIFCQB7+jVV8ezLyxHSLGT81u7Be
> el5ybAgsal/GmhpeQXcEpnYpiqVcHL3XTlY8+34EQQIDAQAB
> -----END PUBLIC KEY-----
>
> However, there is something odd about it, openssl seems to be
> interested only in the first half of the key data:
>
> Well, that key actually contains two, concatenated
> SubjectPublicKeyInfos! I noticed this when I first used a different
> library, and processing failed.

The data between the PEM "BEGIN" and "END" markers is supposed to be a
block of base64 text that contains an ASN.1 DER encoding of the object
in question.  In this case we see, that indeed there are two
back-to-back DER SPKI structures:

    $ openssl asn1parse <<EOF
    -----BEGIN PUBLIC KEY-----
    MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC9oaro18Mt4FITtXvhy/v2N0d0
    aQJ285MgstG5QSgvFnXA+7Bww20hnLQZD4vOZbeIhdu4g5s8S6LWczqswDjVyD97
    9j+RcZM+JcnHPEIvkn7YCKYnM3mvSQKmeRtm9kDVL0waKf+iZ5ZDYiLcfXCSIDnT
    2SMxp3D9UNEfEZDMoQIDAQABMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDK
    A5hv8tKZBw3cx+j0NMrbsOY5QfoUtxGeXjmGI89q63iFxBdSgrJW5wpthZfHcVHl
    roPW885ToeSrEdyUIVCokR7L8PP7Up0PGXUDPIFCQB7+jVV8ezLyxHSLGT81u7Be
    el5ybAgsal/GmhpeQXcEpnYpiqVcHL3XTlY8+34EQQIDAQAB
    -----END PUBLIC KEY-----
    EOF
        0:d=0  hl=3 l= 159 cons: SEQUENCE          
        3:d=1  hl=2 l=  13 cons: SEQUENCE          
        5:d=2  hl=2 l=   9 prim: OBJECT            :rsaEncryption
       16:d=2  hl=2 l=   0 prim: NULL              
       18:d=1  hl=3 l= 141 prim: BIT STRING        
      162:d=0  hl=3 l= 159 cons: SEQUENCE          
      165:d=1  hl=2 l=  13 cons: SEQUENCE          
      167:d=2  hl=2 l=   9 prim: OBJECT            :rsaEncryption
      178:d=2  hl=2 l=   0 prim: NULL              
      180:d=1  hl=3 l= 141 prim: BIT STRING        

Because ASN.1 objects have an explicit length, it is possible to process
just the first 162 bytes (3 byte header + 159 data), without checking
that this represents the entire content of the base64-encoded input.

> • Is openssl right in accepting this key? Why does it use only the
>   first one?

OpenSSL "pkey" application (and perhaps more generally, the underlying
PEM_read_bio_PUBKEY(3)) did not check that the entire input buffer was
consumed, so only the first structure is processed.  The only plausible
outcomes are to extract the first structure and ignore excess data, or
to the reject the input due to the excess data.

Note that the PEM layer relies on the "d2i" functions to read the
DER-encoded data, and the "d2i" functions support reading a portion of
an input buffer, filling in the decoded structure and returning a
pointer to the tail of the input stream, this supports reading of arrays
of DER-encoded objects, or just a single DER encoded object in a larger
"packet".

So what happens here, is that the PEM layer does not compare the "d2i"
end pointer with the end of the input buffer and the "trailing data"
is simply ignored.  The check that's "missing" would be similar to:

    https://github.com/vdukhovni/postfix/blob/master/postfix/src/tls/tls_certkey.c#L208-L214

> • Is the other library wrong in rejecting this key?

I don't think it is wrong to be strict.

> • Do relevant RFCs say something about such a ‘concatenated’ format?

I haven't seen anything that clearly prohibits ignoring excess input,
but there is certainly no expectation that it would be used.  It can
either be rejected or ignored.

I don't see any explicit rules about this in:

    https://datatracker.ietf.org/doc/html/rfc7468

Perhaps I did not read it closely enough, or the relevant normative
rules are in some other document.

-- 
    Viktor.




[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Index of Archives]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux]     [Linux OMAP]     [Linux MIPS]     [ECOS]     [Asterisk Internet PBX]     [Linux API]

  Powered by Linux