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

Updater signature validation - format incompatible w/RFC8017 #6250

Merged
merged 4 commits into from
Jul 4, 2019

Conversation

qistoph
Copy link
Contributor

@qistoph qistoph commented Jul 3, 2019

The signed updates code (#5213) does not correctly implement PKCS#1. This makes it harder to verify the updates in other applications, like a python script.

According to the RFC 8017 section 9.2 step 2:

Encode the algorithm ID for the hash function and the hash value into an ASN.1 value of type DigestInfo with the DER.

Currently the signed data looks like this:

00000000  00 01 ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
00000010  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
00000020  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
00000030  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
00000040  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
00000050  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
00000060  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
00000070  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
00000080  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
00000090  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
000000a0  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
000000b0  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
000000c0  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
000000d0  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff 00  |................|
000000e0  3c 10 ae 9a e8 d3 e6 42  bf c2 a9 c5 71 3f d3 2d  |<......B....q?.-|
000000f0  a5 d3 1d 12 b5 bb dd 86  1b 0a 30 60 4a 2e a2 bd  |..........0`J...|

RFC 8017 step 5 says the encoded message is a concatenation of:
EM = 0x00 || 0x01 || PS || 0x00 || T

T should be the DER of DigestInfo. In this case the DigestInfo should look like:

    0:d=0  hl=2 l=  49 cons: SEQUENCE          
    2:d=1  hl=2 l=  13 cons:  SEQUENCE          
    4:d=2  hl=2 l=   9 prim:   OBJECT            :sha256
   15:d=2  hl=2 l=   0 prim:   NULL              
   17:d=1  hl=2 l=  32 prim:  OCTET STRING      [HEX DUMP]:3C10AE9AE8D3E642BFC2A9C5713FD32DA5D31D12B5BBDD861B0A30604A2EA2BD

That would encode to EM:

00000000  00 01 ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
00000010  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
00000020  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
00000030  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
00000040  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
00000050  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
00000060  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
00000070  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
00000080  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
00000090  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
000000a0  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
000000b0  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
000000c0  ff ff ff ff ff ff ff ff  ff ff ff ff 00 30 31 30  |.............010|
000000d0  0d 06 09 60 86 48 01 65  03 04 02 01 05 00 04 20  |...`.H.e....... |
000000e0  3c 10 ae 9a e8 d3 e6 42  bf c2 a9 c5 71 3f d3 2d  |<......B....q?.-|
000000f0  a5 d3 1d 12 b5 bb dd 86  1b 0a 30 60 4a 2e a2 bd  |..........0`J...|

The currently used version of BearSSL supports proper PKCS#1 signatures, with an OID.

The signing.py is executing:
openssl rsautl -sign -inkey <privatekey> on a pre-computed hash.
To create a signature with a valid PKCS#1 padded signature it should use openssl dgst -sha256 -sign <privatekey> on the raw binary.

This PR includes, changes to:

  • the core to verify signatures with DigestInfo
  • the signing.py to create signatures with DigestInfo
  • the docs to explain usage of legacy and new signature

A few more details are in the issue that I initially created #6201.

@earlephilhower earlephilhower self-assigned this Jul 3, 2019
@earlephilhower
Copy link
Collaborator

A quick check looks great. Let me look at it in more detail later today. Thanks!

Copy link
Collaborator

@earlephilhower earlephilhower left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! I will note in the merge commit that this could be a breaking change so it stands out when we do the release notes.

@d-a-v d-a-v merged commit 6272b49 into esp8266:master Jul 4, 2019
@qistoph qistoph deleted the pkcs1_fix branch July 11, 2019 15:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants