I'm currently attempting to read in keyfiles my code has outputted for an example implementation of RSA-2048.
My output code reads as follows:
void generate_rsa_key(arguments args) {
FILE* fp_pub;
fp_pub = fopen("rsa_key.pub", "wb");
FILE* fp_pri;
fp_pri = fopen("rsa_key.pri", "wb");
rsa_keygen(args.m_n, args.m_pri_exp, args.m_pub_exp);
gmp_fprintf(fp_pub, "%ZX.%ZX", args.m_pub_exp, args.m_n);
gmp_fprintf(fp_pri, "%ZX.%ZX", args.m_pri_exp, args.m_n);
fprintf(stdout, "\nRSA key pair generated.\n\n");
}
Resulting in a hex-encoded output that looks like:
10001.9F959C28250AF2197AE7B1638AA1CC464B4D4E091B2182830D4020267F68D1DDDBB7E8E1039
C9CEDFE6FD58BA0CA4E16D47D586CC66C2D86DCD3171D7CB5B7A12EDBAEC9E6FB944094519D9A6EAC
7CD6D43B1E1EA8C068FAA3BD0C9C4A703FF6A72782C4A3C8214BCECA8FF9F7B044D51ECB6B11DEB3B
80D0835B6518669742EDC116EF929334DF647A59D2AF395BDBECB6DA74C660B1DAF3D4C25432C6B11
D9C4A6A5D29302D50039F15B1850ED57DA7F9C701BA18141A9E0A6761E88B59E1A01C908A60E4A143
EDC67DE94AD8132305F9B28F2AA3B581E9BE0336D3B34AD0D874B92C51E9A2C074608EB3CD0119CC8
6701BA9667FC1AE00CBEC2DE8932DCEF
My code for reading in a keyfile is:
typedef struct arguments {
mpz_t m_pri_exp;
mpz_t m_pub_exp;
mpz_t m_n;
mpz_t o_pub_exp;
mpz_t o_n;
} arguments;
void read_rsa_keyfile(char* path, arguments args, int pri) {
FILE *fp;
fp = fopen(path, "rb");
if (pri) {
gmp_fscanf(fp, "%ZX.%ZX", args.m_pri_exp, args.m_n);
} else {
gmp_fscanf(fp, "%ZX.%ZX", args.o_pub_exp, args.o_n);
}
}
arguments parse_args(int argc, char* argv[]) {
int i;
arguments args;
for (i = 0; i < argc; i++) {
if (!strcmp(argv[i], "-g") || !strcmp(argv[i], "--gen-key")) {
mpz_inits(args.m_pri_exp, args.m_pub_exp, args.m_n, NULL);
generate_rsa_key(args);
exit(-1);
} else if (!strcmp(argv[i], "-f") || !strcmp(argv[i], "--my-key-file")) {
read_rsa_keyfile(argv[i+1], args, T);
} else if (!strcmp(argv[i], "-p") || !strcmp(argv[i], "--other-key-file")) {
read_rsa_keyfile(argv[i+1], args, F);
} else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) {
print_help();
}
}
if (!mpz_cmp_ui(args.m_pri_exp, (unsigned long)0) || \
!mpz_cmp_ui(args.m_n, (unsigned long)0) || \
!mpz_cmp_ui(args.o_pub_exp, (unsigned long)0) || \
!mpz_cmp_ui(args.o_n, (unsigned long)0)) {
print_help();
} else {
return args;
}
}
Note that I do not initialize the mpz_t
variables and that I give the variable itself, not the address, for the gmp_fscanf
calls, both of which are consistent with the GMP docs.
However, when I run the code it segfaults within the GMP library, and gives the error output:
*** glibc detected *** ./dhe_rsa: realloc(): invalid pointer: 0x00007fff9c0342b8 ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x76a16)[0x7fe3dfb1da16]
/lib/x86_64-linux-gnu/libc.so.6(realloc+0x312)[0x7fe3dfb23c22]
/usr/lib/x86_64-linux-gnu/libgmp.so.10(__gmp_default_reallocate+0x1c)[0x7fe3e009ca1c]
/usr/lib/x86_64-linux-gnu/libgmp.so.10(__gmpz_realloc+0x3a)[0x7fe3e00b2bba]
/usr/lib/x86_64-linux-gnu/libgmp.so.10(__gmpz_set_str+0x301)[0x7fe3e00b3ef1]
/usr/lib/x86_64-linux-gnu/libgmp.so.10(__gmp_doscan+0xda7)[0x7fe3e00ed777]
/usr/lib/x86_64-linux-gnu/libgmp.so.10(__gmp_fscanf+0x94)[0x7fe3e00ed8c4]
./dhe_rsa[0x40164f]
./dhe_rsa[0x400fa9]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xfd)[0x7fe3dfac5ead]
./dhe_rsa[0x4011b1]
Is there anything I'm visibly doing wrong with my code? It seems to me to match what is in the docs properly. I've tried a number of different things to try and debug it, and haven't gotten anywhere.
EDIT:
As pointed out by Grzegorz Szpetkowski, I had misunderstood the docs and I do need to initialize the variables. However, the reason I believed that the variables didn't need to be initialized is that I was getting 0 as the result of the my fscanf
reads. As such, that is now my problem. I've edited my function to instead be:
arguments parse_args(int argc, char* argv[]) {
int i;
arguments args;
mpz_inits(args.m_pri_exp, args.m_pub_exp, args.m_n, args.o_pub_exp, args.o_n, NULL);
for (i = 0; i < argc; i++) {
if (!strcmp(argv[i], "-g") || !strcmp(argv[i], "--gen-key")) {
generate_rsa_key(args);
exit(-1);
} else if (!strcmp(argv[i], "-f") || !strcmp(argv[i], "--my-key-file")) {
read_rsa_keyfile(argv[i+1], args, T);
} else if (!strcmp(argv[i], "-p") || !strcmp(argv[i], "--other-key-file")) {
read_rsa_keyfile(argv[i+1], args, F);
} else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) {
print_help();
}
}
gmp_fprintf(stdout, "%ZX\n", args.m_pri_exp);
gmp_fprintf(stdout, "%ZX\n", args.m_n);
gmp_fprintf(stdout, "%ZX\n", args.o_pub_exp);
gmp_fprintf(stdout, "%ZX\n", args.o_n);
if (!mpz_cmp_ui(args.m_pri_exp, (unsigned long)0) || \
!mpz_cmp_ui(args.m_n, (unsigned long)0) || \
!mpz_cmp_ui(args.o_pub_exp, (unsigned long)0) || \
!mpz_cmp_ui(args.o_n, (unsigned long)0)) {
print_help();
} else {
return args;
}
}
And I get the output:
0
0
0
0
The rest remains the same.
It is not obvious what is going wrong, since we don't know how program is called and there are missing pieces of code. However what seems pretty clear to me is that you are calling mpz_inits()
function only for first option (-g
or --gen-key
). As there is exit(-1)
call, it's obvious that other options lack required initialization (read_rsa_keyfile()
is clearly such candidate). To do anything with mpz_t
objects you have to initialize them at first.