comparison keyimport.c @ 1318:10e2a7727253 coverity

merge coverity
author Matt Johnston <matt@ucc.asn.au>
date Fri, 22 Jul 2016 00:08:02 +0800
parents 2c9dac2d6707
children 77c0d57a4410
comparison
equal deleted inserted replaced
1286:7d02b83c61fd 1318:10e2a7727253
34 #include "bignum.h" 34 #include "bignum.h"
35 #include "buffer.h" 35 #include "buffer.h"
36 #include "dbutil.h" 36 #include "dbutil.h"
37 #include "ecc.h" 37 #include "ecc.h"
38 38
39 #if DROPBEAR_ECDSA
39 static const unsigned char OID_SEC256R1_BLOB[] = {0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07}; 40 static const unsigned char OID_SEC256R1_BLOB[] = {0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07};
40 static const unsigned char OID_SEC384R1_BLOB[] = {0x2b, 0x81, 0x04, 0x00, 0x22}; 41 static const unsigned char OID_SEC384R1_BLOB[] = {0x2b, 0x81, 0x04, 0x00, 0x22};
41 static const unsigned char OID_SEC521R1_BLOB[] = {0x2b, 0x81, 0x04, 0x00, 0x23}; 42 static const unsigned char OID_SEC521R1_BLOB[] = {0x2b, 0x81, 0x04, 0x00, 0x23};
43 #endif
42 44
43 #define PUT_32BIT(cp, value) do { \ 45 #define PUT_32BIT(cp, value) do { \
44 (cp)[3] = (unsigned char)(value); \ 46 (cp)[3] = (unsigned char)(value); \
45 (cp)[2] = (unsigned char)((value) >> 8); \ 47 (cp)[2] = (unsigned char)((value) >> 8); \
46 (cp)[1] = (unsigned char)((value) >> 16); \ 48 (cp)[1] = (unsigned char)((value) >> 16); \
57 static int openssh_write(const char *filename, sign_key *key, 59 static int openssh_write(const char *filename, sign_key *key,
58 char *passphrase); 60 char *passphrase);
59 61
60 static int dropbear_write(const char*filename, sign_key * key); 62 static int dropbear_write(const char*filename, sign_key * key);
61 static sign_key *dropbear_read(const char* filename); 63 static sign_key *dropbear_read(const char* filename);
64
65 static int toint(unsigned u);
62 66
63 #if 0 67 #if 0
64 static int sshcom_encrypted(const char *filename, char **comment); 68 static int sshcom_encrypted(const char *filename, char **comment);
65 static struct ssh2_userkey *sshcom_read(const char *filename, char *passphrase); 69 static struct ssh2_userkey *sshcom_read(const char *filename, char *passphrase);
66 static int sshcom_write(const char *filename, struct ssh2_userkey *key, 70 static int sshcom_write(const char *filename, struct ssh2_userkey *key,
239 243
240 *flags = (*p & 0xE0); 244 *flags = (*p & 0xE0);
241 if ((*p & 0x1F) == 0x1F) { 245 if ((*p & 0x1F) == 0x1F) {
242 *id = 0; 246 *id = 0;
243 while (*p & 0x80) { 247 while (*p & 0x80) {
244 *id = (*id << 7) | (*p & 0x7F);
245 p++, sourcelen--; 248 p++, sourcelen--;
246 if (sourcelen == 0) 249 if (sourcelen == 0)
247 return -1; 250 return -1;
248 } 251 *id = (*id << 7) | (*p & 0x7F);
249 *id = (*id << 7) | (*p & 0x7F); 252 }
250 p++, sourcelen--; 253 p++, sourcelen--;
251 } else { 254 } else {
252 *id = *p & 0x1F; 255 *id = *p & 0x1F;
253 p++, sourcelen--; 256 p++, sourcelen--;
254 } 257 }
255 258
256 if (sourcelen == 0) 259 if (sourcelen == 0)
257 return -1; 260 return -1;
258 261
259 if (*p & 0x80) { 262 if (*p & 0x80) {
263 unsigned len;
260 int n = *p & 0x7F; 264 int n = *p & 0x7F;
261 p++, sourcelen--; 265 p++, sourcelen--;
262 if (sourcelen < n) 266 if (sourcelen < n)
263 return -1; 267 return -1;
264 *length = 0; 268 len = 0;
265 while (n--) 269 while (n--)
266 *length = (*length << 8) | (*p++); 270 len = (len << 8) | (*p++);
267 sourcelen -= n; 271 sourcelen -= n;
272 *length = toint(len);
268 } else { 273 } else {
269 *length = *p; 274 *length = *p;
270 p++, sourcelen--; 275 p++, sourcelen--;
276 }
277
278 if (*length < 0) {
279 printf("Negative ASN.1 length\n");
280 return -1;
271 } 281 }
272 282
273 return p - (unsigned char *) source; 283 return p - (unsigned char *) source;
274 } 284 }
275 285
465 } 475 }
466 476
467 m_burn(buffer, sizeof(buffer)); 477 m_burn(buffer, sizeof(buffer));
468 return ret; 478 return ret;
469 479
470 error: 480 error:
471 m_burn(buffer, sizeof(buffer)); 481 m_burn(buffer, sizeof(buffer));
472 if (ret) { 482 if (ret) {
473 if (ret->keyblob) { 483 if (ret->keyblob) {
474 m_burn(ret->keyblob, ret->keyblob_size); 484 m_burn(ret->keyblob, ret->keyblob_size);
475 m_free(ret->keyblob); 485 m_free(ret->keyblob);
580 p = key->keyblob; 590 p = key->keyblob;
581 591
582 /* 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. */
583 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);
584 p += ret; 594 p += ret;
585 if (ret < 0 || id != 16) { 595 if (ret < 0 || id != 16 || len < 0 ||
586 errmsg = "ASN.1 decoding failure - wrong password?"; 596 key->keyblob+key->keyblob_len-p < len) {
597 errmsg = "ASN.1 decoding failure";
587 goto error; 598 goto error;
588 } 599 }
589 600
590 /* Expect a load of INTEGERs. */ 601 /* Expect a load of INTEGERs. */
591 if (key->type == OSSH_RSA) 602 if (key->type == OSSH_RSA)
598 /* 609 /*
599 * Space to create key blob in. 610 * Space to create key blob in.
600 */ 611 */
601 blobbuf = buf_new(3000); 612 blobbuf = buf_new(3000);
602 613
603 #ifdef DROPBEAR_DSS 614 #if DROPBEAR_DSS
604 if (key->type == OSSH_DSA) { 615 if (key->type == OSSH_DSA) {
605 buf_putstring(blobbuf, "ssh-dss", 7); 616 buf_putstring(blobbuf, "ssh-dss", 7);
606 retkey->type = DROPBEAR_SIGNKEY_DSS; 617 retkey->type = DROPBEAR_SIGNKEY_DSS;
607 } 618 }
608 #endif 619 #endif
609 #ifdef DROPBEAR_RSA 620 #if DROPBEAR_RSA
610 if (key->type == OSSH_RSA) { 621 if (key->type == OSSH_RSA) {
611 buf_putstring(blobbuf, "ssh-rsa", 7); 622 buf_putstring(blobbuf, "ssh-rsa", 7);
612 retkey->type = DROPBEAR_SIGNKEY_RSA; 623 retkey->type = DROPBEAR_SIGNKEY_RSA;
613 } 624 }
614 #endif 625 #endif
615 626
616 for (i = 0; i < num_integers; i++) { 627 for (i = 0; i < num_integers; i++) {
617 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,
618 &id, &len, &flags); 629 &id, &len, &flags);
619 p += ret; 630 p += ret;
620 if (ret < 0 || id != 2 || 631 if (ret < 0 || id != 2 || len < 0 ||
621 key->keyblob+key->keyblob_len-p < len) { 632 key->keyblob+key->keyblob_len-p < len) {
622 errmsg = "ASN.1 decoding failure"; 633 errmsg = "ASN.1 decoding failure";
623 goto error; 634 goto error;
624 } 635 }
625 636
664 675
665 /* Skip past the number. */ 676 /* Skip past the number. */
666 p += len; 677 p += len;
667 } 678 }
668 679
669 #ifdef DROPBEAR_ECDSA 680 #if DROPBEAR_ECDSA
670 if (key->type == OSSH_EC) { 681 if (key->type == OSSH_EC) {
671 unsigned char* private_key_bytes = NULL; 682 unsigned char* private_key_bytes = NULL;
672 int private_key_len = 0; 683 int private_key_len = 0;
673 unsigned char* public_key_bytes = NULL; 684 unsigned char* public_key_bytes = NULL;
674 int public_key_len = 0; 685 int public_key_len = 0;
681 /* privateKey OCTET STRING, */ 692 /* privateKey OCTET STRING, */
682 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,
683 &id, &len, &flags); 694 &id, &len, &flags);
684 p += ret; 695 p += ret;
685 /* id==4 for octet string */ 696 /* id==4 for octet string */
686 if (ret < 0 || id != 4 || 697 if (ret < 0 || id != 4 || len < 0 ||
687 key->keyblob+key->keyblob_len-p < len) { 698 key->keyblob+key->keyblob_len-p < len) {
688 errmsg = "ASN.1 decoding failure"; 699 errmsg = "ASN.1 decoding failure";
689 goto error; 700 goto error;
690 } 701 }
691 private_key_bytes = p; 702 private_key_bytes = p;
695 /* parameters [0] ECDomainParameters {{ SECGCurveNames }} OPTIONAL, */ 706 /* parameters [0] ECDomainParameters {{ SECGCurveNames }} OPTIONAL, */
696 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,
697 &id, &len, &flags); 708 &id, &len, &flags);
698 p += ret; 709 p += ret;
699 /* id==0 */ 710 /* id==0 */
700 if (ret < 0 || id != 0) { 711 if (ret < 0 || id != 0 || len < 0) {
701 errmsg = "ASN.1 decoding failure"; 712 errmsg = "ASN.1 decoding failure";
702 goto error; 713 goto error;
703 } 714 }
704 715
705 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,
706 &id, &len, &flags); 717 &id, &len, &flags);
707 p += ret; 718 p += ret;
708 /* id==6 for object */ 719 /* id==6 for object */
709 if (ret < 0 || id != 6 || 720 if (ret < 0 || id != 6 || len < 0 ||
710 key->keyblob+key->keyblob_len-p < len) { 721 key->keyblob+key->keyblob_len-p < len) {
711 errmsg = "ASN.1 decoding failure"; 722 errmsg = "ASN.1 decoding failure";
712 goto error; 723 goto error;
713 } 724 }
714 725
715 if (0) {} 726 if (0) {}
716 #ifdef DROPBEAR_ECC_256 727 #if DROPBEAR_ECC_256
717 else if (len == sizeof(OID_SEC256R1_BLOB) 728 else if (len == sizeof(OID_SEC256R1_BLOB)
718 && memcmp(p, OID_SEC256R1_BLOB, len) == 0) { 729 && memcmp(p, OID_SEC256R1_BLOB, len) == 0) {
719 retkey->type = DROPBEAR_SIGNKEY_ECDSA_NISTP256; 730 retkey->type = DROPBEAR_SIGNKEY_ECDSA_NISTP256;
720 curve = &ecc_curve_nistp256; 731 curve = &ecc_curve_nistp256;
721 } 732 }
722 #endif 733 #endif
723 #ifdef DROPBEAR_ECC_384 734 #if DROPBEAR_ECC_384
724 else if (len == sizeof(OID_SEC384R1_BLOB) 735 else if (len == sizeof(OID_SEC384R1_BLOB)
725 && memcmp(p, OID_SEC384R1_BLOB, len) == 0) { 736 && memcmp(p, OID_SEC384R1_BLOB, len) == 0) {
726 retkey->type = DROPBEAR_SIGNKEY_ECDSA_NISTP384; 737 retkey->type = DROPBEAR_SIGNKEY_ECDSA_NISTP384;
727 curve = &ecc_curve_nistp384; 738 curve = &ecc_curve_nistp384;
728 } 739 }
729 #endif 740 #endif
730 #ifdef DROPBEAR_ECC_521 741 #if DROPBEAR_ECC_521
731 else if (len == sizeof(OID_SEC521R1_BLOB) 742 else if (len == sizeof(OID_SEC521R1_BLOB)
732 && memcmp(p, OID_SEC521R1_BLOB, len) == 0) { 743 && memcmp(p, OID_SEC521R1_BLOB, len) == 0) {
733 retkey->type = DROPBEAR_SIGNKEY_ECDSA_NISTP521; 744 retkey->type = DROPBEAR_SIGNKEY_ECDSA_NISTP521;
734 curve = &ecc_curve_nistp521; 745 curve = &ecc_curve_nistp521;
735 } 746 }
743 /* publicKey [1] BIT STRING OPTIONAL */ 754 /* publicKey [1] BIT STRING OPTIONAL */
744 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,
745 &id, &len, &flags); 756 &id, &len, &flags);
746 p += ret; 757 p += ret;
747 /* id==1 */ 758 /* id==1 */
748 if (ret < 0 || id != 1) { 759 if (ret < 0 || id != 1 || len < 0) {
749 errmsg = "ASN.1 decoding failure"; 760 errmsg = "ASN.1 decoding failure";
750 goto error; 761 goto error;
751 } 762 }
752 763
753 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,
754 &id, &len, &flags); 765 &id, &len, &flags);
755 p += ret; 766 p += ret;
756 /* id==3 for bit string */ 767 /* id==3 for bit string */
757 if (ret < 0 || id != 3 || 768 if (ret < 0 || id != 3 || len < 0 ||
758 key->keyblob+key->keyblob_len-p < len) { 769 key->keyblob+key->keyblob_len-p < len) {
759 errmsg = "ASN.1 decoding failure"; 770 errmsg = "ASN.1 decoding failure";
760 goto error; 771 goto error;
761 } 772 }
762 public_key_bytes = p+1; 773 public_key_bytes = p+1;
828 char *header = NULL, *footer = NULL; 839 char *header = NULL, *footer = NULL;
829 char zero[1]; 840 char zero[1];
830 int ret = 0; 841 int ret = 0;
831 FILE *fp; 842 FILE *fp;
832 843
833 #ifdef DROPBEAR_RSA 844 #if DROPBEAR_RSA
834 mp_int dmp1, dmq1, iqmp, tmpval; /* for rsa */ 845 mp_int dmp1, dmq1, iqmp, tmpval; /* for rsa */
835 #endif 846 #endif
836 847
837 if ( 848 if (
838 #ifdef DROPBEAR_RSA 849 #if DROPBEAR_RSA
839 key->type == DROPBEAR_SIGNKEY_RSA || 850 key->type == DROPBEAR_SIGNKEY_RSA ||
840 #endif 851 #endif
841 #ifdef DROPBEAR_DSS 852 #if DROPBEAR_DSS
842 key->type == DROPBEAR_SIGNKEY_DSS || 853 key->type == DROPBEAR_SIGNKEY_DSS ||
843 #endif 854 #endif
844 0) 855 0)
845 { 856 {
846 /* 857 /*
1022 memcpy(outblob+pos, numbers[i].start, numbers[i].bytes); 1033 memcpy(outblob+pos, numbers[i].start, numbers[i].bytes);
1023 pos += numbers[i].bytes; 1034 pos += numbers[i].bytes;
1024 } 1035 }
1025 } /* end RSA and DSS handling */ 1036 } /* end RSA and DSS handling */
1026 1037
1027 #ifdef DROPBEAR_ECDSA 1038 #if DROPBEAR_ECDSA
1028 if (key->type == DROPBEAR_SIGNKEY_ECDSA_NISTP256 1039 if (key->type == DROPBEAR_SIGNKEY_ECDSA_NISTP256
1029 || key->type == DROPBEAR_SIGNKEY_ECDSA_NISTP384 1040 || key->type == DROPBEAR_SIGNKEY_ECDSA_NISTP384
1030 || key->type == DROPBEAR_SIGNKEY_ECDSA_NISTP521) { 1041 || key->type == DROPBEAR_SIGNKEY_ECDSA_NISTP521) {
1031 1042
1032 /* SEC1 V2 appendix c.4 1043 /* SEC1 V2 appendix c.4
1377 if (ret) { 1388 if (ret) {
1378 if (ret->keyblob) { 1389 if (ret->keyblob) {
1379 memset(ret->keyblob, 0, ret->keyblob_size); 1390 memset(ret->keyblob, 0, ret->keyblob_size);
1380 m_free(ret->keyblob); 1391 m_free(ret->keyblob);
1381 } 1392 }
1382 memset(&ret, 0, sizeof(ret)); 1393 memset(ret, 0, sizeof(*ret));
1383 m_free(ret); 1394 m_free(ret);
1384 } 1395 }
1385 return NULL; 1396 return NULL;
1386 } 1397 }
1387 1398
1405 */ 1416 */
1406 answer = 0; 1417 answer = 0;
1407 pos = 8; 1418 pos = 8;
1408 if (key->keyblob_len < pos+4) 1419 if (key->keyblob_len < pos+4)
1409 goto done; /* key is far too short */ 1420 goto done; /* key is far too short */
1410 pos += 4 + GET_32BIT(key->keyblob + pos); /* skip key type */ 1421 len = toint(GET_32BIT(key->keyblob + pos));
1411 if (key->keyblob_len < pos+4) 1422 if (len < 0 || len > key->keyblob_len - pos - 4)
1412 goto done; /* key is far too short */ 1423 goto done; /* key is far too short */
1413 len = GET_32BIT(key->keyblob + pos); /* find cipher-type length */ 1424 pos += 4 + len; /* skip key type */
1414 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)
1415 goto done; /* cipher type string is incomplete */ 1427 goto done; /* cipher type string is incomplete */
1416 if (len != 4 || 0 != memcmp(key->keyblob + pos + 4, "none", 4)) 1428 if (len != 4 || 0 != memcmp(key->keyblob + pos + 4, "none", 4))
1417 answer = 1; 1429 answer = 1;
1418 1430
1419 done: 1431 done:
1420 *comment = dupstr(key->comment); 1432 *comment = dupstr(key->comment);
1421 memset(key->keyblob, 0, key->keyblob_size); 1433 memset(key->keyblob, 0, key->keyblob_size);
1422 m_free(key->keyblob); 1434 m_free(key->keyblob);
1423 memset(&key, 0, sizeof(key)); 1435 memset(key, 0, sizeof(*key));
1424 m_free(key); 1436 m_free(key);
1425 return answer; 1437 return answer;
1426 } 1438 }
1427 1439
1428 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)
1429 { 1441 {
1430 int bits; 1442 unsigned bits, bytes;
1431 int bytes;
1432 unsigned char *d = (unsigned char *) data; 1443 unsigned char *d = (unsigned char *) data;
1433 1444
1434 if (len < 4) 1445 if (len < 4)
1435 goto error; 1446 goto error;
1436 bits = GET_32BIT(d); 1447 bits = GET_32BIT(d);
1479 char *ciphertext; 1490 char *ciphertext;
1480 int cipherlen; 1491 int cipherlen;
1481 struct ssh2_userkey *ret = NULL, *retkey; 1492 struct ssh2_userkey *ret = NULL, *retkey;
1482 const struct ssh_signkey *alg; 1493 const struct ssh_signkey *alg;
1483 unsigned char *blob = NULL; 1494 unsigned char *blob = NULL;
1484 int blobsize, publen, privlen; 1495 int blobsize = 0, publen, privlen;
1485 1496
1486 if (!key) 1497 if (!key)
1487 return NULL; 1498 return NULL;
1488 1499
1489 /* 1500 /*
1599 } 1610 }
1600 1611
1601 /* 1612 /*
1602 * Strip away the containing string to get to the real meat. 1613 * Strip away the containing string to get to the real meat.
1603 */ 1614 */
1604 len = GET_32BIT(ciphertext); 1615 len = toint(GET_32BIT(ciphertext));
1605 if (len > cipherlen-4) { 1616 if (len < 0 || len > cipherlen-4) {
1606 errmsg = "containing string was ill-formed"; 1617 errmsg = "containing string was ill-formed";
1607 goto error; 1618 goto error;
1608 } 1619 }
1609 ciphertext += 4; 1620 ciphertext += 4;
1610 cipherlen = len; 1621 cipherlen = len;
1667 pos += put_mp(blob+pos, g.start, g.bytes); 1678 pos += put_mp(blob+pos, g.start, g.bytes);
1668 pos += put_mp(blob+pos, y.start, y.bytes); 1679 pos += put_mp(blob+pos, y.start, y.bytes);
1669 publen = pos; 1680 publen = pos;
1670 pos += put_mp(blob+pos, x.start, x.bytes); 1681 pos += put_mp(blob+pos, x.start, x.bytes);
1671 privlen = pos - publen; 1682 privlen = pos - publen;
1672 } 1683 } else
1684 return NULL;
1673 1685
1674 dropbear_assert(privlen > 0); /* should have bombed by now if not */ 1686 dropbear_assert(privlen > 0); /* should have bombed by now if not */
1675 1687
1676 retkey = snew(struct ssh2_userkey); 1688 retkey = snew(struct ssh2_userkey);
1677 retkey->alg = alg; 1689 retkey->alg = alg;
1691 memset(blob, 0, blobsize); 1703 memset(blob, 0, blobsize);
1692 m_free(blob); 1704 m_free(blob);
1693 } 1705 }
1694 memset(key->keyblob, 0, key->keyblob_size); 1706 memset(key->keyblob, 0, key->keyblob_size);
1695 m_free(key->keyblob); 1707 m_free(key->keyblob);
1696 memset(&key, 0, sizeof(key)); 1708 memset(key, 0, sizeof(*key));
1697 m_free(key); 1709 m_free(key);
1698 return ret; 1710 return ret;
1699 } 1711 }
1700 1712
1701 int sshcom_write(const char *filename, sign_key *key, 1713 int sshcom_write(const char *filename, sign_key *key,
1904 m_free(pubblob); 1916 m_free(pubblob);
1905 } 1917 }
1906 return ret; 1918 return ret;
1907 } 1919 }
1908 #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 }