i2d_ASN1_INTEGER zero pad

William Roberts bill.c.roberts at gmail.com
Tue Aug 6 16:18:26 UTC 2019


On Tue, Aug 6, 2019 at 11:16 AM Matt Caswell <matt at openssl.org> wrote:
>
>
>
> On 06/08/2019 17:00, William Roberts wrote:
> > On Tue, Aug 6, 2019 at 10:56 AM Matt Caswell <matt at openssl.org> wrote:
> >>
> >>
> >>
> >> On 06/08/2019 16:34, William Roberts wrote:
> >>> Hi,
> >>> I occasionally get spurious errors in my ECDSA signatures, and it
> >>> appears that when the top byte is over 0x80 of either the R or S
> >>> component, that I get a zero pad. I noticed all this when reading
> >>> through the source, their was some comments (see below). I noticed a
> >>> d2i_ASN1_UINTEGER, but I can't find a coresponding i2d_ version to
> >>> create it. The zero pad seems to be the correct behavior, but it seems
> >>> to be breaking things.
> >>
> >> As you note the zero pad is the correct behaviour.
> >>
> >>
> >>> This is the link to the issue request I got filed for more details:
> >>> https://github.com/tpm2-software/tpm2-pkcs11/issues/277
> >>
> >> This seems to be a problem in tmp2-pkcs11 and not OpenSSL. So its not clear to
> >> me what your question to openssl-users is?
> >
> > The questions is their is a d2i_ASN1_UINTEGER exists for that zero pad
> > issue, is their a i2d version, I couldn't find one.
>
> No, an i2d version does not exists. d2i_ASN1_UINTEGER exists only for
> interoperability with broken software. From the code (crypto/asn1/a_int.c):
>
> /*
>  * This is a version of d2i_ASN1_INTEGER that ignores the sign bit of ASN1
>  * integers: some broken software can encode a positive INTEGER with its MSB
>  * set as negative (it doesn't add a padding zero).
>  */
>
> ASN1_INTEGER *d2i_ASN1_UINTEGER(ASN1_INTEGER **a, const unsigned char **pp,
>                                 long length)
>
> Sine we don't want to *create* knowingly broken DER we don't provide the
> equivalent function.
>

That's what I figured.

>
> >
> > I guess a second question is, is their a better way to build an ECDSA
> > signature from the R and S components, the code
> > for ASNI sequence is something I never figured out, is their an
> > example in ossl somewhere?
>
> If you have the r and s components in raw "binary" format then something like
> this should create an OpenSSL ECDSA_SIG object (totally untested):
>
> ECDSA_SIG *create_ecdsa_sig(unsigned char *r, size_t rlen, unsigned char *s,
> size_t slen)
> {
>     ECDSA_SIG *sig = ECDSA_SIG_new();
>
>     if (sig == NULL)
>         return NULL;
>
>     sig->r = BN_bin2bn(r, rlen, NULL);
>     sig->s = BN_bin2bn(s, slen, NULL);
>
>     if (sig->r == NULL || sig->s == NULL) {
>         ECDSA_SIG_free(sig);
>         return NULL;
>     }
>
>     return sig;
> }
>
> Once you have the ECDSA_SIG structure then encoding it as DER is simply a call
> to i2d_ECDSA_SIG:
>
> https://www.openssl.org/docs/manmaster/man3/i2d_ECDSA_SIG.html
>

That's what I am looking for, thanks!

>
> Matt
>
>
>
>
>
>


More information about the openssl-users mailing list