[openssl-users] 1.0.0.o: SIGSEGV in X509_set_pubkey(), when creating a self-signed DSA certificate

K V v at tenable.com
Mon Mar 30 03:05:04 UTC 2015

LOG_OpenSSL() is my error-reporting macro/function.  Having set things up, as

    DH *dhParameters_512, *dhParameters_1024, *dhParameters_2048,
    static constexpr long certValidityDuration_years{60};
    static constexpr unsigned nBytesToSeedPRNG{4};
    if (RAND_load_file("/dev/random", nBytesToSeedPRNG) < (int)
        LOG_OpenSSL("Failed to seed PRNG");
    dhParameters_512   = get_dh512();
    dhParameters_1024  = get_dh1024();
    dhParameters_2048  = get_dh2048();
    dhParameters_4096  = get_dh4096();

, and generated an EVP_PKEY, as

    static constexpr u_short KEY_LEN{2048};

    EVP_PKEY_t *pkey_m;
    if (unlikely(! (pkey_m = EVP_PKEY_new())))
        LOG_OpenSSL("Cannot allocate an EVP_PKEY");

    DSA *keypair; // Also contains other stuff
    if (unlikely(! (keypair = DSA_new())))
        LOG_OpenSSL("Cannot allocate a DSA");

    if (0 == DSA_generate_parameters_ex(keypair, KEY_LEN,
                                        NULL, 0, NULL, NULL, NULL))
        LOG_OpenSSL("Cannot parameterize a %db DSA key", KEY_LEN);

    if (0 == DSA_generate_key(keypair))
        LOG_OpenSSL("Cannot generate a %db DSA key", KEY_LEN);

    if (unlikely(0 == EVP_PKEY_assign_DSA(pkey_m, &keypair)))
        LOG_OpenSSL("Cannot attach a DSA to an EVP_PKEY");

, then try to create a certificate, as

    X509_t *x509 = X509_new();
    if (unlikely(! x509))
        LOG_OpenSSL("Cannot allocate a X509");

    if (unlikely(0 == X509_set_version(x509, /*support X509v3*/ 2)))
        LOG_OpenSSL("Cannot set X.509 ver");

    if (unlikely(! ASN1_INTEGER_set(X509_get_serialNumber(x509), 1)))
        LOG_OpenSSL("Cannot set serial number");

    if (unlikely(! X509_gmtime_adj(X509_get_notBefore(x509), 0) ||
                 ! X509_gmtime_adj(X509_get_notAfter(x509),
                   certValidityDuration_years * 366 * 24 * 60 * 60)))
        LOG_OpenSSL("Cannot set validity period bounds");

    if (0 == X509_set_pubkey(x509, keypair.pkey_m))
        LOG_OpenSSL("Cannot set keypair");

Then follow calls to X509_NAME_add_entry_by_txt(), X509_set_issuer_name(),
and X509_sign(); but the program doesn't make it there.  Call stack:

Program received signal SIGSEGV, Segmentation fault.
0x00000000006e7c7f in BN_num_bits (a=0x5515bf5e) at bn_lib.c:250
(gdb) bt
#0  0x00000000006e7c7f in BN_num_bits (a=0x5515bf5e) at bn_lib.c:250
#1  0x0000000000714cfa in bn_i2c (pval=0x7fffffffdde8, cont=0x0,
putype=0x7fffffffd9b0, it=0x8de540 <BIGNUM_it>) at x_bignum.c:117
#2  0x0000000000718b1c in asn1_ex_i2c (pval=0x7fffffffdde8, cout=0x0,
putype=0x7fffffffd9b0, it=0x8de540 <BIGNUM_it>) at tasn_enc.c:583
#3  0x00000000007189db in asn1_i2d_ex_primitive (pval=0x7fffffffdde8,
out=0x0, it=0x8de540 <BIGNUM_it>, tag=-1, aclass=0) at tasn_enc.c:523
#4  0x0000000000717e09 in ASN1_item_ex_i2d (pval=0x7fffffffdde8, out=0x0,
it=0x8de540 <BIGNUM_it>, tag=-1, aclass=0) at tasn_enc.c:154
#5  0x0000000000718663 in asn1_template_ex_i2d (pval=0x7fffffffdde8,
out=0x0, tt=0x8d9900 <DSAPublicKey_ch_tt>, tag=-1, iclass=0) at tasn_enc.c:413
#6  0x0000000000717f12 in ASN1_item_ex_i2d (pval=0x7fffffffdbb8, out=0x0,
it=0x8d9960 <DSAPublicKey_it>, tag=-1, aclass=0) at tasn_enc.c:170
#7  0x0000000000717c48 in asn1_item_flags_i2d (val=0x7fffffffddb8,
out=0x7fffffffdc50, it=0x8d9960 <DSAPublicKey_it>, flags=0) at tasn_enc.c:110
#8  0x0000000000717bf4 in ASN1_item_i2d (val=0x7fffffffddb8,
out=0x7fffffffdc50, it=0x8d9960 <DSAPublicKey_it>) at tasn_enc.c:91
#9  0x00000000006f962f in i2d_DSAPublicKey (a=0x7fffffffddb8,
out=0x7fffffffdc50) at dsa_asn1.c:145
#10 0x00000000007719c9 in dsa_pub_encode (pk=0x192c89e0, pkey=0x192c8590) at
#11 0x000000000078249b in X509_PUBKEY_set (x=0x192c7960, pkey=0x192c8590) at
#12 0x0000000000727e81 in X509_set_pubkey (x=0x192c8db0, pkey=0x192c8590) at

Specifically, in frame #10, we have

(gdb) p pval
$86 = (ASN1_VALUE **) 0x7fffffffdc18
(gdb) p *pval
$87 = (ASN1_VALUE *) 0x7fffffffddb8

; but in frame #5, we call asn1_get_field_ptr(), which increments *pval by
48B, so then we have

(gdb) p pchval
$96 = (ASN1_VALUE **) 0x7fffffffdde8
(gdb) p *pchval
$97 = (ASN1_VALUE *) 0x5515bf5e

That 0x5515bf5e is outside of the program's virtual space, as we learn in
frame #0.

What am I doing wrong, please?  Many thanks in advance.

as a result of calling 

More information about the openssl-users mailing list