0

I need to do some RSA decryption and my private key is stored in a file. I am using C++. At first I used OpenSSL, and it worked smoothly, but then the licensing problem appeared, as I want my code to be GPLv2 compatible. Now I am trying to use libgcrypt, but I am having problems using the S-expressions. This is my code:

#include <stdio.h>
#include <stdint.h>
#include <iostream>

#include <gcrypt.h>

using namespace std;

int main()
{
    int cipher_len, key_len;
    FILE *t = NULL, *k = NULL;
    gcry_mpi_t text_mpi = NULL;
    gcry_sexp_t text_s_exp = NULL;
    gcry_mpi_t key_mpi = NULL;
    gcry_sexp_t key_s_exp = NULL;
    gcry_sexp_t decrypted_s_exp = NULL;
    gcry_error_t err;

    /* read encrypted text file */
    if( ! ( t = fopen( "outrsa", "rb" ) ) )
    {
        cout << "could not open encrypted text file" << endl;
        goto error;
    }
    fseek( t, 0, SEEK_END );
    cipher_len = ftell( t );
    rewind( t );

    uint8_t text[cipher_len];
    memset( text, '\0', cipher_len );

    fread( text, 1, cipher_len, t );
    if( ferror( t ) )
    {
        cout << "error while reading encrypted text file" << endl;
        goto error;
    }

    /* create S-expression for encrypted text */
    if( gcry_mpi_scan( &text_mpi, GCRYMPI_FMT_USG, text, cipher_len, NULL ) )
    {
        cout << "error when scanning mpi from encrypted file text" << endl;
        goto error;
    }
    if( gcry_sexp_build( &text_s_exp, NULL, "(enc-val(flags oaep)(rsa(a %m)))", text_mpi ) )
    {
        cout << "error while creating S-expr from mpi for encrypted text" << endl;
        goto error;
    }

    /* read private key file */
    if( ! ( k = fopen( "priv.key", "rb" ) ) )
    {
        cout << "could not open key file" << endl;
        goto error;
    }
    fseek( k, 0, SEEK_END );
    key_len = ftell( k );
    rewind( k );

    uint8_t key[key_len];
    memset( key, '\0', key_len );

    key_len = fread( key, 1, key_len, k );
    if( ferror( k ) )
    {
        cout << "error while reading key file" << endl;
        goto error;
    }

    /* create S-expression for private key */
    if( gcry_mpi_scan( &key_mpi, GCRYMPI_FMT_USG, key, key_len, NULL ) )
    {
        cout << "error when scanning mpi from key file" << endl;
        goto error;
    }
    if( gcry_sexp_build( &key_s_exp, NULL, "(data(flags raw)(value %m))", key_mpi ) )
    {
        cout << "error while creating S-expr from mpi for key" << endl;
        goto error;
    }

    /* decrypt */
    if( ( err = gcry_pk_decrypt( &decrypted_s_exp, text_s_exp, key_s_exp ) ) )
    {
        cout << "error on decryption, source: " << gcry_strsource( err ) << ", error: " << gcry_strerror( err ) << endl;
        goto error;
    }

    /* extract decrypted text from S-expr */
    unsigned char decrypted[ cipher_len + 1 ];
    memset( decrypted, '\0', cipher_len + 1 );
    if( gcry_sexp_sprint( decrypted_s_exp, GCRYSEXP_FMT_DEFAULT, decrypted, cipher_len ) )
    {
        cout << "error while extracting decrypted text from S-expr" << endl;
        goto error;
    }

    cout << "decrypted text:" << endl << decrypted << endl;

    return 0;

error:
    if( text_mpi )
        gcry_mpi_release( text_mpi );
    if( key_mpi )
        gcry_mpi_release( key_mpi );
    if( text_s_exp )
        gcry_sexp_release( text_s_exp );
    if( key_s_exp )
        gcry_sexp_release( key_s_exp );
    if( decrypted_s_exp )
        gcry_sexp_release( decrypted_s_exp );
    if( k )
        fclose( k );
    if( t )
        fclose( t );
    return 1;
}

Now, I know this is definetely not the correct way of using libgcrypt (as I am reading the entire key text as an MPI, and the decryption fails), but with the manual in front, I cannot find a way of reading the key... Should I do the parsing of the key manually?

Thanks!

simm
  • 33
  • 4
  • 1
    You should probably evaluate GnuPG or GnuTLS. – jww Apr 04 '14 at 17:23
  • I would like to use the same library for reading the key and for decrypting. Is it possible with GnuPG and GnuTLS? I saw they are more in the domain of network security... – simm Apr 08 '14 at 10:03

0 Answers0