char* encrypt(rsa_packet * packet, char *public_key, char *plaintext){ gcry_error_t error; gcry_mpi_t r_mpi; if ((error = gcry_mpi_scan(&r_mpi, GCRYMPI_FMT_HEX, plaintext, 0, NULL))) { printf("Error in gcry_mpi_scan() in encrypt(): %s\nSource: %s\n", gcry_strerror(error), gcry_strsource(error)); exit(1); } gcry_sexp_t data; size_t erroff; if ((error = gcry_sexp_build(&data, &erroff, "(data (flags raw) (value %m))", r_mpi))) { printf("Error in gcry_sexp_build() in encrypt() at %ld: %s\nSource: %s\n", erroff, gcry_strerror(error), gcry_strsource(error)); exit(1); } gcry_sexp_t public_sexp = sexp_new(public_key); gcry_sexp_t r_ciph; struct timeval timer; timer_start(&timer); if ((error = gcry_pk_encrypt(&r_ciph, data, public_sexp))) { printf("Error in gcry_pk_encrypt(): %s\nSource: %s\n", gcry_strerror(error), gcry_strsource(error)); exit(1); } timer_poll("\nSoftware encrypt: %d.%06d seconds\n", &timer); gcry_sexp_t cipher_sexp = gcry_sexp_cdr(gcry_sexp_find_token(r_ciph, "a", 1)); gcry_mpi_t cipher_mpi = gcry_sexp_nth_mpi(cipher_sexp, 0, GCRYMPI_FMT_USG); gcry_mpi_print(GCRYMPI_FMT_USG, packet->ciphertext, 256, &packet->cipher_len, cipher_mpi); return sexp_string(r_ciph); }
gcry_sexp_t gcry_sexp_cadr ( const gcry_sexp_t list ) { gcry_sexp_t a, b; a = gcry_sexp_cdr (list); b = gcry_sexp_car (a); gcry_sexp_release (a); return b; }
void generate_key(rsa_packet * packet, char **public_key, char **private_key) { gcry_error_t error; int i; // Generate a reduced strength (to save time) RSA key, 1024 bits long // gcry_sexp_t params = sexp_new( "(genkey (rsa (transient-key) (nbits 3:512)))" ); gcry_sexp_t params = sexp_new( "(genkey (rsa (transient-key) (nbits 4:1024)))" ); gcry_sexp_t r_key; if ((error = gcry_pk_genkey(&r_key, params))) { printf("Error in gcry_pk_genkey(): %s\nSource: %s\n", gcry_strerror(error), gcry_strsource(error)); exit(1); } // Parse the S expression strings gcry_sexp_t public_sexp = gcry_sexp_nth(r_key, 1); gcry_sexp_t private_sexp = gcry_sexp_nth(r_key, 2); gcry_sexp_t mod_sexp = gcry_sexp_cdr(gcry_sexp_find_token(private_sexp, "n", 1)); gcry_sexp_t priv_exp_sexp = gcry_sexp_cdr(gcry_sexp_find_token(private_sexp, "d", 1)); gcry_sexp_t pub_exp_sexp = gcry_sexp_cdr(gcry_sexp_find_token(public_sexp, "e", 1)); // Extract the raw data in MPI format gcry_mpi_t mod_mpi, pubexp_mpi, privexp_mpi; mod_mpi = gcry_sexp_nth_mpi(mod_sexp, 0, GCRYMPI_FMT_USG); privexp_mpi = gcry_sexp_nth_mpi(priv_exp_sexp, 0, GCRYMPI_FMT_USG); pubexp_mpi = gcry_sexp_nth_mpi(pub_exp_sexp, 0, GCRYMPI_FMT_USG); //gcry_mpi_aprint(GCRYMPI_FMT_HEX, public_key, NULL, mod_mpi); // Now pack it into unsigned char gcry_mpi_print(GCRYMPI_FMT_USG, packet->mod, 256, &packet->mod_len, mod_mpi); gcry_mpi_print(GCRYMPI_FMT_USG, packet->priv_exp, 256, &packet->priv_len, privexp_mpi); gcry_mpi_print(GCRYMPI_FMT_USG, packet->pub_exp, 256, &packet->pub_len, pubexp_mpi); // printf ("fmt: %i: %.*s\n", (int)len, (int) len, ); *public_key = sexp_string(public_sexp); *private_key = sexp_string(private_sexp); }
int p2p_encrypt(unsigned char *msg, size_t msglen, unsigned char *buf, size_t buflen, gcry_sexp_t r_key) { gcry_sexp_t ciph, data; size_t err; gcry_sexp_build(&data, &err, "(data (flags pkcs1) (value %b))", msglen, msg); gcry_pk_encrypt(&ciph, data, r_key); gcry_sexp_release(data); gcry_sexp_t a = gcry_sexp_find_token(ciph, "a", 0); gcry_sexp_release(ciph); gcry_sexp_t sexp_mpi = gcry_sexp_cdr(a); gcry_sexp_release(a); gcry_mpi_t data_mpi = gcry_sexp_nth_mpi(sexp_mpi, 0, GCRYMPI_FMT_USG); gcry_mpi_print(GCRYMPI_FMT_PGP, buf, buflen, &err, data_mpi); return err; }
int p2p_decrypt(unsigned char *buf, size_t buflen, char *msg, size_t msglen, gcry_sexp_t d_key) { size_t err; gcry_sexp_t ciph; gcry_mpi_t data_mpi; gcry_mpi_scan(&data_mpi, GCRYMPI_FMT_PGP, buf, buflen, &err); gcry_sexp_build(&ciph, &err, "(enc-val (flags pkcs1) (rsa (a %M)))", data_mpi); gcry_mpi_release(data_mpi); gcry_sexp_t data_sexp; gcry_pk_decrypt(&data_sexp, ciph, d_key); gcry_sexp_release(ciph); gcry_sexp_t data = gcry_sexp_cdr(data_sexp); gcry_sexp_release(data_sexp); size_t len; const char *msg_data = gcry_sexp_nth_data(data, 0, &len); len = msglen > len ? len : msglen; memcpy(msg, msg_data, len); gcry_sexp_release(data); return len; }
void test_sexp ( int argc, char **argv ) { int rc, nbits; gcry_sexp_t sexp; gcry_mpi_t key[3]; size_t n; char *buf; if ( gcry_mpi_scan( &key[0], GCRYMPI_FMT_HEX, elg_testkey1.p, NULL ) ) BUG(); if ( gcry_mpi_scan( &key[1], GCRYMPI_FMT_HEX, elg_testkey1.g, NULL ) ) BUG(); if ( gcry_mpi_scan( &key[2], GCRYMPI_FMT_HEX, elg_testkey1.y, NULL ) ) BUG(); /* get nbits from a key */ rc = gcry_sexp_build ( &sexp, NULL, "(public-key(elg(p%m)(g%m)(y%m)))", key[0], key[1], key[2] ); fputs ( "DUMP of PK:\n", stderr ); gcry_sexp_dump ( sexp ); { gcry_sexp_t x; x = gcry_sexp_cdr ( sexp ); fputs ( "DUMP of CDR:\n", stderr ); gcry_sexp_dump ( x ); gcry_sexp_release ( x ); } nbits = gcry_pk_get_nbits( sexp ); printf ( "elg_testkey1 - nbits=%d\n", nbits ); n = gcry_sexp_sprint ( sexp, 0, NULL, 0 ); buf = gcry_xmalloc ( n ); n = gcry_sexp_sprint ( sexp, 0, buf, n ); printf ( "sprint length=%u\n", (unsigned int)n ); gcry_free ( buf ); gcry_sexp_release( sexp ); }
/* fixme: we need better tests */ static void basic (void) { int pass; gcry_sexp_t sexp; int idx; char *secure_buffer; size_t secure_buffer_len; const char *string; static struct { const char *token; const char *parm; } values[] = { { "public-key", NULL }, { "dsa", NULL }, { "dsa", "p" }, { "dsa", "y" }, { "dsa", "q" }, { "dsa", "g" }, { NULL } }; info ("doing some pretty pointless tests\n"); secure_buffer_len = 99; secure_buffer = gcry_xmalloc_secure (secure_buffer_len); memset (secure_buffer, 'G', secure_buffer_len); for (pass=0;;pass++) { gcry_mpi_t m; switch (pass) { case 0: string = ("(public-key (dsa (p #41424344#) (y this_is_y) " "(q #61626364656667#) (g %m)))"); m = gcry_mpi_set_ui (NULL, 42); if ( gcry_sexp_build (&sexp, NULL, string, m ) ) { gcry_mpi_release (m); fail (" scanning `%s' failed\n", string); return; } gcry_mpi_release (m); break; case 1: string = ("(public-key (dsa (p #41424344#) (y this_is_y) " "(q %b) (g %m)))"); m = gcry_mpi_set_ui (NULL, 42); if ( gcry_sexp_build (&sexp, NULL, string, 15, "foo\0\x01\0x02789012345", m) ) { gcry_mpi_release (m); fail (" scanning `%s' failed\n", string); return; } gcry_mpi_release (m); break; case 2: string = ("(public-key (dsa (p #41424344#) (y silly_y_value) " "(q %b) (g %m)))"); m = gcry_mpi_set_ui (NULL, 17); if ( gcry_sexp_build (&sexp, NULL, string, secure_buffer_len, secure_buffer, m) ) { gcry_mpi_release (m); fail (" scanning `%s' failed\n", string); return; } gcry_mpi_release (m); if (!gcry_is_secure (sexp)) fail ("gcry_sexp_build did not switch to secure memory\n"); break; case 3: { gcry_sexp_t help_sexp; if (gcry_sexp_new (&help_sexp, "(foobar-parms (xp #1234#)(xq #03#))", 0, 1)) { fail (" scanning fixed string failed\n"); return; } string = ("(public-key (dsa (p #41424344#) (parm %S) " "(y dummy)(q %b) (g %m)))"); m = gcry_mpi_set_ui (NULL, 17); if ( gcry_sexp_build (&sexp, NULL, string, help_sexp, secure_buffer_len, secure_buffer, m) ) { gcry_mpi_release (m); fail (" scanning `%s' failed\n", string); return; } gcry_mpi_release (m); gcry_sexp_release (help_sexp); } break; default: return; /* Ready. */ } /* now find something */ for (idx=0; values[idx].token; idx++) { const char *token = values[idx].token; const char *parm = values[idx].parm; gcry_sexp_t s1, s2; gcry_mpi_t a; const char *p; size_t n; s1 = gcry_sexp_find_token (sexp, token, strlen(token) ); if (!s1) { fail ("didn't found `%s'\n", token); continue; } p = gcry_sexp_nth_data (s1, 0, &n); if (!p) { gcry_sexp_release (s1); fail ("no car for `%s'\n", token); continue; } info ("car=`%.*s'\n", (int)n, p); s2 = gcry_sexp_cdr (s1); if (!s2) { gcry_sexp_release (s1); fail ("no cdr for `%s'\n", token); continue; } p = gcry_sexp_nth_data (s2, 0, &n); gcry_sexp_release (s2); if (p) { gcry_sexp_release (s1); fail ("data at car of `%s'\n", token); continue; } if (parm) { s2 = gcry_sexp_find_token (s1, parm, strlen (parm)); gcry_sexp_release (s1); if (!s2) { fail ("didn't found `%s'\n", parm); continue; } p = gcry_sexp_nth_data (s2, 0, &n); if (!p) { gcry_sexp_release (s2); fail("no car for `%s'\n", parm ); continue; } info ("car=`%.*s'\n", (int)n, p); p = gcry_sexp_nth_data (s2, 1, &n); if (!p) { gcry_sexp_release (s2); fail("no cdr for `%s'\n", parm ); continue; } info ("cdr=`%.*s'\n", (int)n, p); a = gcry_sexp_nth_mpi (s2, 0, GCRYMPI_FMT_USG); gcry_sexp_release (s2); if (!a) { fail("failed to cdr the mpi for `%s'\n", parm); continue; } gcry_mpi_release (a); } else gcry_sexp_release (s1); } gcry_sexp_release (sexp); sexp = NULL; } gcry_free (secure_buffer); }