ソースを参照

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;
 }