Mercurial > dropbear
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 } |