Closed cpswan closed 1 year ago
Got a possible answer for the "spurious null byte" @cpswan . Take a look at this, and also at this.
Looking at the DER
scheme:
We can see that the BIT STRING
field has "4+271" bytes. But that "4" isn't taking in account one zero byte at the end of the encapsulation that we see before the 271 bytes which contain the integers that we need.
It isn't being taken in account because it doesn't belong to the encapsulation, but to the content of BIT STRING
(that's why the asn1 decoder includes it):
271 + 1 = 272 (multiple of 8) 272/8 = 34 (which is a natural, non-decimal number)
That prepended zero byte means the number of zeroes padded at the end of the bit string in order to be a multiple of 8, including the prepended byte itself (so in this case the bit string has not been padded with zeroes (unused values) at the end).
An example of a public key with a BIT STRING with some zeroes padding would be useful. The thing is that I have tried with 3 different atSigns and I always get no padding. Maybe some keys created by some generation systems or with formats don't necessarily have to deal with paddings because they are intended to have a certain length (if that's true, it makes our task easier).
(Images are from ASN.1 JavaScript decoder, although I used a different key on them)
Thanks @realvarx
I think in that case we should be handling stripping the zero in the uasn1 library.
Public keys are always going to be 2048 bits (==256 bytes) so I don't expect zero padding will ever come into play, which can leave us all scratching out heads why they chose to encode as a bit string rather than an octet string?
I'm going to make this a draft while I refactor.
which can leave us all scratching out heads why they chose to encode as a bit string rather than an octet string?
I also found this comment in one of the links that I shared:
Public keys are always BIT STRING in X.509; this is an historical remnant from older times, kept for the sake of backward compatibility. – Thomas Pornin
I was able to get the n and e parameters from a base64 encoded public rsa key here: https://github.com/atsign-foundation/at_pico_w/blob/e7fbbd159a4a68fb0e68bb41617da0ff39ddf738/lib/pem_service.py#L170
Thanks @JeremyTubongbanua looks like we arrived at much the same approach.
This is ready for review again.
Ongoing work for https://github.com/atsign-foundation/micropython/issues/2 requires the ability to extract integers from another atSign's public key.
- What I did
Tidied up the work done by @duanqi211 to add Bit String support to
uasn1.py
Added a method to extract public key integers.
- How I did it
Getting the parameters from a public key is very similar to doing the same with a private key, except that they're encoded into a Bit String rather than an Octet String.
One trip hazard encountered is the spurious null byte at the beginning of the sequence extracted from the bit string, which throws off the ASN.1 parser if it's not trimmed out. @realvarx @TylerTrott @JeremyTubongbanua @XavierChanth any thoughts on how/why this is happening would be appreciated?
- How to verify it
Running
micropython
locally on WSL2:Example output:
- Description for the changelog
feat: Add ability to extract RSA public key parameters