[gnutls-help] openpgp and gnutls_privkey_import_openpgp

Petr Vanek petr at yarpen.cz
Thu May 30 15:16:13 CEST 2013

hi all,

what is proper use of gnutls_privkey_import_openpgp, please?

I have a playground application to examine gnutls as a potential backend
for new Qore language module and I'm getting crashes in nettle when I
try to decrypt data.

Is there any public implementation of this functionality I can look
into? Any hints?

petr vanek

selfcompiled gnutls-3.2.0, nettle-2.7; OS used: opensuse 12.3.

gnutls_global_init() is called in main(), also:
    gnutls_global_set_log_function(log_func); // log_func is basically
printf("LOG> %d: %s", level, msg);

test_decrypt(273): 0 GNUTLS_E_SUCCESS = Success. <-- result of     res =
test_decrypt(276): 0 GNUTLS_E_SUCCESS = Success. <--     res =
LOG> 2: ASSERT: stream.c:1035
test_decrypt(284): 0 GNUTLS_E_SUCCESS = Success. <--     res =
gnutls_openpgp_privkey_import(pgppriv, &data, GNUTLS_OPENPGP_FMT_BASE64,
"n/a for now", 0); // the ASCII armored key is in data
LOG> 2: ASSERT: privkey.c:1249
LOG> 2: ASSERT: privkey.c:1249
test_decrypt(287): 0 GNUTLS_E_SUCCESS = Success. <-- res =
gnutls_privkey_import_openpgp(privkey, pgppriv, 0);
LOG> 2: ASSERT: privkey.c:1249                <-- calling of res =
gnutls_privkey_decrypt_data(privkey, 0, &ciphertext, &plaintext);
LOG> 9: Decrypting using master PGP key
LOG> 2: ASSERT: privkey.c:1249
LOG> 2: ASSERT: pubkey.c:291
LOG> 2: ASSERT: pgp.c:1228
LOG> 2: ASSERT: privkey.c:838

Program received signal SIGSEGV, Segmentation fault.
wrap_nettle_mpi_clear (a=0x0) at mpi.c:220
220       memset(TOMPZ(a)[0]._mp_d, 0,
(gdb) bt
#0  wrap_nettle_mpi_clear (a=0x0) at mpi.c:220
#1  0x00007ffff7b078e7 in gnutls_pk_params_clear (p=p at entry=0x7fffffffdb60)
    at gnutls_pk.c:223
#2  0x00007ffff7b8551e in _gnutls_openpgp_privkey_get_mpis (
    pkey=pkey at entry=0x60dbd0, keyid=keyid at entry=0x0,
    params=params at entry=0x7fffffffdb60) at privkey.c:856
#3  0x00007ffff7b868db in _gnutls_openpgp_privkey_decrypt_data
    flags=<optimized out>, ciphertext=0x7fffffffdc40,
    at privkey.c:1449
#4  0x00000000004022c9 in test_decrypt (bn=0x62c310)
    at ../qore-gnutls/main.cpp:295
#5  0x0000000000401f94 in test_encrypt () at ../qore-gnutls/main.cpp:252
#6  0x000000000040240f in main () at ../qore-gnutls/main.cpp:375

the code is:

#define QERRCHECK(err) \
    printf("%s(%d): %d %s = %s\n", __FUNCTION__, __LINE__, res,
gnutls_strerror_name(res), gnutls_strerror(res)); \
    if ((err) != 0) { \
        printf("ERROR: %s\n", gnutls_error_is_fatal((res)) ? "FATAL" :
"regular"); \
        return; \

void test_decrypt(BinaryNode *bn) {
    int res;

    gnutls_privkey_t privkey;
    gnutls_openpgp_privkey_t pgppriv;

    res = gnutls_privkey_init(&privkey);

    res = gnutls_openpgp_privkey_init(&pgppriv);

    gnutls_datum_t data;
    data.data = (unsigned char*)privkeyTxt;
    data.size = sizeof(privkeyTxt);

    res = gnutls_openpgp_privkey_import(pgppriv, &data,
GNUTLS_OPENPGP_FMT_BASE64, "n/a for now", 0);

    res = gnutls_privkey_import_openpgp(privkey, pgppriv, 0);

    //gnutls_privkey_set_pin_function(privkey, test_decrypt_callback,
NULL); // TODO: context data

    gnutls_datum_t plaintext;
    gnutls_datum_t ciphertext;
    ciphertext.data = (unsigned char*)bn->getPtr();
    ciphertext.size = bn->size();
    res = gnutls_privkey_decrypt_data(privkey, 0, &ciphertext, &plaintext);


More information about the Gnutls-help mailing list