forked from vedantk/gcrypt-example
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.cc
116 lines (96 loc) · 3.08 KB
/
main.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
// main.cc
// Copyright (C) 2013 Vedant Kumar <[email protected]>, see ~/LICENSE.txt.
#include "gcry.hh"
int main(int argc, char** argv)
{
if (argc != 2) {
fprintf(stderr, "Usage: %s <rsa-keypair.sp>\n", argv[0]);
xerr("Invalid arguments.");
}
gcrypt_init();
gcry_error_t err;
char* fname = argv[1];
FILE* lockf = fopen(fname, "rb");
if (!lockf) {
xerr("fopen() failed");
}
/* Grab a key pair password and create an AES context with it. */
gcry_cipher_hd_t aes_hd;
get_aes_ctx(&aes_hd);
/* Read and decrypt the key pair from disk. */
size_t rsa_len = get_keypair_size(2048);
void* rsa_buf = calloc(1, rsa_len);
if (!rsa_buf) {
xerr("malloc: could not allocate rsa buffer");
}
if (fread(rsa_buf, rsa_len, 1, lockf) != 1) {
xerr("fread() failed");
}
err = gcry_cipher_decrypt(aes_hd, (unsigned char*) rsa_buf,
rsa_len, NULL, 0);
if (err) {
xerr("gcrypt: failed to decrypt key pair");
}
/* Load the key pair components into sexps. */
gcry_sexp_t rsa_keypair;
err = gcry_sexp_new(&rsa_keypair, rsa_buf, rsa_len, 0);
gcry_sexp_t pubk = gcry_sexp_find_token(rsa_keypair, "public-key", 0);
gcry_sexp_t privk = gcry_sexp_find_token(rsa_keypair, "private-key", 0);
/* Create a message. */
gcry_mpi_t msg;
gcry_sexp_t data;
const unsigned char* s = (const unsigned char*) "Hello world.";
err = gcry_mpi_scan(&msg, GCRYMPI_FMT_USG, s,
strlen((const char*) s), NULL);
if (err) {
xerr("failed to create a mpi from the message");
}
err = gcry_sexp_build(&data, NULL,
"(data (flags raw) (value %m))", msg);
if (err) {
xerr("failed to create a sexp from the message");
}
/* Encrypt the message. */
gcry_sexp_t ciph;
err = gcry_pk_encrypt(&ciph, data, pubk);
if (err) {
xerr("gcrypt: encryption failed");
}
/* Decrypt the message. */
gcry_sexp_t plain;
err = gcry_pk_decrypt(&plain, ciph, privk);
if (err) {
xerr("gcrypt: decryption failed");
}
/* Pretty-print the results. */
gcry_mpi_t out_msg = gcry_sexp_nth_mpi(plain, 0, GCRYMPI_FMT_USG);
printf("Original:\n");
gcry_mpi_dump(msg);
printf("\n" "Decrypted:\n");
gcry_mpi_dump(out_msg);
printf("\n");
if (gcry_mpi_cmp(msg, out_msg)) {
xerr("data corruption!");
}
printf("Messages match.\n");
unsigned char obuf[64] = { 0 };
err = gcry_mpi_print(GCRYMPI_FMT_USG, (unsigned char*) &obuf,
sizeof(obuf), NULL, out_msg);
if (err) {
xerr("failed to stringify mpi");
}
printf("-> %s\n", (char*) obuf);
/* Release contexts. */
gcry_mpi_release(msg);
gcry_mpi_release(out_msg);
gcry_sexp_release(rsa_keypair);
gcry_sexp_release(pubk);
gcry_sexp_release(privk);
gcry_sexp_release(data);
gcry_sexp_release(ciph);
gcry_sexp_release(plain);
gcry_cipher_close(aes_hd);
free(rsa_buf);
fclose(lockf);
return 0;
}