uni

University stuff
git clone git://git.margiolis.net/uni.git
Log | Files | Refs | README | LICENSE

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 }