OpenSSHサーバーが/etc/ssh/moduli
そして、Diffie-Hellmanグループ交換ごとにランダムに係数を選択します。そのファイルに含めることができるモジュラス行の数に実際的な制限があるかどうか、私は疑問に思っています。
50,000行など、とんでもない数が問題を引き起こしたり、奇妙な動作を引き起こしたりしますか?
おそらく4294967295
ソースファイルdh.c
では、moduliファイルがfopen
で開かれ、fgets
ループを使用して各行が抽出されます。処理中の現在の行は、int linenum
として宣言された変数に記録されます。これは、2を表すことができる32ビットの符号付き整数であることを意味します32 可能な値。署名されているため、これは-2147483648〜2147483647に相当します(0はまだ数値であり、正と見なされるため、1つ少なくなります)。 0から始まり、増分するため、最大値は2になります。32/2-1.この範囲を超えて回り込むとマイナスになります。
ソースコードでは、符号付きと符号なしの間でいくつかの変換があります。 int linenum
は行数を保持しますが、int bestcount
は適切な行数を保持してarc4random_uniform
に渡され、0とbestcount
の間のランダムな値を出力します。受け入れる値と返す値は符号なしですが、別の符号付き整数which
に格納されます。その整数は、使用されるランダム線を指定するために使用されます。行の数が32ビット整数で保持できる数を超える場合、行の上限のランダムな選択は、実際の行数よりも少なく、おそらくはるかに少なくなります。
この制限は実際には問題ではありません。 1行の最大長は4096バイトで、232 各行が4096バイトの行(最初の行が0で始まるため、-1ではありません)では、最大ファイルサイズは16テラバイトになります。 openssl dhparamがテラバイトのモジュラスを生成するのを待っています。
OpenSSH 7.5p1以降のソースコード内の関数全体:
DH *
choose_dh(int min, int wantbits, int max)
{
FILE *f;
char line[4096];
int best, bestcount, which;
int linenum;
struct dhgroup dhg;
if ((f = fopen(_PATH_DH_MODULI, "r")) == NULL) {
logit("WARNING: could not open %s (%s), using fixed modulus",
_PATH_DH_MODULI, strerror(errno));
return (dh_new_group_fallback(max));
}
linenum = 0;
best = bestcount = 0;
while (fgets(line, sizeof(line), f)) {
linenum++;
if (!parse_prime(linenum, line, &dhg))
continue;
BN_clear_free(dhg.g);
BN_clear_free(dhg.p);
if (dhg.size > max || dhg.size < min)
continue;
if ((dhg.size > wantbits && dhg.size < best) ||
(dhg.size > best && best < wantbits)) {
best = dhg.size;
bestcount = 0;
}
if (dhg.size == best)
bestcount++;
}
rewind(f);
if (bestcount == 0) {
fclose(f);
logit("WARNING: no suitable primes in %s", _PATH_DH_MODULI);
return (dh_new_group_fallback(max));
}
linenum = 0;
which = arc4random_uniform(bestcount);
while (fgets(line, sizeof(line), f)) {
if (!parse_prime(linenum, line, &dhg))
continue;
if ((dhg.size > max || dhg.size < min) ||
dhg.size != best ||
linenum++ != which) {
BN_clear_free(dhg.g);
BN_clear_free(dhg.p);
continue;
}
break;
}
fclose(f);
if (linenum != which+1) {
logit("WARNING: line %d disappeared in %s, giving up",
which, _PATH_DH_MODULI);
return (dh_new_group_fallback(max));
}
return (dh_new_group(dhg.g, dhg.p));
}
これはすべて、ソースコードをざっと見ただけです。大きなファイルが原因で私が予測できない理由で将来発生する可能性のある他の問題がある場合は、上限が小さくなる可能性があります。しかし、そうなると思う理由は何もありません。