From: simon Date: Tue, 3 Oct 2000 09:05:56 +0000 (+0000) Subject: Work around DSA formatting bug in commercial-SSH 2.0.13 X-Git-Url: https://git.distorted.org.uk/u/mdw/putty/commitdiff_plain/7f7837c88158367256d3ae71bca717c8c2ef4825?hp=4c73ca1f3ee28245459d5c9ef36e25c549191952 Work around DSA formatting bug in commercial-SSH 2.0.13 git-svn-id: svn://svn.tartarus.org/sgt/putty@665 cda61777-01e9-0310-a592-d414129be87e --- diff --git a/sshdss.c b/sshdss.c index 2a5e2689..01c452b9 100644 --- a/sshdss.c +++ b/sshdss.c @@ -161,11 +161,24 @@ static int dss_verifysig(char *sig, int siglen, char *data, int datalen) { if (!dss_p) return 0; - getstring(&sig, &siglen, &p, &slen); - if (!p || memcmp(p, "ssh-dss", 7)) { - return 0; + /* + * Commercial SSH (2.0.13) and OpenSSH disagree over the format + * of a DSA signature. OpenSSH is in line with the IETF drafts: + * it uses a string "ssh-dss", followed by a 40-byte string + * containing two 160-bit integers end-to-end. Commercial SSH + * can't be bothered with the header bit, and considers a DSA + * signature blob to be _just_ the 40-byte string containing + * the two 160-bit integers. We tell them apart by measuring + * the length: length 40 means the commercial-SSH bug, anything + * else is assumed to be IETF-compliant. + */ + if (siglen != 40) { /* bug not present; read admin fields */ + getstring(&sig, &siglen, &p, &slen); + if (!p || memcmp(p, "ssh-dss", 7)) { + return 0; + } + sig += 4, siglen -= 4; /* skip yet another length field */ } - sig += 4, siglen -= 4; /* skip yet another length field */ r = get160(&sig, &siglen); s = get160(&sig, &siglen); if (!r || !s)