X-Git-Url: https://asedeno.scripts.mit.edu/gitweb/?a=blobdiff_plain;f=import.c;h=340785bdbd6000aead4857bd31dea4cad4aa5c02;hb=15386cbe927fc85ac2fed0bb47704645c4b67dad;hp=ed57add09fc85186bc331b5aab2bdd3255d9b70b;hpb=7db526c7306a12d86bff9ce1de00e9838987c0af;p=PuTTY.git diff --git a/import.c b/import.c index ed57add0..340785bd 100644 --- a/import.c +++ b/import.c @@ -195,14 +195,16 @@ static int ber_read_id_len(void *source, int sourcelen, return -1; if (*p & 0x80) { + unsigned len; int n = *p & 0x7F; p++, sourcelen--; if (sourcelen < n) return -1; - *length = 0; + len = 0; while (n--) - *length = (*length << 8) | (*p++); + len = (len << 8) | (*p++); sourcelen -= n; + *length = toint(len); } else { *length = *p; p++, sourcelen--; @@ -362,7 +364,8 @@ static struct openssh_pem_key *load_openssh_pem_key(const Filename *filename, struct openssh_pem_key *ret; FILE *fp = NULL; char *line = NULL; - char *errmsg, *p; + const char *errmsg; + char *p; int headers_done; char base64_bit[4]; int base64_chars = 0; @@ -382,8 +385,8 @@ static struct openssh_pem_key *load_openssh_pem_key(const Filename *filename, goto error; } strip_crlf(line); - if (0 != strncmp(line, "-----BEGIN ", 11) || - 0 != strcmp(line+strlen(line)-16, "PRIVATE KEY-----")) { + if (!strstartswith(line, "-----BEGIN ") || + !strendswith(line, "PRIVATE KEY-----")) { errmsg = "file does not begin with OpenSSH key header"; goto error; } @@ -420,8 +423,8 @@ static struct openssh_pem_key *load_openssh_pem_key(const Filename *filename, goto error; } strip_crlf(line); - if (0 == strncmp(line, "-----END ", 9) && - 0 == strcmp(line+strlen(line)-16, "PRIVATE KEY-----")) { + if (strstartswith(line, "-----END ") && + strendswith(line, "PRIVATE KEY-----")) { sfree(line); line = NULL; break; /* done */ @@ -570,7 +573,7 @@ struct ssh2_userkey *openssh_pem_read(const Filename *filename, int ret, id, len, flags; int i, num_integers; struct ssh2_userkey *retval = NULL; - char *errmsg; + const char *errmsg; unsigned char *blob; int blobsize = 0, blobptr, privptr; char *modptr = NULL; @@ -656,7 +659,8 @@ struct ssh2_userkey *openssh_pem_read(const Filename *filename, * decrypt, if the key was encrypted. */ ret = ber_read_id_len(p, key->keyblob_len, &id, &len, &flags); p += ret; - if (ret < 0 || id != 16) { + if (ret < 0 || id != 16 || len < 0 || + key->keyblob+key->keyblob_len-p < len) { errmsg = "ASN.1 decoding failure"; retval = key->encrypted ? SSH2_WRONG_PASSPHRASE : NULL; goto error; @@ -682,8 +686,8 @@ struct ssh2_userkey *openssh_pem_read(const Filename *filename, ret = ber_read_id_len(p, key->keyblob+key->keyblob_len-p, &id, &len, &flags); p += ret; - if (ret < 0 || id != 2 || key->keyblob+key->keyblob_len-p < len || - len != 1 || p[0] != 1) { + if (ret < 0 || id != 2 || len != 1 || + key->keyblob+key->keyblob_len-p < len || p[0] != 1) { errmsg = "ASN.1 decoding failure"; retval = key->encrypted ? SSH2_WRONG_PASSPHRASE : NULL; goto error; @@ -693,7 +697,8 @@ struct ssh2_userkey *openssh_pem_read(const Filename *filename, ret = ber_read_id_len(p, key->keyblob+key->keyblob_len-p, &id, &len, &flags); p += ret; - if (ret < 0 || id != 4 || key->keyblob+key->keyblob_len-p < len) { + if (ret < 0 || id != 4 || len < 0 || + key->keyblob+key->keyblob_len-p < len) { errmsg = "ASN.1 decoding failure"; retval = key->encrypted ? SSH2_WRONG_PASSPHRASE : NULL; goto error; @@ -705,7 +710,8 @@ struct ssh2_userkey *openssh_pem_read(const Filename *filename, ret = ber_read_id_len(p, key->keyblob+key->keyblob_len-p, &id, &len, &flags); p += ret; - if (ret < 0 || id != 0 || key->keyblob+key->keyblob_len-p < len) { + if (ret < 0 || id != 0 || len < 0 || + key->keyblob+key->keyblob_len-p < len) { errmsg = "ASN.1 decoding failure"; retval = key->encrypted ? SSH2_WRONG_PASSPHRASE : NULL; goto error; @@ -713,7 +719,8 @@ struct ssh2_userkey *openssh_pem_read(const Filename *filename, ret = ber_read_id_len(p, key->keyblob+key->keyblob_len-p, &id, &len, &flags); p += ret; - if (ret < 0 || id != 6 || key->keyblob+key->keyblob_len-p < len) { + if (ret < 0 || id != 6 || len < 0 || + key->keyblob+key->keyblob_len-p < len) { errmsg = "ASN.1 decoding failure"; retval = key->encrypted ? SSH2_WRONG_PASSPHRASE : NULL; goto error; @@ -729,7 +736,8 @@ struct ssh2_userkey *openssh_pem_read(const Filename *filename, ret = ber_read_id_len(p, key->keyblob+key->keyblob_len-p, &id, &len, &flags); p += ret; - if (ret < 0 || id != 1 || key->keyblob+key->keyblob_len-p < len) { + if (ret < 0 || id != 1 || len < 0 || + key->keyblob+key->keyblob_len-p < len) { errmsg = "ASN.1 decoding failure"; retval = key->encrypted ? SSH2_WRONG_PASSPHRASE : NULL; goto error; @@ -737,7 +745,8 @@ struct ssh2_userkey *openssh_pem_read(const Filename *filename, ret = ber_read_id_len(p, key->keyblob+key->keyblob_len-p, &id, &len, &flags); p += ret; - if (ret < 0 || id != 3 || key->keyblob+key->keyblob_len-p < len || + if (ret < 0 || id != 3 || len < 0 || + key->keyblob+key->keyblob_len-p < len || len != ((((curve->fieldBits + 7) / 8) * 2) + 2)) { errmsg = "ASN.1 decoding failure"; retval = key->encrypted ? SSH2_WRONG_PASSPHRASE : NULL; @@ -752,7 +761,7 @@ struct ssh2_userkey *openssh_pem_read(const Filename *filename, goto error; } retkey->alg = alg; - blob = snewn((4+19 + 4+8 + 4+len) + (4+privlen), unsigned char); + blob = snewn((4+19 + 4+8 + 4+len) + (4+1+privlen), unsigned char); if (!blob) { sfree(retkey); errmsg = "out of memory"; @@ -772,12 +781,20 @@ struct ssh2_userkey *openssh_pem_read(const Filename *filename, PUT_32BIT(q, len); q += 4; memcpy(q, p, len); q += len; - PUT_32BIT(q, privlen); - memcpy(q+4, priv, privlen); + /* + * To be acceptable to our createkey(), the private blob must + * contain a valid mpint, i.e. without the top bit set. But + * the input private string may have the top bit set, so we + * prefix a zero byte to ensure createkey() doesn't fail for + * that reason. + */ + PUT_32BIT(q, privlen+1); + q[4] = 0; + memcpy(q+5, priv, privlen); retkey->data = retkey->alg->createkey(retkey->alg, blob, q-blob, - q, 4+privlen); + q, 5+privlen); if (!retkey->data) { sfree(retkey); @@ -804,7 +821,7 @@ struct ssh2_userkey *openssh_pem_read(const Filename *filename, ret = ber_read_id_len(p, key->keyblob+key->keyblob_len-p, &id, &len, &flags); p += ret; - if (ret < 0 || id != 2 || + if (ret < 0 || id != 2 || len < 0 || key->keyblob+key->keyblob_len-p < len) { errmsg = "ASN.1 decoding failure"; retval = key->encrypted ? SSH2_WRONG_PASSPHRASE : NULL; @@ -877,6 +894,8 @@ struct ssh2_userkey *openssh_pem_read(const Filename *filename, } else { assert(0 && "Bad key type from load_openssh_pem_key"); + errmsg = "Bad key type from load_openssh_pem_key"; + goto error; } /* @@ -910,7 +929,7 @@ int openssh_pem_write(const Filename *filename, struct ssh2_userkey *key, int outlen; struct mpint_pos numbers[9]; int nnumbers, pos, len, seqlen, i; - char *header, *footer; + const char *header, *footer; char zero[1]; unsigned char iv[8]; int ret = 0; @@ -1283,7 +1302,8 @@ static struct openssh_new_key *load_openssh_new_key(const Filename *filename, struct openssh_new_key *ret; FILE *fp = NULL; char *line = NULL; - char *errmsg, *p; + const char *errmsg; + char *p; char base64_bit[4]; int base64_chars = 0; const void *filedata; @@ -1526,7 +1546,7 @@ struct ssh2_userkey *openssh_new_read(const Filename *filename, struct ssh2_userkey *retkey; int i; struct ssh2_userkey *retval = NULL; - char *errmsg; + const char *errmsg; unsigned char *blob; int blobsize = 0; unsigned checkint0, checkint1; @@ -1981,7 +2001,8 @@ static struct sshcom_key *load_sshcom_key(const Filename *filename, FILE *fp; char *line = NULL; int hdrstart, len; - char *errmsg, *p; + const char *errmsg; + char *p; int headers_done; char base64_bit[4]; int base64_chars = 0; @@ -2226,7 +2247,7 @@ struct ssh2_userkey *sshcom_read(const Filename *filename, char *passphrase, const char **errmsg_p) { struct sshcom_key *key = load_sshcom_key(filename, errmsg_p); - char *errmsg; + const char *errmsg; int pos, len; const char prefix_rsa[] = "if-modn{sign{rsa"; const char prefix_dsa[] = "dl-modp{sign{dsa"; @@ -2470,7 +2491,7 @@ int sshcom_write(const Filename *filename, struct ssh2_userkey *key, int outlen; struct mpint_pos numbers[6]; int nnumbers, initial_zero, pos, lenpos, i; - char *type; + const char *type; char *ciphertext; int cipherlen; int ret = 0; @@ -2566,7 +2587,7 @@ int sshcom_write(const Filename *filename, struct ssh2_userkey *key, pos += 4; /* length field, fill in later */ pos += put_string(outblob+pos, type, strlen(type)); { - char *ciphertype = passphrase ? "3des-cbc" : "none"; + const char *ciphertype = passphrase ? "3des-cbc" : "none"; pos += put_string(outblob+pos, ciphertype, strlen(ciphertype)); } lenpos = pos; /* remember this position */