/*
* Libgcrypt example (Asimmetric Cryptography)
* This simple software is a demostration program that use libgcrypt
* library with RSA algorithm
*
* Matrix86 of TuxMeaLux.net
* matrix86 [.at.] tuxmealux [.dot.] net
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
#include <stdio.h>
#include <gcrypt.h>
#include <assert.h>
#define SIZE 6000
//plain text -> mpi -> s-expression -> crypt text
void
die( char *str ){
fprintf( stderr, "[ERROR] %s\n",str );
exit(1);
}
void
charTosexp( char *plain, gcry_sexp_t *s_exp ){
gcry_mpi_t plain_mpi;
if( gcry_mpi_scan( &plain_mpi, GCRYMPI_FMT_USG, plain, strlen(plain), NULL ) ) die( " during char->mpi conversion." );
if( gcry_sexp_build( s_exp, NULL, "(data(flags raw)(value %m))", plain_mpi ) ) die( " during mpi->s-expression conversion." );
gcry_mpi_release( plain_mpi );
return;
}
void
sexpToChar( gcry_sexp_t s_exp, char * txtexp, int lenght ){
if( gcry_sexp_sprint( s_exp, GCRYSEXP_FMT_DEFAULT, txtexp, lenght ) == 0 ) die( "errore conversione testo" );
}
void
generate_key( gcry_sexp_t *pkey, gcry_sexp_t *skey )
{
gcry_sexp_t key_spec, key, pub_key, sec_key;
int rc;
rc = gcry_sexp_new( &key_spec, "(genkey (rsa (nbits 4:2048)))", 0, 1 );
if( rc ) die( "error creating S-expression." );
rc = gcry_pk_genkey( &key, key_spec );
gcry_sexp_release( key_spec );
if( rc ) die( "error generating RSA key." );
pub_key = gcry_sexp_find_token( key, "public-key", 0 );
if ( !pub_key ) die( "public part missing in key." );
sec_key = gcry_sexp_find_token( key, "private-key", 0 );
if ( !sec_key ) die( "private part missing in key." );
gcry_sexp_release( key );
*pkey = pub_key;
*skey = sec_key;
}
void
printSexp( char *text, int maxlength ) {
int i;
for( i=0; i < maxlength; i++ ) {
if( text[i] == ')' && text[i+1] == '\n' && text[i+2] == '\0' ) break;
if( text[i] == '\0' ) text[i] = ' ';
}
return;
}
int
main( int argc, char** argv )
{
int err;
int i = 0;
char *version;
gcry_sexp_t data_decrypted = NULL;
gcry_sexp_t p_key, s_key, plain_sexp, crypt_sexp;
char plain[300], cryptext[SIZE], decrypt[SIZE], buffer[SIZE];
memset( plain, '\0', sizeof(plain) );
memset( cryptext, '\0', sizeof(cryptext) );
memset( decrypt, '\0', sizeof(decrypt) );
gcry_control( GCRYCTL_DISABLE_SECMEM );
version = strdup( gcry_check_version(NULL) );
printf( "Libgcrypt Test.\nVersion: %s\n", version
);
gcry_control( GCRYCTL_ENABLE_QUICK_RANDOM, 0 );
printf( "Generazione chiavi pubblica e privata.\n" );
// Generation of public and private keys
generate_key( &p_key, &s_key );
sexpToChar( p_key, buffer, SIZE );
printSexp( buffer, SIZE );
printf( "Chiave pubblica:\n%s\n\n", buffer
);
sexpToChar( s_key, buffer, SIZE );
printSexp( buffer, SIZE );
printf( "Chiave privata:\n%s\n\n", buffer
);
printf( "Inserisci la stringa da codificare: " );
while( ( plain[i] = getchar() ) != '\n' ){
i++;
}
charTosexp( plain, &plain_sexp ); // From string to s-expression
if( ( err = gcry_pk_encrypt( &crypt_sexp, plain_sexp, p_key ) ) ) die( "during the encryption fase." );
sexpToChar( crypt_sexp, cryptext, SIZE ); // From s-expression to string
printSexp( cryptext, SIZE );
printf( "Testo cifrato: \n%s\n\n", cryptext
);
if( ( gcry_pk_decrypt( &data_decrypted, crypt_sexp, s_key ) ) ) die( "during the decryption fase." );
sexpToChar( data_decrypted, decrypt, SIZE );
printf( "Testo in chiaro: \n%s\n\n", decrypt
);
gcry_sexp_release( s_key );
gcry_sexp_release( p_key );
gcry_sexp_release( crypt_sexp );
gcry_sexp_release( plain_sexp );
return 0;
}