priv.c (1836B)
1 #include <err.h> 2 #include <stdio.h> 3 #include <string.h> 4 #include <unistd.h> 5 6 #include <openssl/bn.h> 7 8 static char *argv0; 9 10 static const char * 11 read_line(FILE *fp) 12 { 13 char buf[2048]; 14 15 if (fgets(buf, sizeof(buf), fp) == NULL) 16 err(1, "fgets"); 17 return (strdup(buf)); 18 } 19 20 static void 21 printbn(char *str, BIGNUM *bn) 22 { 23 char *s; 24 25 s = BN_bn2hex(bn); 26 printf("%s%s\n", str, s); 27 OPENSSL_free(s); 28 } 29 30 static void 31 usage(void) 32 { 33 fprintf(stderr, "usage: %s [-v] input\n", argv0); 34 exit(1); 35 } 36 37 int 38 main(int argc, char *argv[]) 39 { 40 BN_CTX *ctx; 41 BIGNUM *p, *q, *e, *n, *d; 42 BIGNUM *phi, *one, *foo, *bar; 43 FILE *fp; 44 int verbose = 0; 45 char ch; 46 47 argv0 = *argv; 48 49 while ((ch = getopt(argc, argv, "v")) != -1) { 50 switch (ch) { 51 case 'v': 52 verbose = 1; 53 break; 54 case '?': /* FALLTHROUGH */ 55 default: 56 usage(); 57 } 58 } 59 argc -= optind; 60 argv += optind; 61 62 if (!argc) 63 usage(); 64 if ((fp = fopen(*argv, "r")) == NULL) 65 err(1, "fopen(%s)", *argv); 66 67 ctx = BN_CTX_new(); 68 p = BN_new(); 69 q = BN_new(); 70 e = BN_new(); 71 n = BN_new(); 72 d = BN_new(); 73 74 phi = BN_new(); 75 one = BN_new(); 76 foo = BN_new(); 77 bar = BN_new(); 78 79 /* We assume the file has at least 3 lines */ 80 BN_hex2bn(&p, read_line(fp)); 81 BN_hex2bn(&q, read_line(fp)); 82 BN_hex2bn(&e, read_line(fp)); 83 BN_mul(n, p, q, ctx); 84 85 /* 86 * Calculate private key: 87 * 1. phi(n) = (p-1) * (q-1) 88 * 2. (e * d mod phi(n) = 1), solve for d 89 */ 90 BN_dec2bn(&one, "1"); 91 BN_sub(foo, p, one); 92 BN_sub(bar, q, one); 93 BN_mul(phi, foo, bar, ctx); 94 BN_mod_inverse(d, e, phi, ctx); 95 96 if (verbose) { 97 printbn("e: ", e); 98 printbn("n: ", n); 99 printbn("d: ", d); 100 } else 101 printbn("", d); 102 103 fclose(fp); 104 OPENSSL_free(p); 105 OPENSSL_free(q); 106 OPENSSL_free(e); 107 OPENSSL_free(n); 108 OPENSSL_free(q); 109 OPENSSL_free(phi); 110 OPENSSL_free(one); 111 OPENSSL_free(foo); 112 OPENSSL_free(bar); 113 OPENSSL_free(ctx); 114 115 return (0); 116 }