@@ -289,7 +289,7 @@ static int ssh2_read_mpint(void *data, int len, struct mpint_pos *ret)
289
289
290
290
if (len < 4 )
291
291
goto error ;
292
- bytes = GET_32BIT (d );
292
+ bytes = toint ( GET_32BIT (d ) );
293
293
if (bytes < 0 || len - 4 < bytes )
294
294
goto error ;
295
295
@@ -745,6 +745,10 @@ int openssh_write(const Filename *filename, struct ssh2_userkey *key,
745
745
struct mpint_pos n , e , d , p , q , iqmp , dmp1 , dmq1 ;
746
746
Bignum bd , bp , bq , bdmp1 , bdmq1 ;
747
747
748
+ /*
749
+ * These blobs were generated from inside PuTTY, so we needn't
750
+ * treat them as untrusted.
751
+ */
748
752
pos = 4 + GET_32BIT (pubblob );
749
753
pos += ssh2_read_mpint (pubblob + pos , publen - pos , & e );
750
754
pos += ssh2_read_mpint (pubblob + pos , publen - pos , & n );
@@ -798,6 +802,10 @@ int openssh_write(const Filename *filename, struct ssh2_userkey *key,
798
802
int pos ;
799
803
struct mpint_pos p , q , g , y , x ;
800
804
805
+ /*
806
+ * These blobs were generated from inside PuTTY, so we needn't
807
+ * treat them as untrusted.
808
+ */
801
809
pos = 4 + GET_32BIT (pubblob );
802
810
pos += ssh2_read_mpint (pubblob + pos , publen - pos , & p );
803
811
pos += ssh2_read_mpint (pubblob + pos , publen - pos , & q );
@@ -1216,11 +1224,12 @@ int sshcom_encrypted(const Filename *filename, char **comment)
1216
1224
pos = 8 ;
1217
1225
if (key -> keyblob_len < pos + 4 )
1218
1226
goto done ; /* key is far too short */
1219
- pos += 4 + GET_32BIT (key -> keyblob + pos ); /* skip key type */
1220
- if (key -> keyblob_len < pos + 4 )
1227
+ len = toint ( GET_32BIT (key -> keyblob + pos ));
1228
+ if (len < 0 || len > key -> keyblob_len - pos - 4 )
1221
1229
goto done ; /* key is far too short */
1222
- len = GET_32BIT (key -> keyblob + pos ); /* find cipher-type length */
1223
- if (key -> keyblob_len < pos + 4 + len )
1230
+ pos += 4 + len ; /* skip key type */
1231
+ len = toint (GET_32BIT (key -> keyblob + pos )); /* find cipher-type length */
1232
+ if (len < 0 || len > key -> keyblob_len - pos - 4 )
1224
1233
goto done ; /* cipher type string is incomplete */
1225
1234
if (len != 4 || 0 != memcmp (key -> keyblob + pos + 4 , "none" , 4 ))
1226
1235
answer = 1 ;
@@ -1236,8 +1245,7 @@ int sshcom_encrypted(const Filename *filename, char **comment)
1236
1245
1237
1246
static int sshcom_read_mpint (void * data , int len , struct mpint_pos * ret )
1238
1247
{
1239
- int bits ;
1240
- int bytes ;
1248
+ unsigned bits , bytes ;
1241
1249
unsigned char * d = (unsigned char * ) data ;
1242
1250
1243
1251
if (len < 4 )
@@ -1309,7 +1317,8 @@ struct ssh2_userkey *sshcom_read(const Filename *filename, char *passphrase,
1309
1317
*/
1310
1318
pos = 8 ;
1311
1319
if (key -> keyblob_len < pos + 4 ||
1312
- (len = GET_32BIT (key -> keyblob + pos )) > key -> keyblob_len - pos - 4 ) {
1320
+ (len = toint (GET_32BIT (key -> keyblob + pos ))) < 0 ||
1321
+ len > key -> keyblob_len - pos - 4 ) {
1313
1322
errmsg = "key blob does not contain a key type string" ;
1314
1323
goto error ;
1315
1324
}
@@ -1329,7 +1338,8 @@ struct ssh2_userkey *sshcom_read(const Filename *filename, char *passphrase,
1329
1338
* Determine the cipher type.
1330
1339
*/
1331
1340
if (key -> keyblob_len < pos + 4 ||
1332
- (len = GET_32BIT (key -> keyblob + pos )) > key -> keyblob_len - pos - 4 ) {
1341
+ (len = toint (GET_32BIT (key -> keyblob + pos ))) < 0 ||
1342
+ len > key -> keyblob_len - pos - 4 ) {
1333
1343
errmsg = "key blob does not contain a cipher type string" ;
1334
1344
goto error ;
1335
1345
}
@@ -1347,7 +1357,8 @@ struct ssh2_userkey *sshcom_read(const Filename *filename, char *passphrase,
1347
1357
* Get hold of the encrypted part of the key.
1348
1358
*/
1349
1359
if (key -> keyblob_len < pos + 4 ||
1350
- (len = GET_32BIT (key -> keyblob + pos )) > key -> keyblob_len - pos - 4 ) {
1360
+ (len = toint (GET_32BIT (key -> keyblob + pos ))) < 0 ||
1361
+ len > key -> keyblob_len - pos - 4 ) {
1351
1362
errmsg = "key blob does not contain actual key data" ;
1352
1363
goto error ;
1353
1364
}
@@ -1411,7 +1422,7 @@ struct ssh2_userkey *sshcom_read(const Filename *filename, char *passphrase,
1411
1422
/*
1412
1423
* Strip away the containing string to get to the real meat.
1413
1424
*/
1414
- len = GET_32BIT (ciphertext );
1425
+ len = toint ( GET_32BIT (ciphertext ) );
1415
1426
if (len < 0 || len > cipherlen - 4 ) {
1416
1427
errmsg = "containing string was ill-formed" ;
1417
1428
goto error ;
@@ -1540,6 +1551,10 @@ int sshcom_write(const Filename *filename, struct ssh2_userkey *key,
1540
1551
int pos ;
1541
1552
struct mpint_pos n , e , d , p , q , iqmp ;
1542
1553
1554
+ /*
1555
+ * These blobs were generated from inside PuTTY, so we needn't
1556
+ * treat them as untrusted.
1557
+ */
1543
1558
pos = 4 + GET_32BIT (pubblob );
1544
1559
pos += ssh2_read_mpint (pubblob + pos , publen - pos , & e );
1545
1560
pos += ssh2_read_mpint (pubblob + pos , publen - pos , & n );
@@ -1565,6 +1580,10 @@ int sshcom_write(const Filename *filename, struct ssh2_userkey *key,
1565
1580
int pos ;
1566
1581
struct mpint_pos p , q , g , y , x ;
1567
1582
1583
+ /*
1584
+ * These blobs were generated from inside PuTTY, so we needn't
1585
+ * treat them as untrusted.
1586
+ */
1568
1587
pos = 4 + GET_32BIT (pubblob );
1569
1588
pos += ssh2_read_mpint (pubblob + pos , publen - pos , & p );
1570
1589
pos += ssh2_read_mpint (pubblob + pos , publen - pos , & q );
0 commit comments