Преглед на файлове

Improving gen program, using getopt() and testing it with a trivial script.

XXX. The syntax gives as helper in usage is probably wrong, shall read POSIX
standard.
Modifying gen program to be used for generating test private and public keys.
Michele Orrù преди 11 години
родител
ревизия
183e457bcf
променени са 2 файла, в които са добавени 89 реда и са изтрити 23 реда
  1. 1 2
      src/apps/Makefile.am
  2. 88 21
      src/apps/gen.c

+ 1 - 2
src/apps/Makefile.am

@@ -6,5 +6,4 @@ gen_SOURCES = gen.c
 gen_LDFLAGS = -lcrypto -lssl
 
 
-gen.o:
-	$(CC) $(CFLAGS) $(LIBS) gen.c -c -o gen.o
+TESTS = tests/test_gen.test

+ 88 - 21
src/apps/gen.c

@@ -8,45 +8,65 @@
 #include <errno.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <unistd.h>
 
 #include <openssl/bn.h>
 #include <openssl/ssl.h>
 #include <openssl/rsa.h>
 
-
-void usage(void)
+static void
+usage(int ret)
 {
-  static const char* help_message = "%s usage: %s"
-    " <pub key> <priv key> <p> <q>"
-    "\n";
+  static const char* help_message = "%s usage: \n"
+    "%s pub [-n MODULUS | -p PRIME -q PRIME] -e PUBLIC_EXPONENT\n"
+    "%s priv -p PRIME -q PRIME -e PUBLIC_EXPONENT -d PRIVATE_EXPONENT\n";
   fprintf(stderr, help_message, program_invocation_short_name,
           program_invocation_name);
+
+  exit(ret);
 }
 
-int main(int argc, char **argv)
+
+static int
+pubkey_generation(RSA* rsa)
+{
+  BN_CTX *ctx = BN_CTX_new();
+
+  /* we need <N, e> to get a valid public key. */
+  if (!(rsa->e &&
+        (rsa->n ||(rsa->p && rsa->q)))) {
+    fprintf(stderr, "Not enough parameter for the public key generation!\n");
+    exit(EXIT_FAILURE);
+    }
+
+  if (!rsa->n)
+    BN_mul(rsa->n, rsa->p, rsa->q, ctx);
+
+  PEM_write_RSAPublicKey(stdout, rsa);
+
+  BN_CTX_free(ctx);
+  return EXIT_SUCCESS;
+}
+
+static int
+privkey_generation(RSA *rsa)
 {
-  BN_CTX* ctx;
-  BIGNUM* p1, *q1;
-  RSA* rsa;
+  BIGNUM *p1, *q1;
+  BN_CTX *ctx = BN_CTX_new();
+
+  if (!(rsa->p && rsa->q && rsa->e && rsa->d)) {
+    fprintf(stderr, "Not enough parameter for the private key generation!\n");
+    return EXIT_FAILURE;
+  }
 
-  rsa = RSA_new();
   p1 = BN_new();
   q1 = BN_new();
-  ctx = BN_CTX_new();
   rsa->n = BN_new();
   rsa->iqmp = BN_new();
   rsa->dmp1 = BN_new();
   rsa->dmq1 = BN_new();
 
-  if (argc < 4+1) {
-    usage();
-    return EXIT_FAILURE;
-  }
   /* generating RSA key */
-  BN_dec2bn(&rsa->e, argv[1]);
-  BN_dec2bn(&rsa->d, argv[2]);
-  BN_dec2bn(&rsa->p, argv[3]);
-  BN_dec2bn(&rsa->q, argv[4]);
   BN_mul(rsa->n, rsa->p, rsa->q, ctx);
   BN_sub(p1, rsa->p, BN_value_one());
   BN_sub(q1, rsa->q, BN_value_one());
@@ -55,22 +75,69 @@ int main(int argc, char **argv)
   BN_mod_inverse(rsa->iqmp, rsa->q, rsa->p, ctx);
   PEM_write_RSAPrivateKey(stdout, rsa, NULL, NULL, 0, NULL, NULL);
 
+  BN_CTX_free(ctx);
+  return EXIT_SUCCESS;
+}
+
+int main(int argc, char **argv)
+{
+  int opt;
+  RSA *rsa = RSA_new();
+
+  rsa->n = rsa->e = rsa->q = rsa->q = NULL;
+
+  if (argc < 3) usage(EXIT_FAILURE);
+
+  while ((opt = getopt(argc-1, argv+1, "e:N:n:p:q:")) != -1)  {
+    switch (opt) {
+    case 'N':
+    case 'n':
+      if (!BN_dec2bn(&rsa->n, optarg)) usage(EXIT_FAILURE);
+      break;
+    case 'd':
+      if (!BN_dec2bn(&rsa->d, optarg)) usage(EXIT_FAILURE);
+      break;
+    case 'e':
+      if (!BN_dec2bn(&rsa->e, optarg)) usage(EXIT_FAILURE);
+      break;
+    case 'p':
+      if (!BN_dec2bn(&rsa->p, optarg)) usage(EXIT_FAILURE);
+      break;
+    case 'q':
+      if (!BN_dec2bn(&rsa->q, optarg)) usage(EXIT_FAILURE);
+      break;
+    default:
+      usage(EXIT_FAILURE);
+    }
+  }
+
+  if (!strcmp(argv[1], "pub"))
+    return pubkey_generation(rsa);
+  else if (!strcmp(argv[1], "priv"))
+    return privkey_generation(rsa);
+  else
+    usage(EXIT_FAILURE);
+
   /* creating public key */
+  /*
   EVP_PKEY *pk;
   pk = EVP_PKEY_new();
   EVP_PKEY_set1_RSA(pk, rsa);
-
+  */
   /* creating dummy certificate */
+  /*
   X509* crt;
   crt = X509_new();
   if (!X509_set_pubkey(crt, pk)) exit(EXIT_FAILURE);
+  */
   /* PEM_write_X509(stdout, crt); */
+  /*
   X509_free(crt);
   EVP_PKEY_free(pk);
-  BN_CTX_free(ctx);
   BN_free(q1);
   BN_free(p1);
   RSA_free(rsa);
 
+  */
   return EXIT_SUCCESS;
 }