summaryrefslogtreecommitdiff
path: root/wsutil/wsgcrypt.c
diff options
context:
space:
mode:
Diffstat (limited to 'wsutil/wsgcrypt.c')
-rw-r--r--wsutil/wsgcrypt.c86
1 files changed, 86 insertions, 0 deletions
diff --git a/wsutil/wsgcrypt.c b/wsutil/wsgcrypt.c
index 869111a214..a6d527f4bd 100644
--- a/wsutil/wsgcrypt.c
+++ b/wsutil/wsgcrypt.c
@@ -71,6 +71,92 @@ void crypt_des_ecb(guint8 *output, const guint8 *buffer, const guint8 *key56)
gcry_cipher_close(handle);
}
+size_t rsa_decrypt_inplace(const guint len, guchar* data, gcry_sexp_t pk, gboolean pkcs1_padding, char **err)
+{
+ gint rc = 0;
+ size_t decr_len = 0, i = 0;
+ gcry_sexp_t s_data = NULL, s_plain = NULL;
+ gcry_mpi_t encr_mpi = NULL, text = NULL;
+
+ *err = NULL;
+
+ /* create mpi representation of encrypted data */
+ rc = gcry_mpi_scan(&encr_mpi, GCRYMPI_FMT_USG, data, len, NULL);
+ if (rc != 0 ) {
+ *err = g_strdup_printf("can't convert data to mpi (size %d):%s", len, gcry_strerror(rc));
+ return 0;
+ }
+
+ /* put the data into a simple list */
+ rc = gcry_sexp_build(&s_data, NULL, "(enc-val(rsa(a%m)))", encr_mpi);
+ if (rc != 0) {
+ *err = g_strdup_printf("can't build encr_sexp:%s", gcry_strerror(rc));
+ decr_len = 0;
+ goto out;
+ }
+
+ /* pass it to libgcrypt */
+ rc = gcry_pk_decrypt(&s_plain, s_data, pk);
+ if (rc != 0)
+ {
+ *err = g_strdup_printf("can't decrypt key:%s", gcry_strerror(rc));
+ decr_len = 0;
+ goto out;
+ }
+
+ /* convert plain text sexp to mpi format */
+ text = gcry_sexp_nth_mpi(s_plain, 0, 0);
+ if (! text) {
+ *err = g_strdup("can't convert sexp to mpi");
+ decr_len = 0;
+ goto out;
+ }
+
+ /* compute size requested for plaintext buffer */
+ rc = gcry_mpi_print(GCRYMPI_FMT_USG, NULL, 0, &decr_len, text);
+ if (rc != 0) {
+ *err = g_strdup_printf("can't compute decr size:%s", gcry_strerror(rc));
+ decr_len = 0;
+ goto out;
+ }
+
+ /* sanity check on out buffer */
+ if (decr_len > len) {
+ *err = g_strdup_printf("decrypted data is too long ?!? (%" G_GSIZE_MODIFIER "u max %d)", decr_len, len);
+ decr_len = 0;
+ goto out;
+ }
+
+ /* write plain text to newly allocated buffer */
+ rc = gcry_mpi_print(GCRYMPI_FMT_USG, data, len, &decr_len, text);
+ if (rc != 0) {
+ *err = g_strdup_printf("can't print decr data to mpi (size %" G_GSIZE_MODIFIER "u):%s", decr_len, gcry_strerror(rc));
+ decr_len = 0;
+ goto out;
+ }
+
+ if (pkcs1_padding) {
+ /* strip the padding*/
+ rc = 0;
+ for (i = 1; i < decr_len; i++) {
+ if (data[i] == 0) {
+ rc = (gint) i+1;
+ break;
+ }
+ }
+
+ decr_len -= rc;
+ memmove(data, data+rc, decr_len);
+ }
+
+out:
+ gcry_sexp_release(s_data);
+ gcry_sexp_release(s_plain);
+ gcry_mpi_release(encr_mpi);
+ gcry_mpi_release(text);
+ return decr_len;
+}
+
/*
* Editor modelines - http://www.wireshark.org/tools/modelines.html
*