X-Git-Url: https://git.distorted.org.uk/~mdw/sgt/putty/blobdiff_plain/9febf7ed49d2d2f13d9addc7714acd492c2c7111..434725096984264473fc977bc1f85db7191ce103:/sshdss.c diff --git a/sshdss.c b/sshdss.c index 2b19a921..bf6c3ba5 100644 --- a/sshdss.c +++ b/sshdss.c @@ -82,6 +82,8 @@ static Bignum get160(char **data, int *datalen) return b; } +static void dss_freekey(void *key); /* forward reference */ + static void *dss_newkey(char *data, int len) { char *p; @@ -89,8 +91,6 @@ static void *dss_newkey(char *data, int len) struct dss_key *dss; dss = snew(struct dss_key); - if (!dss) - return NULL; getstring(&data, &len, &p, &slen); #ifdef DEBUG_DSS @@ -111,6 +111,14 @@ static void *dss_newkey(char *data, int len) dss->q = getmp(&data, &len); dss->g = getmp(&data, &len); dss->y = getmp(&data, &len); + dss->x = NULL; + + if (!dss->p || !dss->q || !dss->g || !dss->y || + !bignum_cmp(dss->q, Zero) || !bignum_cmp(dss->p, Zero)) { + /* Invalid key. */ + dss_freekey(dss); + return NULL; + } return dss; } @@ -118,10 +126,16 @@ static void *dss_newkey(char *data, int len) static void dss_freekey(void *key) { struct dss_key *dss = (struct dss_key *) key; - freebn(dss->p); - freebn(dss->q); - freebn(dss->g); - freebn(dss->y); + if (dss->p) + freebn(dss->p); + if (dss->q) + freebn(dss->q); + if (dss->g) + freebn(dss->g); + if (dss->y) + freebn(dss->y); + if (dss->x) + freebn(dss->x); sfree(dss); } @@ -254,8 +268,13 @@ static int dss_verifysig(void *key, char *sig, int siglen, } r = get160(&sig, &siglen); s = get160(&sig, &siglen); - if (!r || !s) + if (!r || !s) { + if (r) + freebn(r); + if (s) + freebn(s); return 0; + } /* * Step 1. w <- s^-1 mod q. @@ -384,7 +403,13 @@ static void *dss_createkey(unsigned char *pub_blob, int pub_len, Bignum ytest; dss = dss_newkey((char *) pub_blob, pub_len); + if (!dss) + return NULL; dss->x = getmp(&pb, &priv_len); + if (!dss->x) { + dss_freekey(dss); + return NULL; + } /* * Check the obsolete hash in the old DSS key format. @@ -423,8 +448,6 @@ static void *dss_openssh_createkey(unsigned char **blob, int *len) struct dss_key *dss; dss = snew(struct dss_key); - if (!dss) - return NULL; dss->p = getmp(b, len); dss->q = getmp(b, len); @@ -432,14 +455,11 @@ static void *dss_openssh_createkey(unsigned char **blob, int *len) dss->y = getmp(b, len); dss->x = getmp(b, len); - if (!dss->p || !dss->q || !dss->g || !dss->y || !dss->x) { - sfree(dss->p); - sfree(dss->q); - sfree(dss->g); - sfree(dss->y); - sfree(dss->x); - sfree(dss); - return NULL; + if (!dss->p || !dss->q || !dss->g || !dss->y || !dss->x || + !bignum_cmp(dss->q, Zero) || !bignum_cmp(dss->p, Zero)) { + /* Invalid key. */ + dss_freekey(dss); + return NULL; } return dss; @@ -479,6 +499,8 @@ static int dss_pubkey_bits(void *blob, int len) int ret; dss = dss_newkey((char *) blob, len); + if (!dss) + return -1; ret = bignum_bitcount(dss->p); dss_freekey(dss); @@ -607,6 +629,7 @@ static unsigned char *dss_sign(void *key, char *data, int datalen, int *siglen) s = modmul(kinv, hxr, dss->q); /* s = k^-1 * (hash + x*r) mod q */ freebn(hxr); freebn(kinv); + freebn(k); freebn(hash); /*