]> asedeno.scripts.mit.edu Git - PuTTY.git/blobdiff - sshrsa.c
Const-correctness in public-key functions.
[PuTTY.git] / sshrsa.c
index 3bd971f8d0516ec7e194dba9a8446f907c919993..3adccfbef1d43eb9fc0787b7e7537ca26d60488a 100644 (file)
--- a/sshrsa.c
+++ b/sshrsa.c
 #include "ssh.h"
 #include "misc.h"
 
-int makekey(unsigned char *data, int len, struct RSAKey *result,
-           unsigned char **keystr, int order)
+int makekey(const unsigned char *data, int len, struct RSAKey *result,
+           const unsigned char **keystr, int order)
 {
-    unsigned char *p = data;
+    const unsigned char *p = data;
     int i, n;
 
     if (len < 4)
@@ -59,7 +59,7 @@ int makekey(unsigned char *data, int len, struct RSAKey *result,
     return p - data;
 }
 
-int makeprivate(unsigned char *data, int len, struct RSAKey *result)
+int makeprivate(const unsigned char *data, int len, struct RSAKey *result)
 {
     return ssh1_read_bignum(data, len, &result->private_exponent);
 }
@@ -264,6 +264,7 @@ static Bignum rsa_privkey_op(Bignum input, struct RSAKey *key)
            bitsleft--;
            bignum_set_bit(random, bits, v);
        }
+        bn_restore_invariant(random);
 
        /*
         * Now check that this number is strictly greater than
@@ -273,9 +274,18 @@ static Bignum rsa_privkey_op(Bignum input, struct RSAKey *key)
            bignum_cmp(random, key->modulus) >= 0) {
            freebn(random);
            continue;
-       } else {
-           break;
        }
+
+        /*
+         * Also, make sure it has an inverse mod modulus.
+         */
+        random_inverse = modinv(random, key->modulus);
+        if (!random_inverse) {
+           freebn(random);
+           continue;
+        }
+
+        break;
     }
 
     /*
@@ -294,7 +304,6 @@ static Bignum rsa_privkey_op(Bignum input, struct RSAKey *key)
      */
     random_encrypted = crt_modpow(random, key->exponent,
                                   key->modulus, key->p, key->q, key->iqmp);
-    random_inverse = modinv(random, key->modulus);
     input_blinded = modmul(input, random_encrypted, key->modulus);
     ret_blinded = crt_modpow(input_blinded, key->private_exponent,
                              key->modulus, key->p, key->q, key->iqmp);
@@ -443,6 +452,8 @@ int rsa_verify(struct RSAKey *key)
 
        freebn(key->iqmp);
        key->iqmp = modinv(key->q, key->p);
+        if (!key->iqmp)
+            return 0;
     }
 
     /*
@@ -522,7 +533,8 @@ void freersakey(struct RSAKey *key)
  * Implementation of the ssh-rsa signing key type. 
  */
 
-static void getstring(char **data, int *datalen, char **p, int *length)
+static void getstring(const char **data, int *datalen,
+                      const char **p, int *length)
 {
     *p = NULL;
     if (*datalen < 4)
@@ -538,9 +550,9 @@ static void getstring(char **data, int *datalen, char **p, int *length)
     *data += *length;
     *datalen -= *length;
 }
-static Bignum getmp(char **data, int *datalen)
+static Bignum getmp(const char **data, int *datalen)
 {
-    char *p;
+    const char *p;
     int length;
     Bignum b;
 
@@ -551,9 +563,11 @@ static Bignum getmp(char **data, int *datalen)
     return b;
 }
 
-static void *rsa2_newkey(char *data, int len)
+static void rsa2_freekey(void *key);   /* forward reference */
+
+static void *rsa2_newkey(const char *data, int len)
 {
-    char *p;
+    const char *p;
     int slen;
     struct RSAKey *rsa;
 
@@ -570,6 +584,11 @@ static void *rsa2_newkey(char *data, int len)
     rsa->p = rsa->q = rsa->iqmp = NULL;
     rsa->comment = NULL;
 
+    if (!rsa->exponent || !rsa->modulus) {
+        rsa2_freekey(rsa);
+        return NULL;
+    }
+
     return rsa;
 }
 
@@ -666,11 +685,11 @@ static unsigned char *rsa2_private_blob(void *key, int *len)
     return blob;
 }
 
-static void *rsa2_createkey(unsigned char *pub_blob, int pub_len,
-                           unsigned char *priv_blob, int priv_len)
+static void *rsa2_createkey(const unsigned char *pub_blob, int pub_len,
+                           const unsigned char *priv_blob, int priv_len)
 {
     struct RSAKey *rsa;
-    char *pb = (char *) priv_blob;
+    const char *pb = (const char *) priv_blob;
 
     rsa = rsa2_newkey((char *) pub_blob, pub_len);
     rsa->private_exponent = getmp(&pb, &priv_len);
@@ -686,9 +705,9 @@ static void *rsa2_createkey(unsigned char *pub_blob, int pub_len,
     return rsa;
 }
 
-static void *rsa2_openssh_createkey(unsigned char **blob, int *len)
+static void *rsa2_openssh_createkey(const unsigned char **blob, int *len)
 {
-    char **b = (char **) blob;
+    const char **b = (const char **) blob;
     struct RSAKey *rsa;
 
     rsa = snew(struct RSAKey);
@@ -744,12 +763,12 @@ static int rsa2_openssh_fmtkey(void *key, unsigned char *blob, int len)
     return bloblen;
 }
 
-static int rsa2_pubkey_bits(void *blob, int len)
+static int rsa2_pubkey_bits(const void *blob, int len)
 {
     struct RSAKey *rsa;
     int ret;
 
-    rsa = rsa2_newkey((char *) blob, len);
+    rsa = rsa2_newkey((const char *) blob, len);
     ret = bignum_bitcount(rsa->modulus);
     rsa2_freekey(rsa);
 
@@ -822,12 +841,12 @@ static const unsigned char asn1_weird_stuff[] = {
 
 #define ASN1_LEN ( (int) sizeof(asn1_weird_stuff) )
 
-static int rsa2_verifysig(void *key, char *sig, int siglen,
-                         char *data, int datalen)
+static int rsa2_verifysig(void *key, const char *sig, int siglen,
+                         const char *data, int datalen)
 {
     struct RSAKey *rsa = (struct RSAKey *) key;
     Bignum in, out;
-    char *p;
+    const char *p;
     int slen;
     int bytes, i, j, ret;
     unsigned char hash[20];
@@ -872,7 +891,7 @@ static int rsa2_verifysig(void *key, char *sig, int siglen,
     return ret;
 }
 
-static unsigned char *rsa2_sign(void *key, char *data, int datalen,
+static unsigned char *rsa2_sign(void *key, const char *data, int datalen,
                                int *siglen)
 {
     struct RSAKey *rsa = (struct RSAKey *) key;
@@ -924,6 +943,7 @@ const struct ssh_signkey ssh_rsa = {
     rsa2_createkey,
     rsa2_openssh_createkey,
     rsa2_openssh_fmtkey,
+    6 /* n,e,d,iqmp,q,p */,
     rsa2_pubkey_bits,
     rsa2_fingerprint,
     rsa2_verifysig,