chiark / gitweb /
rsa1: Break rsa_loadpriv_core out of rsapriv_apply
[secnet.git] / rsa.c
diff --git a/rsa.c b/rsa.c
index 57ea2424f6273eb1c4003be191fcda18ea5bd73e..b19e898332fe18e3468636b85d385dcd4309fd8b 100644 (file)
--- a/rsa.c
+++ b/rsa.c
@@ -341,19 +341,24 @@ static uint16_t keyfile_get_short(struct cloc loc, FILE *f)
 #define LDUNSUP_FILE(...) cfgfatal_maybefile(f,loc,__VA_ARGS__)
 #define FREE(b)           free(b)
 
-static list_t *rsapriv_apply(closure_t *self, struct cloc loc, dict_t *context,
-                            list_t *args)
+static struct rsapriv *rsa_loadpriv_core(FILE *f, struct cloc loc,
+                                        bool_t do_validity_check,
+                                        const char *filename)
 {
-    struct rsapriv *st;
-    FILE *f;
-    cstring_t filename;
-    item_t *i;
+    struct rsapriv *st=0;
     long length;
-    uint8_t *b, *c;
+    uint8_t *b=0, *c=0;
     int cipher_type;
     MP_INT e,d,iqmp,tmp,tmp2,tmp3;
     bool_t valid;
 
+    mpz_init(&e);
+    mpz_init(&d);
+    mpz_init(&iqmp);
+    mpz_init(&tmp);
+    mpz_init(&tmp2);
+    mpz_init(&tmp3);
+
     NEW(st);
     st->cl.description="rsapriv";
     st->cl.type=CL_SIGPRIVKEY;
@@ -366,30 +371,16 @@ static list_t *rsapriv_apply(closure_t *self, struct cloc loc, dict_t *context,
     st->ops.hash=0;
     st->ops.dispose=0; /* xxx */
     st->loc=loc;
+    mpz_init(&st->n);
+    mpz_init(&st->q);
+    mpz_init(&st->p);
+    mpz_init(&st->dp);
+    mpz_init(&st->dq);
+    mpz_init(&st->w);
 
-    /* Argument is filename pointing to SSH1 private key file */
-    i=list_elem(args,0);
-    if (i) {
-       if (i->type!=t_string) {
-           cfgfatal(i->loc,"rsa-private","first argument must be a string\n");
-       }
-       filename=i->data.string;
-    } else {
-       filename=NULL; /* Make compiler happy */
-       cfgfatal(loc,"rsa-private","you must provide a filename\n");
-    }
-
-    f=fopen(filename,"rb");
     if (!f) {
-       if (just_check_config) {
-           Message(M_WARNING,"rsa-private (%s:%d): cannot open keyfile "
-                   "\"%s\"; assuming it's valid while we check the "
-                   "rest of the configuration\n",loc.file,loc.line,filename);
-           goto assume_valid;
-       } else {
-           fatal_perror("rsa-private (%s:%d): cannot open file \"%s\"",
-                        loc.file,loc.line,filename);
-       }
+       assert(just_check_config);
+       goto assume_valid;
     }
 
     /* Check that the ID string is correct */
@@ -419,7 +410,6 @@ static list_t *rsapriv_apply(closure_t *self, struct cloc loc, dict_t *context,
     if (fread(b,length,1,f) != 1) {
        LDFATAL_FILE("rsa-private","error reading modulus\n");
     }
-    mpz_init(&st->n);
     read_mpbin(&st->n,b,length);
     FREE(b);
     length=(keyfile_get_short(loc,f)+7)/8;
@@ -430,7 +420,6 @@ static list_t *rsapriv_apply(closure_t *self, struct cloc loc, dict_t *context,
     if (fread(b,length,1,f)!=1) {
        LDFATAL_FILE("rsa-private","error reading e\n");
     }
-    mpz_init(&e);
     read_mpbin(&e,b,length);
     FREE(b);
     
@@ -463,7 +452,6 @@ static list_t *rsapriv_apply(closure_t *self, struct cloc loc, dict_t *context,
        LDFATAL_FILE("rsa-private",
                           "error reading decryption key\n");
     }
-    mpz_init(&d);
     read_mpbin(&d,b,length);
     FREE(b);
     /* Read iqmp (inverse of q mod p) */
@@ -477,7 +465,6 @@ static list_t *rsapriv_apply(closure_t *self, struct cloc loc, dict_t *context,
        LDFATAL_FILE("rsa-private",
                           "error reading decryption key\n");
     }
-    mpz_init(&iqmp);
     read_mpbin(&iqmp,b,length);
     FREE(b);
     /* Read q (the smaller of the two primes) */
@@ -491,7 +478,6 @@ static list_t *rsapriv_apply(closure_t *self, struct cloc loc, dict_t *context,
        LDFATAL_FILE("rsa-private",
                           "error reading q value\n");
     }
-    mpz_init(&st->q);
     read_mpbin(&st->q,b,length);
     FREE(b);
     /* Read p (the larger of the two primes) */
@@ -505,12 +491,11 @@ static list_t *rsapriv_apply(closure_t *self, struct cloc loc, dict_t *context,
        LDFATAL_FILE("rsa-private",
                           "error reading p value\n");
     }
-    mpz_init(&st->p);
     read_mpbin(&st->p,b,length);
     FREE(b);
     
-    if (fclose(f)!=0) {
-       fatal_perror("rsa-private (%s:%d): fclose",loc.file,loc.line);
+    if (ferror(f)) {
+       fatal_perror("rsa-private (%s:%d): ferror",loc.file,loc.line);
     }
 
     /*
@@ -518,14 +503,7 @@ static list_t *rsapriv_apply(closure_t *self, struct cloc loc, dict_t *context,
      * values for fast CRT signing.
      */
     valid=False;
-    i=list_elem(args,1);
-    mpz_init(&tmp);
-    mpz_init(&tmp2);
-    mpz_init(&tmp3);
-    if (i && i->type==t_bool && i->data.bool==False) {
-       Message(M_INFO,"rsa-private (%s:%d): skipping RSA key validity "
-               "check\n",loc.file,loc.line);
-    } else {
+    if (do_validity_check) {
        /* Verify that p*q is equal to n. */
        mpz_mul(&tmp, &st->p, &st->q);
        if (mpz_cmp(&tmp, &st->n) != 0)
@@ -565,9 +543,6 @@ static list_t *rsapriv_apply(closure_t *self, struct cloc loc, dict_t *context,
      *   dq == d mod (q-1)      similarly mod q
      *   w == iqmp * q          so that w == 0 mod q, and w == 1 mod p
      */
-    mpz_init(&st->dp);
-    mpz_init(&st->dq);
-    mpz_init(&st->w);
     mpz_sub_ui(&tmp, &st->p, 1);
     mpz_mod(&st->dp, &d, &tmp);
     mpz_sub_ui(&tmp, &st->q, 1);
@@ -589,6 +564,51 @@ done_checks:
     mpz_clear(&iqmp);
 
 assume_valid:
+    return st;
+}
+
+static list_t *rsapriv_apply(closure_t *self, struct cloc loc, dict_t *context,
+                            list_t *args)
+{
+    struct rsapriv *st;
+    item_t *i;
+    cstring_t filename;
+    FILE *f;
+
+    /* Argument is filename pointing to SSH1 private key file */
+    i=list_elem(args,0);
+    if (i) {
+       if (i->type!=t_string) {
+           cfgfatal(i->loc,"rsa-private","first argument must be a string\n");
+       }
+       filename=i->data.string;
+    } else {
+       filename=NULL; /* Make compiler happy */
+       cfgfatal(i->loc,"rsa-private","you must provide a filename\n");
+    }
+
+    f=fopen(filename,"rb");
+    if (!f) {
+       if (just_check_config) {
+           Message(M_WARNING,"rsa-private (%s:%d): cannot open keyfile "
+                   "\"%s\"; assuming it's valid while we check the "
+                   "rest of the configuration\n",loc.file,loc.line,filename);
+       } else {
+           fatal_perror("rsa-private (%s:%d): cannot open file \"%s\"",
+                        loc.file,loc.line,filename);
+       }
+    }
+
+    bool_t do_validity_check=True;
+    i=list_elem(args,1);
+    if (i && i->type==t_bool && i->data.bool==False) {
+       Message(M_INFO,"rsa-private (%s:%d): skipping RSA key validity "
+               "check\n",loc.file,loc.line);
+       do_validity_check=False;
+    }
+
+    st=rsa_loadpriv_core(f,loc,do_validity_check,filename);
+    fclose(f);
     return new_closure(&st->cl);
 }