openssl / openssl

TLS/SSL and crypto library

Home Page:https://www.openssl.org

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

PEM_write_bio_PUBKEY causes segmentation fault when EVP_PKEY has private key and no public key

dongbeiouba opened this issue · comments

commented

EVP_PKEY may be constructed from raw data, the public key(EC point) and private key(BIGNUM).

But if only private key is set, the pubic key is not set, then call PEM_write_bio_PUBKEY(bio, pkey) will cause segmentation fault.

PEM_write_bio_PrivateKey() doesn't cause segmentation fault.

backtrace:

Program received signal SIGSEGV, Segmentation fault.
0x00005555555d57bb in ec_point_is_compat (point=0x0, group=0x555555a9d610) at crypto/ec/ec_local.h:330
330	    return group->meth == point->meth
(gdb) bt
#0  0x00005555555d57bb in ec_point_is_compat (point=0x0, group=0x555555a9d610) at crypto/ec/ec_local.h:330
#1  0x00005555555d5a76 in EC_POINT_point2oct (group=0x555555a9d610, point=0x0, form=POINT_CONVERSION_UNCOMPRESSED, buf=0x0, len=0, ctx=0x0) at crypto/ec/ec_oct.c:82
#2  0x000055555575350c in i2o_ECPublicKey (a=0x555555a8c5b0, out=0x0) at crypto/ec/ec_asn1.c:1164
#3  0x000055555574f0c8 in eckey_pub_encode (pk=0x555555a9e410, pkey=0x555555a9be90) at crypto/ec/ec_ameth.c:80
#4  0x0000555555648b3c in i2d_PUBKEY (a=0x555555a9be90, pp=0x0) at crypto/x509/x_pubkey.c:564
#5  0x000055555561140b in PEM_ASN1_write_bio (i2d=0x555555648aa1 <i2d_PUBKEY>, name=0x55555593d885 "PUBLIC KEY", bp=0x555555a8b2a0, x=0x555555a9be90, enc=0x0, kstr=0x0, klen=0,
    callback=0x0, u=0x0) at crypto/pem/pem_lib.c:347
#6  0x00005555556103b0 in PEM_write_bio_PUBKEY (out=0x555555a8b2a0, x=0x555555a9be90) at crypto/pem/pem_all.c:226
#7  0x00005555555be2f9 in main () at a.c:50

demo:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <openssl/evp.h>
#include <openssl/pem.h>
#include <openssl/ec.h>
#include <openssl/bio.h>

int main()
{
    int ok = 0;
    BIO *bio = NULL;
    EC_KEY *eckey = NULL;
    EC_GROUP *group = NULL;
    EVP_PKEY *pkey = NULL;
    BIGNUM *bn = NULL;
    const char *priv = "2f:c7:ff:d6:64:c9:81:80:12:38:af:28:80:fd:e7:c3:41:82:1d:1d:00:35:67:c4:3b:63:16:03:d5:03:5c:ae";

    bio = BIO_new_fp(stderr, BIO_NOCLOSE);
    if (bio == NULL)
        goto end;

    eckey = EC_KEY_new();
    if (eckey == NULL)
        goto end;

    group = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1);
    if (group == NULL)
        goto end;

    if (!EC_KEY_set_group(eckey, group))
        goto end;

    if (!BN_hex2bn(&bn, priv))
        goto end;

    if (!EC_KEY_set_private_key(eckey, bn))
        goto end;

    pkey = EVP_PKEY_new();
    if (pkey == NULL)
        goto end;

    if (!EVP_PKEY_assign_EC_KEY(pkey, eckey))
        goto end;

//    if (!PEM_write_bio_PrivateKey(bio, pkey, NULL, NULL, 0, NULL, NULL))
//        goto end;

    if (!PEM_write_bio_PUBKEY(bio, pkey))
        goto end;

    ok = 1;
end:
    if (ok)
        return 0;
    else
        return 1;
}

I'm not sure this is truly a bug. If you create an EVP_key without some data, and then try to write that data....