static void *dss_createkey(unsigned char *pub_blob, int pub_len, unsigned char *priv_blob, int priv_len) { dss_key *dss; char *pb = (char *) priv_blob; char *hash; int hashlen; SHA_State s; unsigned char digest[20]; 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. */ hashlen = -1; getstring(&pb, &priv_len, &hash, &hashlen); if (hashlen == 20) { SHA_Init(&s); sha_mpint(&s, dss->p); sha_mpint(&s, dss->q); sha_mpint(&s, dss->g); SHA_Final(&s, digest); if (0 != memcmp(hash, digest, 20)) { dss_freekey(dss); return NULL; } } /* * Now ensure g^x mod p really is y. */ ytest = modpow(dss->g, dss->x, dss->p); if (0 != bignum_cmp(ytest, dss->y)) { dss_freekey(dss); freebn(ytest); return NULL; } freebn(ytest); return dss; }
static int dss_pubkey_bits(void *blob, int len) { struct dss_key *dss; int ret; dss = dss_newkey((char *) blob, len); ret = bignum_bitcount(dss->p); dss_freekey(dss); return ret; }
static void *dss_newkey(char *data, int len) { char *p; int slen; dss_key *dss; dss = snewn(1,dss_key); getstring(&data, &len, &p, &slen); #ifdef DEBUG_DSS { int i; printf("key:"); for (i = 0; i < len; i++) printf(" %02x", (unsigned char) (data[i])); printf("\n"); } #endif if (!p || slen != 7 || memcmp(p, "ssh-dss", 7)) { sfree(dss); return NULL; } dss->p = getmp(&data, &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; }
static void *dss_openssh_createkey(unsigned char **blob, int *len) { char **b = (char **) blob; struct dss_key *dss; dss = snew(struct dss_key); dss->p = getmp(b, len); dss->q = getmp(b, len); dss->g = getmp(b, len); dss->y = getmp(b, len); dss->x = getmp(b, len); 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; }