浏览代码

Creating run_question().

Yet another interface for handling questions, to be used both at runtime and
while testing.
Michele Orrù 11 年之前
父节点
当前提交
cb955a4287

+ 20 - 49
src/qa.c

@@ -154,9 +154,8 @@ qa_init(const struct qa_conf* conf)
 static int
 qa_dispose(X509 *crt, RSA *rsa)
 {
-  int exit_code = EXIT_SUCCESS;
+  int exit_code;
   RSA *pub;
-  RSA *priv = NULL;
   qa_question_t *q;
 #ifdef HAVE_OPENMPI
   int proc, procs, i;
@@ -179,57 +178,29 @@ qa_dispose(X509 *crt, RSA *rsa)
 #endif
 
     printf( "[-] Running: %s\n", q->pretty_name);
-
-    /*
-     * Run setup. If it fails, then print an error message and go to the next
-     * question.
-     */
-    if (q->setup && q->setup() <= 0)  {
-      fprintf(stderr, "[x] Unexpected error loading question %s\n", q->pretty_name);
-      continue;
-    }
-
-    /*
-     * Run test. If the test is undecidible or either ok, go on. Otherwise,
-     * print an error message and go to the next question.
-     */
-    if (q->test && q->test(crt) < 0) {
-      fprintf(stderr, "[|] Question %s cannot attack the given certificate.\n", q->pretty_name);
-      continue;
-    }
-
-    /*
-     * Attempt to attack the X509 certificate.
-     */
-    if (crt && q->ask_crt)  q->ask_crt(crt);
-
-    /*
-     * Attempt to attack RSA. If the attack went ok, there's no need to go
-     * on. Print out a nice message and then quit.
-     */
-    if (q->ask_rsa &&
-        (priv = q->ask_rsa(pub))) {
-      fprintf(stderr, "[\\] Key Broken using %s.\n", q->pretty_name);
-      print_rsa_private(priv);
-      exit_code = EXIT_FAILURE;
-      break;
-    }
-
-    /*
-     * Shut down the given question. If it fails, print an error messae and go
-     * on.
-     */
-    if (q->teardown && q->teardown() <= 0) {
-      fprintf(stderr, "[x] Unexpected error shutting down question %s.\n", q->pretty_name);
-      continue;
-    }
+    switch (run_question(q, crt, pub)) {
+      case -3:
+        fprintf(stderr, "[x] Unexpected error shutting down question %s\n", q->pretty_name);
+        exit_code = EXIT_FAILURE;
+      case -2:
+        fprintf(stderr, "[x] Unexpected error loading question %s\n", q->pretty_name);
+        exit_code = EXIT_FAILURE;
+        break;
+      case -1:
+        fprintf(stderr, "[|] Question %s cannot attack the given certificate.\n", q->pretty_name);
+        exit_code = EXIT_SUCCESS;
+        break;
+      default:
+        fprintf(stderr, "[\\] Key Broken using %s.\n", q->pretty_name);
+        exit_code = EXIT_SUCCESS;
+        goto end;
+      }
   }
 
-  if (priv) RSA_free(priv);
-  MPI_Abort(MPI_COMM_WORLD, -1);
+end:
   QA_library_del();
   /*
    *  Key seems resistent: exit successfully.
    */
-  return EXIT_SUCCESS;
+  return exit_code;
 }

+ 42 - 0
src/questions/allquestions.c

@@ -12,6 +12,8 @@
 #include <string.h>
 #include <bsd/sys/queue.h>
 
+#include <openssl/x509.h>
+#include <openssl/rsa.h>
 #include <openssl/ssl.h>
 #include <mpi.h>
 
@@ -45,6 +47,46 @@ void select_question(const char *sq)
       LIST_REMOVE(q, qs);
 }
 
