comparison keyimport.c @ 1316:2c9dac2d6707

merge 2016.74
author Matt Johnston <matt@ucc.asn.au>
date Thu, 21 Jul 2016 23:38:42 +0800
parents 750ec4ec4cbe 8678e2cc1e53
children 77c0d57a4410
comparison
equal deleted inserted replaced
1298:251c5f7a6e96 1316:2c9dac2d6707
60 char *passphrase); 60 char *passphrase);
61 61
62 static int dropbear_write(const char*filename, sign_key * key); 62 static int dropbear_write(const char*filename, sign_key * key);
63 static sign_key *dropbear_read(const char* filename); 63 static sign_key *dropbear_read(const char* filename);
64 64
65 static int toint(unsigned u);
66
65 #if 0 67 #if 0
66 static int sshcom_encrypted(const char *filename, char **comment); 68 static int sshcom_encrypted(const char *filename, char **comment);
67 static struct ssh2_userkey *sshcom_read(const char *filename, char *passphrase); 69 static struct ssh2_userkey *sshcom_read(const char *filename, char *passphrase);
68 static int sshcom_write(const char *filename, struct ssh2_userkey *key, 70 static int sshcom_write(const char *filename, struct ssh2_userkey *key,
69 char *passphrase); 71 char *passphrase);
241 243
242 *flags = (*p & 0xE0); 244 *flags = (*p & 0xE0);
243 if ((*p & 0x1F) == 0x1F) { 245 if ((*p & 0x1F) == 0x1F) {
244 *id = 0; 246 *id = 0;
245 while (*p & 0x80) { 247 while (*p & 0x80) {
246 *id = (*id << 7) | (*p & 0x7F);
247 p++, sourcelen--; 248 p++, sourcelen--;
248 if (sourcelen == 0) 249 if (sourcelen == 0)
249 return -1; 250 return -1;
250 } 251 *id = (*id << 7) | (*p & 0x7F);
251 *id = (*id << 7) | (*p & 0x7F); 252 }
252 p++, sourcelen--; 253 p++, sourcelen--;
253 } else { 254 } else {
254 *id = *p & 0x1F; 255 *id = *p & 0x1F;
255 p++, sourcelen--; 256 p++, sourcelen--;
256 } 257 }
257 258
258 if (sourcelen == 0) 259 if (sourcelen == 0)
259 return -1; 260 return -1;
260 261
261 if (*p & 0x80) { 262 if (*p & 0x80) {
263 unsigned len;
262 int n = *p & 0x7F; 264 int n = *p & 0x7F;
263 p++, sourcelen--; 265 p++, sourcelen--;
264 if (sourcelen < n) 266 if (sourcelen < n)
265 return -1; 267 return -1;
266 *length = 0; 268 len = 0;
267 while (n--) 269 while (n--)
268 *length = (*length << 8) | (*p++); 270 len = (len << 8) | (*p++);
269 sourcelen -= n; 271 sourcelen -= n;
272 *length = toint(len);
270 } else { 273 } else {
271 *length = *p; 274 *length = *p;
272 p++, sourcelen--; 275 p++, sourcelen--;
276 }
277
278 if (*length < 0) {
279 printf("Negative ASN.1 length\n");
280 return -1;
273 } 281 }
274 282
275 return p - (unsigned char *) source; 283 return p - (unsigned char *) source;
276 } 284 }
277 285
467 } 475 }
468 476
469 m_burn(buffer, sizeof(buffer)); 477 m_burn(buffer, sizeof(buffer));
470 return ret; 478 return ret;
471 479
472 error: 480 error:
473 m_burn(buffer, sizeof(buffer)); 481 m_burn(buffer, sizeof(buffer));
474 if (ret) { 482 if (ret) {
475 if (ret->keyblob) { 483 if (ret->keyblob) {
476 m_burn(ret->keyblob, ret->keyblob_size); 484 m_burn(ret->keyblob, ret->keyblob_size);
477 m_free(ret->keyblob); 485 m_free(ret->keyblob);
582 p = key->keyblob; 590 p = key->keyblob;
583 591
584 /* Expect the SEQUENCE header. Take its absence as a failure to decrypt. */ 592 /* Expect the SEQUENCE header. Take its absence as a failure to decrypt. */
585 ret = ber_read_id_len(p, key->keyblob_len, &id, &len, &flags); 593 ret = ber_read_id_len(p, key->keyblob_len, &id, &len, &flags);
586 p += ret; 594 p += ret;
587 if (ret < 0 || id != 16) { 595 if (ret < 0 || id != 16 || len < 0 ||
588 errmsg = "ASN.1 decoding failure - wrong password?"; 596 key->keyblob+key->keyblob_len-p < len) {
597 errmsg = "ASN.1 decoding failure";
589 goto error; 598 goto error;
590 } 599 }
591 600
592 /* Expect a load of INTEGERs. */ 601 /* Expect a load of INTEGERs. */
593 if (key->type == OSSH_RSA) 602 if (key->type == OSSH_RSA)
617 626
618 for (i = 0; i < num_integers; i++) { 627 for (i = 0; i < num_integers; i++) {
619 ret = ber_read_id_len(p, key->keyblob+key->keyblob_len-p, 628 ret = ber_read_id_len(p, key->keyblob+key->keyblob_len-p,
620 &id, &len, &flags); 629 &id, &len, &flags);
621 p += ret; 630 p += ret;
622 if (ret < 0 || id != 2 || 631 if (ret < 0 || id != 2 || len < 0 ||
623 key->keyblob+key->keyblob_len-p < len) { 632 key->keyblob+key->keyblob_len-p < len) {
624 errmsg = "ASN.1 decoding failure"; 633 errmsg = "ASN.1 decoding failure";
625 goto error; 634 goto error;
626 } 635 }
627 636
683 /* privateKey OCTET STRING, */ 692 /* privateKey OCTET STRING, */
684 ret = ber_read_id_len(p, key->keyblob+key->keyblob_len-p, 693 ret = ber_read_id_len(p, key->keyblob+key->keyblob_len-p,
685 &id, &len, &flags); 694 &id, &len, &flags);
686 p += ret; 695 p += ret;
687 /* id==4 for octet string */ 696 /* id==4 for octet string */
688 if (ret < 0 || id != 4 || 697 if (ret < 0 || id != 4 || len < 0 ||
689 key->keyblob+key->keyblob_len-p < len) { 698 key->keyblob+key->keyblob_len-p < len) {
690 errmsg = "ASN.1 decoding failure"; 699 errmsg = "ASN.1 decoding failure";
691 goto error; 700 goto error;
692 } 701 }
693 private_key_bytes = p; 702 private_key_bytes = p;
697 /* parameters [0] ECDomainParameters {{ SECGCurveNames }} OPTIONAL, */ 706 /* parameters [0] ECDomainParameters {{ SECGCurveNames }} OPTIONAL, */
698 ret = ber_read_id_len(p, key->keyblob+key->keyblob_len-p, 707 ret = ber_read_id_len(p, key->keyblob+key->keyblob_len-p,
699 &id, &len, &flags); 708 &id, &len, &flags);
700 p += ret; 709 p += ret;
701 /* id==0 */ 710 /* id==0 */
702 if (ret < 0 || id != 0) { 711 if (ret < 0 || id != 0 || len < 0) {
703 errmsg = "ASN.1 decoding failure"; 712 errmsg = "ASN.1 decoding failure";
704 goto error; 713 goto error;
705 } 714 }
706 715
707 ret = ber_read_id_len(p, key->keyblob+key->keyblob_len-p, 716 ret = ber_read_id_len(p, key->keyblob+key->keyblob_len-p,
708 &id, &len, &flags); 717 &id, &len, &flags);
709 p += ret; 718 p += ret;
710 /* id==6 for object */ 719 /* id==6 for object */
711 if (ret < 0 || id != 6 || 720 if (ret < 0 || id != 6 || len < 0 ||
712 key->keyblob+key->keyblob_len-p < len) { 721 key->keyblob+key->keyblob_len-p < len) {
713 errmsg = "ASN.1 decoding failure"; 722 errmsg = "ASN.1 decoding failure";
714 goto error; 723 goto error;
715 } 724 }
716 725
745 /* publicKey [1] BIT STRING OPTIONAL */ 754 /* publicKey [1] BIT STRING OPTIONAL */
746 ret = ber_read_id_len(p, key->keyblob+key->keyblob_len-p, 755 ret = ber_read_id_len(p, key->keyblob+key->keyblob_len-p,
747 &id, &len, &flags); 756 &id, &len, &flags);
748 p += ret; 757 p += ret;
749 /* id==1 */ 758 /* id==1 */
750 if (ret < 0 || id != 1) { 759 if (ret < 0 || id != 1 || len < 0) {
751 errmsg = "ASN.1 decoding failure"; 760 errmsg = "ASN.1 decoding failure";
752 goto error; 761 goto error;
753 } 762 }
754 763
755 ret = ber_read_id_len(p, key->keyblob+key->keyblob_len-p, 764 ret = ber_read_id_len(p, key->keyblob+key->keyblob_len-p,
756 &id, &len, &flags); 765 &id, &len, &flags);
757 p += ret; 766 p += ret;
758 /* id==3 for bit string */ 767 /* id==3 for bit string */
759 if (ret < 0 || id != 3 || 768 if (ret < 0 || id != 3 || len < 0 ||
760 key->keyblob+key->keyblob_len-p < len) { 769 key->keyblob+key->keyblob_len-p < len) {
761 errmsg = "ASN.1 decoding failure"; 770 errmsg = "ASN.1 decoding failure";
762 goto error; 771 goto error;
763 } 772 }
764 public_key_bytes = p+1; 773 public_key_bytes = p+1;
1379 if (ret) { 1388 if (ret) {
1380 if (ret->keyblob) { 1389 if (ret->keyblob) {
1381 memset(ret->keyblob, 0, ret->keyblob_size); 1390 memset(ret->keyblob, 0, ret->keyblob_size);
1382 m_free(ret->keyblob); 1391 m_free(ret->keyblob);
1383 } 1392 }
1384 memset(&ret, 0, sizeof(ret)); 1393 memset(ret, 0, sizeof(*ret));
1385 m_free(ret); 1394 m_free(ret);
1386 } 1395 }
1387 return NULL; 1396 return NULL;
1388 } 1397 }
1389 1398
1407 */ 1416 */
1408 answer = 0; 1417 answer = 0;
1409 pos = 8; 1418 pos = 8;
1410 if (key->keyblob_len < pos+4) 1419 if (key->keyblob_len < pos+4)
1411 goto done; /* key is far too short */ 1420 goto done; /* key is far too short */
1412 pos += 4 + GET_32BIT(key->keyblob + pos); /* skip key type */ 1421 len = toint(GET_32BIT(key->keyblob + pos));
1413 if (key->keyblob_len < pos+4) 1422 if (len < 0 || len > key->keyblob_len - pos - 4)
1414 goto done; /* key is far too short */ 1423 goto done; /* key is far too short */
1415 len = GET_32BIT(key->keyblob + pos); /* find cipher-type length */ 1424 pos += 4 + len; /* skip key type */
1416 if (key->keyblob_len < pos+4+len) 1425 len = toint(GET_32BIT(key->keyblob + pos)); /* find cipher-type length */
1426 if (len < 0 || len > key->keyblob_len - pos - 4)
1417 goto done; /* cipher type string is incomplete */ 1427 goto done; /* cipher type string is incomplete */
1418 if (len != 4 || 0 != memcmp(key->keyblob + pos + 4, "none", 4)) 1428 if (len != 4 || 0 != memcmp(key->keyblob + pos + 4, "none", 4))
1419 answer = 1; 1429 answer = 1;
1420 1430
1421 done: 1431 done:
1422 *comment = dupstr(key->comment); 1432 *comment = dupstr(key->comment);
1423 memset(key->keyblob, 0, key->keyblob_size); 1433 memset(key->keyblob, 0, key->keyblob_size);
1424 m_free(key->keyblob); 1434 m_free(key->keyblob);
1425 memset(&key, 0, sizeof(key)); 1435 memset(key, 0, sizeof(*key));
1426 m_free(key); 1436 m_free(key);
1427 return answer; 1437 return answer;
1428 } 1438 }
1429 1439
1430 static int sshcom_read_mpint(void *data, int len, struct mpint_pos *ret) 1440 static int sshcom_read_mpint(void *data, int len, struct mpint_pos *ret)
1431 { 1441 {
1432 int bits; 1442 unsigned bits, bytes;
1433 int bytes;
1434 unsigned char *d = (unsigned char *) data; 1443 unsigned char *d = (unsigned char *) data;
1435 1444
1436 if (len < 4) 1445 if (len < 4)
1437 goto error; 1446 goto error;
1438 bits = GET_32BIT(d); 1447 bits = GET_32BIT(d);
1481 char *ciphertext; 1490 char *ciphertext;
1482 int cipherlen; 1491 int cipherlen;
1483 struct ssh2_userkey *ret = NULL, *retkey; 1492 struct ssh2_userkey *ret = NULL, *retkey;
1484 const struct ssh_signkey *alg; 1493 const struct ssh_signkey *alg;
1485 unsigned char *blob = NULL; 1494 unsigned char *blob = NULL;
1486 int blobsize, publen, privlen; 1495 int blobsize = 0, publen, privlen;
1487 1496
1488 if (!key) 1497 if (!key)
1489 return NULL; 1498 return NULL;
1490 1499
1491 /* 1500 /*
1601 } 1610 }
1602 1611
1603 /* 1612 /*
1604 * Strip away the containing string to get to the real meat. 1613 * Strip away the containing string to get to the real meat.
1605 */ 1614 */
1606 len = GET_32BIT(ciphertext); 1615 len = toint(GET_32BIT(ciphertext));
1607 if (len > cipherlen-4) { 1616 if (len < 0 || len > cipherlen-4) {
1608 errmsg = "containing string was ill-formed"; 1617 errmsg = "containing string was ill-formed";
1609 goto error; 1618 goto error;
1610 } 1619 }
1611 ciphertext += 4; 1620 ciphertext += 4;
1612 cipherlen = len; 1621 cipherlen = len;
1669 pos += put_mp(blob+pos, g.start, g.bytes); 1678 pos += put_mp(blob+pos, g.start, g.bytes);
1670 pos += put_mp(blob+pos, y.start, y.bytes); 1679 pos += put_mp(blob+pos, y.start, y.bytes);
1671 publen = pos; 1680 publen = pos;
1672 pos += put_mp(blob+pos, x.start, x.bytes); 1681 pos += put_mp(blob+pos, x.start, x.bytes);
1673 privlen = pos - publen; 1682 privlen = pos - publen;
1674 } 1683 } else
1684 return NULL;
1675 1685
1676 dropbear_assert(privlen > 0); /* should have bombed by now if not */ 1686 dropbear_assert(privlen > 0); /* should have bombed by now if not */
1677 1687
1678 retkey = snew(struct ssh2_userkey); 1688 retkey = snew(struct ssh2_userkey);
1679 retkey->alg = alg; 1689 retkey->alg = alg;
1693 memset(blob, 0, blobsize); 1703 memset(blob, 0, blobsize);
1694 m_free(blob); 1704 m_free(blob);
1695 } 1705 }
1696 memset(key->keyblob, 0, key->keyblob_size); 1706 memset(key->keyblob, 0, key->keyblob_size);
1697 m_free(key->keyblob); 1707 m_free(key->keyblob);
1698 memset(&key, 0, sizeof(key)); 1708 memset(key, 0, sizeof(*key));
1699 m_free(key); 1709 m_free(key);
1700 return ret; 1710 return ret;
1701 } 1711 }
1702 1712
1703 int sshcom_write(const char *filename, sign_key *key, 1713 int sshcom_write(const char *filename, sign_key *key,
1906 m_free(pubblob); 1916 m_free(pubblob);
1907 } 1917 }
1908 return ret; 1918 return ret;
1909 } 1919 }
1910 #endif /* ssh.com stuff disabled */ 1920 #endif /* ssh.com stuff disabled */
1921
1922 /* From PuTTY misc.c */
1923 static int toint(unsigned u)
1924 {
1925 /*
1926 * Convert an unsigned to an int, without running into the
1927 * undefined behaviour which happens by the strict C standard if
1928 * the value overflows. You'd hope that sensible compilers would
1929 * do the sensible thing in response to a cast, but actually I
1930 * don't trust modern compilers not to do silly things like
1931 * assuming that _obviously_ you wouldn't have caused an overflow
1932 * and so they can elide an 'if (i < 0)' test immediately after
1933 * the cast.
1934 *
1935 * Sensible compilers ought of course to optimise this entire
1936 * function into 'just return the input value'!
1937 */
1938 if (u <= (unsigned)INT_MAX)
1939 return (int)u;
1940 else if (u >= (unsigned)INT_MIN) /* wrap in cast _to_ unsigned is OK */
1941 return INT_MIN + (int)(u - (unsigned)INT_MIN);
1942 else
1943 return INT_MIN; /* fallback; should never occur on binary machines */
1944 }