Parcourir la source

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ù il y a 11 ans
Parent
commit
183e457bcf
2 fichiers modifiés avec 89 ajouts et 23 suppressions
  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;
 }