+
+/**
+ * \brief Run a specific question, returning the measure of security probed.
+ * \return -1 if the question `q` is not suited for attacking the certificate.
+ *         -2 if there has been a problem setting up the given question
+ *         -3 if there has been a problem shutting down the given question
+ *          0 if the certificate/key is considered secure.
+ *          1.. attack measure.
+ *
+ */
+int run_question(qa_question_t *q, X509 *crt, RSA *pub)
+{
+  RSA *priv;
+
+  /* Run setup, if any */
+  if (q->setup && q->setup() <= 0)
+    return -2;
+  /* Run test, if any. */
+  if (q->test && q->test(crt) < 0)
+    return -1;
+  /* Attempt to attack the X509 certificate. */
+  if (crt && q->ask_crt)
+    q->ask_crt(crt);
+  /* Attempt to attack the RSA public key */
+  if (q->ask_rsa &&
+      (priv = q->ask_rsa(pub))) {
+#ifdef DEBUG
+    PEM_write_RSAPrivateKey(stdout, priv, NULL, NULL, 0, NULL, NULL);
+    // print_rsa_private(priv);
+#endif
+    RSA_free(priv);
+    return 1;
+  }
+  /* Shut down the given question. */
+  if (q->teardown && q->teardown() <= 0)
+    return -3;
+
+  return 0;
+}
+
 /**
  * \brief Puts registered questions into \ref questions.
  *

+ 1 - 0
src/questions/include/questions.h

@@ -40,6 +40,7 @@ LIST_HEAD(listhead, qa_question) questions;
 
 void select_question(const char *);
 void select_all_questions(void);
+int run_question(qa_question_t *q, X509 *crt, RSA *pub);
 
 void QA_library_init(void);
 

+ 4 - 2
src/questions/tests/Makefile.am

@@ -3,8 +3,8 @@
 LDADD = ../libquestions.a -lssl -lcrypto
 
 check_PROGRAMS = test_qarith test_qstrings test_wiener test_pollard test_dixon \
-	         test_williams test_primes
-TESTS = $(check_PROGRAMS) test_fermat.test test_metadata.test test_pollardrho.test
+	         test_williams test_primes test_pollardrho test_fermat
+TESTS = $(check_PROGRAMS) test_metadata.test
 
 
 test_primes_sources = test_primes.c
@@ -14,3 +14,5 @@ test_qarith_SOURCES = test_qarith.c
 test_wiener_SOURCES = test_wiener.c
 test_pollard_SOURCES = test_pollard.c
 test_dixon_SOURCES = test_dixon.c
+test_pollardrho_SOURCES = test_pollardrho.c
+test_fermat_SOURCES = test_fermat.c

+ 29 - 0
src/questions/tests/test_fermat.c

@@ -0,0 +1,29 @@
+#include <assert.h>
+#include <stdlib.h>
+
+#include <openssl/pem.h>
+#include <openssl/rsa.h>
+
+#include "qa/questions/questions.h"
+
+extern qa_question_t FermatQuestion;
+
+int test_crt(char *in)
+{
+  FILE *fp;
+  RSA *pub;
+
+  if (!(fp = fopen(in, "r")))
+      return EXIT_FAILURE;
+
+  pub = PEM_read_RSAPublicKey(fp, NULL, 0, NULL);
+  if (run_question(&FermatQuestion, NULL, pub) < 1)
+    return EXIT_FAILURE;
+
+  return EXIT_SUCCESS;
+}
+
+int main(void)
+{
+  return (test_crt("fermat.pem") || test_crt("fermat2.pem"));
+}

+ 0 - 5
src/questions/tests/test_fermat.test

@@ -1,5 +0,0 @@
-../../qa -a fermat fermat.pem > /dev/null
-[[ $? == 1 ]] || exit 1
-
-../../qa -a fermat fermat2.pem > /dev/null
-[[ $? == 1 ]] || exit 1

+ 29 - 0
src/questions/tests/test_pollardrho.c

@@ -0,0 +1,29 @@
+#include <assert.h>
+#include <stdlib.h>
+
+#include <openssl/pem.h>
+#include <openssl/rsa.h>
+#include <openssl/x509.h>
+
+#include "qa/questions/questions.h"
+
+int main(void)
+{
+  FILE *fp;
+  RSA *pub;
+  X509 *crt;
+  extern qa_question_t PollardRhoQuestion;
+  extern qa_question_t PollardBrentRhoQuestion;
+
+if (!(fp = fopen("pollardrho.crt", "r")))
+      return EXIT_FAILURE;
+
+  crt = PEM_read_X509(fp, NULL, 0, NULL);
+  pub = X509_get_pubkey(crt)->pkey.rsa;
+  if (run_question(&PollardRhoQuestion, crt, pub) < 1)
+    return EXIT_FAILURE;
+  if (run_question(&PollardBrentRhoQuestion, crt, pub) < 1)
+    return EXIT_FAILURE;
+
+  return EXIT_SUCCESS;
+}