github.com/letsencrypt/boulder@v0.20251208.0/goodkey/good_key_test.go (about) 1 package goodkey 2 3 import ( 4 "context" 5 "crypto/ecdsa" 6 "crypto/elliptic" 7 "crypto/rand" 8 "crypto/rsa" 9 "fmt" 10 "math/big" 11 "testing" 12 13 "github.com/letsencrypt/boulder/test" 14 ) 15 16 // testingPolicy is a simple policy which allows all of the key types, so that 17 // the unit tests can exercise checks against all key types. 18 var testingPolicy = &KeyPolicy{allowedKeys: AllowedKeys{ 19 RSA2048: true, RSA3072: true, RSA4096: true, 20 ECDSAP256: true, ECDSAP384: true, ECDSAP521: true, 21 }} 22 23 func TestUnknownKeyType(t *testing.T) { 24 notAKey := struct{}{} 25 err := testingPolicy.GoodKey(context.Background(), notAKey) 26 test.AssertError(t, err, "Should have rejected a key of unknown type") 27 test.AssertEquals(t, err.Error(), "unsupported key type struct {}") 28 } 29 30 func TestNilKey(t *testing.T) { 31 err := testingPolicy.GoodKey(context.Background(), nil) 32 test.AssertError(t, err, "Should have rejected a nil key") 33 test.AssertEquals(t, err.Error(), "unsupported key type <nil>") 34 } 35 36 func TestSmallModulus(t *testing.T) { 37 pubKey := rsa.PublicKey{ 38 N: big.NewInt(0), 39 E: 65537, 40 } 41 // 2040 bits 42 _, ok := pubKey.N.SetString("104192126510885102608953552259747211060428328569316484779167706297543848858189721071301121307701498317286069484848193969810800653457088975832436062805901725915630417996487259956349018066196416400386483594314258078114607080545265502078791826837453107382149801328758721235866366842649389274931060463277516954884108984101391466769505088222180613883737986792254164577832157921425082478871935498631777878563742033332460445633026471887331001305450139473524438241478798689974351175769895824322173301257621327448162705637127373457350813027123239805772024171112299987923305882261194120410409098448380641378552305583392176287", 10) 43 if !ok { 44 t.Errorf("error parsing pubkey modulus") 45 } 46 err := testingPolicy.GoodKey(context.Background(), &pubKey) 47 test.AssertError(t, err, "Should have rejected too-short key") 48 test.AssertEquals(t, err.Error(), "key size not supported: 2040") 49 } 50 51 func TestLargeModulus(t *testing.T) { 52 pubKey := rsa.PublicKey{ 53 N: big.NewInt(0), 54 E: 65537, 55 } 56 // 4097 bits 57 _, ok := pubKey.N.SetString("1528586537844618544364689295678280797814937047039447018548513699782432768815684971832418418955305671838918285565080181315448131784543332408348488544125812746629522583979538961638790013578302979210481729874191053412386396889481430969071543569003141391030053024684850548909056275565684242965892176703473950844930842702506635531145654194239072799616096020023445127233557468234181352398708456163013484600764686209741158795461806441111028922165846800488957692595308009319392149669715238691709012014980470238746838534949750493558807218940354555205690667168930634644030378921382266510932028134500172599110460167962515262077587741235811653717121760943005253103187409557573174347385738572144714188928416780963680160418832333908040737262282830643745963536624555340279793555475547508851494656512855403492456740439533790565640263514349940712999516725281940465613417922773583725174223806589481568984323871222072582132221706797917380250216291620957692131931099423995355390698925093903005385497308399692769135287821632877871068909305276870015125960884987746154344006895331078411141197233179446805991116541744285238281451294472577537413640009811940462311100056023815261650331552185459228689469446389165886801876700815724561451940764544990177661873073", 10) 58 if !ok { 59 t.Errorf("error parsing pubkey modulus") 60 } 61 err := testingPolicy.GoodKey(context.Background(), &pubKey) 62 test.AssertError(t, err, "Should have rejected too-long key") 63 test.AssertEquals(t, err.Error(), "key size not supported: 4097") 64 } 65 66 func TestModulusModulo8(t *testing.T) { 67 bigOne := big.NewInt(1) 68 key := rsa.PublicKey{ 69 N: bigOne.Lsh(bigOne, 2048), 70 E: 5, 71 } 72 err := testingPolicy.GoodKey(context.Background(), &key) 73 test.AssertError(t, err, "Should have rejected modulus with length not divisible by 8") 74 test.AssertEquals(t, err.Error(), "key size not supported: 2049") 75 } 76 77 var mod2048 = big.NewInt(0).Sub(big.NewInt(0).Lsh(big.NewInt(1), 2048), big.NewInt(1)) 78 79 func TestNonStandardExp(t *testing.T) { 80 evenMod := big.NewInt(0).Add(big.NewInt(1).Lsh(big.NewInt(1), 2047), big.NewInt(2)) 81 key := rsa.PublicKey{ 82 N: evenMod, 83 E: (1 << 16), 84 } 85 err := testingPolicy.GoodKey(context.Background(), &key) 86 test.AssertError(t, err, "Should have rejected non-standard exponent") 87 test.AssertEquals(t, err.Error(), "key exponent must be 65537") 88 } 89 90 func TestEvenModulus(t *testing.T) { 91 evenMod := big.NewInt(0).Add(big.NewInt(1).Lsh(big.NewInt(1), 2047), big.NewInt(2)) 92 key := rsa.PublicKey{ 93 N: evenMod, 94 E: (1 << 16) + 1, 95 } 96 err := testingPolicy.GoodKey(context.Background(), &key) 97 test.AssertError(t, err, "Should have rejected even modulus") 98 test.AssertEquals(t, err.Error(), "key divisible by small prime") 99 } 100 101 func TestModulusDivisibleBySmallPrime(t *testing.T) { 102 key := rsa.PublicKey{ 103 N: mod2048, 104 E: (1 << 16) + 1, 105 } 106 err := testingPolicy.GoodKey(context.Background(), &key) 107 test.AssertError(t, err, "Should have rejected modulus divisible by 3") 108 test.AssertEquals(t, err.Error(), "key divisible by small prime") 109 } 110 111 func TestROCA(t *testing.T) { 112 n, ok := big.NewInt(1).SetString("19089470491547632015867380494603366846979936677899040455785311493700173635637619562546319438505971838982429681121352968394792665704951454132311441831732124044135181992768774222852895664400681270897445415599851900461316070972022018317962889565731866601557238345786316235456299813772607869009873279585912430769332375239444892105064608255089298943707214066350230292124208314161171265468111771687514518823144499250339825049199688099820304852696380797616737008621384107235756455735861506433065173933123259184114000282435500939123478591192413006994709825840573671701120771013072419520134975733578923370992644987545261926257", 10) 113 if !ok { 114 t.Fatal("failed to parse") 115 } 116 key := rsa.PublicKey{ 117 N: n, 118 E: 65537, 119 } 120 err := testingPolicy.GoodKey(context.Background(), &key) 121 test.AssertError(t, err, "Should have rejected ROCA-weak key") 122 test.AssertEquals(t, err.Error(), "key generated by vulnerable Infineon-based hardware") 123 } 124 125 func TestGoodKey(t *testing.T) { 126 private, err := rsa.GenerateKey(rand.Reader, 2048) 127 test.AssertNotError(t, err, "Error generating key") 128 test.AssertNotError(t, testingPolicy.GoodKey(context.Background(), &private.PublicKey), "Should have accepted good key") 129 } 130 131 func TestECDSABadCurve(t *testing.T) { 132 for _, curve := range invalidCurves { 133 private, err := ecdsa.GenerateKey(curve, rand.Reader) 134 test.AssertNotError(t, err, "Error generating key") 135 err = testingPolicy.GoodKey(context.Background(), &private.PublicKey) 136 test.AssertError(t, err, "Should have rejected key with unsupported curve") 137 test.AssertEquals(t, err.Error(), fmt.Sprintf("ECDSA curve %s not allowed", curve.Params().Name)) 138 } 139 } 140 141 var invalidCurves = []elliptic.Curve{ 142 elliptic.P224(), 143 } 144 145 var validCurves = []elliptic.Curve{ 146 elliptic.P256(), 147 elliptic.P384(), 148 elliptic.P521(), 149 } 150 151 func TestECDSAGoodKey(t *testing.T) { 152 for _, curve := range validCurves { 153 private, err := ecdsa.GenerateKey(curve, rand.Reader) 154 test.AssertNotError(t, err, "Error generating key") 155 test.AssertNotError(t, testingPolicy.GoodKey(context.Background(), &private.PublicKey), "Should have accepted good key") 156 } 157 } 158 159 func TestECDSANotOnCurveX(t *testing.T) { 160 for _, curve := range validCurves { 161 // Change a public key so that it is no longer on the curve. 162 private, err := ecdsa.GenerateKey(curve, rand.Reader) 163 test.AssertNotError(t, err, "Error generating key") 164 165 private.X.Add(private.X, big.NewInt(1)) 166 err = testingPolicy.GoodKey(context.Background(), &private.PublicKey) 167 test.AssertError(t, err, "Should not have accepted key not on the curve") 168 test.AssertEquals(t, err.Error(), "key point is not on the curve") 169 } 170 } 171 172 func TestECDSANotOnCurveY(t *testing.T) { 173 for _, curve := range validCurves { 174 // Again with Y. 175 private, err := ecdsa.GenerateKey(curve, rand.Reader) 176 test.AssertNotError(t, err, "Error generating key") 177 178 // Change the public key so that it is no longer on the curve. 179 private.Y.Add(private.Y, big.NewInt(1)) 180 err = testingPolicy.GoodKey(context.Background(), &private.PublicKey) 181 test.AssertError(t, err, "Should not have accepted key not on the curve") 182 test.AssertEquals(t, err.Error(), "key point is not on the curve") 183 } 184 } 185 186 func TestECDSANegative(t *testing.T) { 187 for _, curve := range validCurves { 188 // Check that negative X is not accepted. 189 private, err := ecdsa.GenerateKey(curve, rand.Reader) 190 test.AssertNotError(t, err, "Error generating key") 191 192 private.X.Neg(private.X) 193 err = testingPolicy.GoodKey(context.Background(), &private.PublicKey) 194 test.AssertError(t, err, "Should not have accepted key with negative X") 195 test.AssertEquals(t, err.Error(), "key x, y must not be negative") 196 197 // Check that negative Y is not accepted. 198 private.X.Neg(private.X) 199 private.Y.Neg(private.Y) 200 err = testingPolicy.GoodKey(context.Background(), &private.PublicKey) 201 test.AssertError(t, err, "Should not have accepted key with negative Y") 202 test.AssertEquals(t, err.Error(), "key x, y must not be negative") 203 } 204 } 205 206 func TestECDSAXOutsideField(t *testing.T) { 207 for _, curve := range validCurves { 208 // Check that X outside [0, p-1] is not accepted. 209 private, err := ecdsa.GenerateKey(curve, rand.Reader) 210 test.AssertNotError(t, err, "Error generating key") 211 212 private.X.Mul(private.X, private.Curve.Params().P) 213 err = testingPolicy.GoodKey(context.Background(), &private.PublicKey) 214 test.AssertError(t, err, "Should not have accepted key with a X > p-1") 215 test.AssertEquals(t, err.Error(), "key x, y must not exceed P-1") 216 } 217 } 218 219 func TestECDSAYOutsideField(t *testing.T) { 220 for _, curve := range validCurves { 221 // Check that Y outside [0, p-1] is not accepted. 222 private, err := ecdsa.GenerateKey(curve, rand.Reader) 223 test.AssertNotError(t, err, "Error generating key") 224 225 private.X.Mul(private.Y, private.Curve.Params().P) 226 err = testingPolicy.GoodKey(context.Background(), &private.PublicKey) 227 test.AssertError(t, err, "Should not have accepted key with a Y > p-1") 228 test.AssertEquals(t, err.Error(), "key x, y must not exceed P-1") 229 } 230 } 231 232 func TestECDSAIdentity(t *testing.T) { 233 for _, curve := range validCurves { 234 // The point at infinity is 0,0, it should not be accepted. 235 public := ecdsa.PublicKey{ 236 Curve: curve, 237 X: big.NewInt(0), 238 Y: big.NewInt(0), 239 } 240 241 err := testingPolicy.GoodKey(context.Background(), &public) 242 test.AssertError(t, err, "Should not have accepted key with point at infinity") 243 test.AssertEquals(t, err.Error(), "key x, y must not be the point at infinity") 244 } 245 } 246 247 func TestNonRefKey(t *testing.T) { 248 private, err := rsa.GenerateKey(rand.Reader, 2048) 249 test.AssertNotError(t, err, "Error generating key") 250 test.AssertError(t, testingPolicy.GoodKey(context.Background(), private.PublicKey), "Accepted non-reference key") 251 } 252 253 func TestDBBlocklistAccept(t *testing.T) { 254 for _, testCheck := range []BlockedKeyCheckFunc{ 255 nil, 256 func(context.Context, []byte) (bool, error) { 257 return false, nil 258 }, 259 } { 260 policy, err := NewPolicy(nil, testCheck) 261 test.AssertNotError(t, err, "NewKeyPolicy failed") 262 263 k, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) 264 test.AssertNotError(t, err, "ecdsa.GenerateKey failed") 265 err = policy.GoodKey(context.Background(), k.Public()) 266 test.AssertNotError(t, err, "GoodKey failed with a non-blocked key") 267 } 268 } 269 270 func TestDBBlocklistReject(t *testing.T) { 271 testCheck := func(context.Context, []byte) (bool, error) { 272 return true, nil 273 } 274 275 policy, err := NewPolicy(nil, testCheck) 276 test.AssertNotError(t, err, "NewKeyPolicy failed") 277 278 k, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) 279 test.AssertNotError(t, err, "ecdsa.GenerateKey failed") 280 err = policy.GoodKey(context.Background(), k.Public()) 281 test.AssertError(t, err, "GoodKey didn't fail with a blocked key") 282 test.AssertErrorIs(t, err, ErrBadKey) 283 test.AssertEquals(t, err.Error(), "public key is forbidden") 284 } 285 286 func TestDefaultAllowedKeys(t *testing.T) { 287 policy, err := NewPolicy(nil, nil) 288 test.AssertNotError(t, err, "NewPolicy with nil config failed") 289 test.Assert(t, policy.allowedKeys.RSA2048, "RSA 2048 should be allowed") 290 test.Assert(t, policy.allowedKeys.RSA3072, "RSA 3072 should be allowed") 291 test.Assert(t, policy.allowedKeys.RSA4096, "RSA 4096 should be allowed") 292 test.Assert(t, policy.allowedKeys.ECDSAP256, "NIST P256 should be allowed") 293 test.Assert(t, policy.allowedKeys.ECDSAP384, "NIST P384 should be allowed") 294 test.Assert(t, !policy.allowedKeys.ECDSAP521, "NIST P521 should not be allowed") 295 296 policy, err = NewPolicy(&Config{}, nil) 297 test.AssertNotError(t, err, "NewPolicy with nil config.AllowedKeys failed") 298 test.Assert(t, policy.allowedKeys.RSA2048, "RSA 2048 should be allowed") 299 test.Assert(t, policy.allowedKeys.RSA3072, "RSA 3072 should be allowed") 300 test.Assert(t, policy.allowedKeys.RSA4096, "RSA 4096 should be allowed") 301 test.Assert(t, policy.allowedKeys.ECDSAP256, "NIST P256 should be allowed") 302 test.Assert(t, policy.allowedKeys.ECDSAP384, "NIST P384 should be allowed") 303 test.Assert(t, !policy.allowedKeys.ECDSAP521, "NIST P521 should not be allowed") 304 } 305 306 func TestRSAStrangeSize(t *testing.T) { 307 k := &rsa.PublicKey{N: big.NewInt(10)} 308 err := testingPolicy.GoodKey(context.Background(), k) 309 test.AssertError(t, err, "expected GoodKey to fail") 310 test.AssertEquals(t, err.Error(), "key size not supported: 4") 311 } 312 313 func TestCheckPrimeFactorsTooClose(t *testing.T) { 314 type testCase struct { 315 name string 316 p string 317 q string 318 expectRounds int 319 } 320 321 testCases := []testCase{ 322 { 323 // The factors 59 and 101 multiply to 5959. The values a and b calculated 324 // by Fermat's method will be 80 and 21. The ceil of the square root of 325 // 5959 is 78. Therefore it takes 3 rounds of Fermat's method to find the 326 // factors. 327 name: "tiny", 328 p: "101", 329 q: "59", 330 expectRounds: 3, 331 }, 332 { 333 // These factors differ only in their second-to-last digit. They're so close 334 // that a single iteration of Fermat's method is sufficient to find them. 335 name: "very close", 336 p: "12451309173743450529024753538187635497858772172998414407116324997634262083672423797183640278969532658774374576700091736519352600717664126766443002156788367", 337 q: "12451309173743450529024753538187635497858772172998414407116324997634262083672423797183640278969532658774374576700091736519352600717664126766443002156788337", 338 expectRounds: 1, 339 }, 340 { 341 // These factors differ by slightly more than 2^256, which takes fourteen 342 // rounds to factor. 343 name: "still too close", 344 p: "11779932606551869095289494662458707049283241949932278009554252037480401854504909149712949171865707598142483830639739537075502512627849249573564209082969463", 345 q: "11779932606551869095289494662458707049283241949932278009554252037480401854503793357623711855670284027157475142731886267090836872063809791989556295953329083", 346 expectRounds: 14, 347 }, 348 { 349 // These factors come from a real canon printer in the wild with a broken 350 // key generation mechanism. 351 name: "canon printer (2048 bit, 1 round)", 352 p: "155536235030272749691472293262418471207550926406427515178205576891522284497518443889075039382254334975506248481615035474816604875321501901699955105345417152355947783063521554077194367454070647740704883461064399268622437721385112646454393005862535727615809073410746393326688230040267160616554768771412289114449", 353 q: "155536235030272749691472293262418471207550926406427515178205576891522284497518443889075039382254334975506248481615035474816604875321501901699955105345417152355947783063521554077194367454070647740704883461064399268622437721385112646454393005862535727615809073410746393326688230040267160616554768771412289114113", 354 expectRounds: 1, 355 }, 356 { 357 // These factors come from a real innsbruck printer in the wild with a 358 // broken key generation mechanism. 359 name: "innsbruck printer (4096 bit, 1 round)", 360 p: "25868808535211632564072019392873831934145242707953960515208595626279836366691068618582894100813803673421320899654654938470888358089618966238341690624345530870988951109006149164192566967552401505863871260691612081236189439839963332690997129144163260418447718577834226720411404568398865166471102885763673744513186211985402019037772108416694793355840983833695882936201196462579254234744648546792097397517107797153785052856301942321429858537224127598198913168345965493941246097657533085617002572245972336841716321849601971924830462771411171570422802773095537171762650402420866468579928479284978914972383512240254605625661", 361 q: "25868808535211632564072019392873831934145242707953960515208595626279836366691068618582894100813803673421320899654654938470888358089618966238341690624345530870988951109006149164192566967552401505863871260691612081236189439839963332690997129144163260418447718577834226720411404568398865166471102885763673744513186211985402019037772108416694793355840983833695882936201196462579254234744648546792097397517107797153785052856301942321429858537224127598198913168345965493941246097657533085617002572245972336841716321849601971924830462771411171570422802773095537171762650402420866468579928479284978914972383512240254605624819", 362 expectRounds: 1, 363 }, 364 { 365 // FIPS requires that |p-q| > 2^(nlen/2 - 100). For example, a 2048-bit 366 // RSA key must have prime factors with a difference of at least 2^924. 367 // These two factors have a difference of exactly 2^924 + 4, just *barely* 368 // FIPS-compliant. Their first different digit is in column 52 of this 369 // file, which makes them vastly further apart than the cases above. Their 370 // product cannot be factored even with 100,000,000 rounds of Fermat's 371 // Algorithm. 372 name: "barely FIPS compliant (2048 bit)", 373 p: "151546560166767007654995655231369126386504564489055366370313539237722892921762327477057109592614214965864835328962951695621854530739049166771701397343693962526456985866167580660948398404000483264137738772983130282095332559392185543017295488346592188097443414824871619976114874896240350402349774470198190454623", 374 q: "151546560166767007654995655231510939369872272987323309037144546294925352276321214430320942815891873491060949332482502812040326472743233767963240491605860423063942576391584034077877871768428333113881339606298282107984376151546711223157061364850161576363709081794948857957944390170575452970542651659150041855843", 375 expectRounds: -1, 376 }, 377 } 378 379 for _, tc := range testCases { 380 t.Run(tc.name, func(t *testing.T) { 381 p, ok := new(big.Int).SetString(tc.p, 10) 382 if !ok { 383 t.Fatalf("failed to load prime factor p (%s)", tc.p) 384 } 385 386 q, ok := new(big.Int).SetString(tc.q, 10) 387 if !ok { 388 t.Fatalf("failed to load prime factor q (%s)", tc.q) 389 } 390 391 n := new(big.Int).Mul(p, q) 392 err := checkPrimeFactorsTooClose(n, 100) 393 394 if tc.expectRounds > 0 { 395 test.AssertError(t, err, "failed to factor n") 396 test.AssertContains(t, err.Error(), fmt.Sprintf("p: %s", tc.p)) 397 test.AssertContains(t, err.Error(), fmt.Sprintf("q: %s", tc.q)) 398 test.AssertContains(t, err.Error(), fmt.Sprintf("in %d rounds", tc.expectRounds)) 399 } else { 400 test.AssertNil(t, err, "factored the unfactorable") 401 } 402 }) 403 } 404 } 405 406 func benchFermat(rounds int, b *testing.B) { 407 n := big.NewInt(0) 408 n.SetString("801622717394169050106926578578301725055526605503706912100006286161529273473377413824975745384114446662904851914935980611269769546695796451504160869649117000521094368058953989236438103975426680952076533198797388295193391779933559668812684470909409457778161223896975426492372231040386646816154793996920467596916193680611886097694746368434138296683172992347929528214464827172059378866098534956467670429228681248968588692628197119606249988365750115578731538804653322115223303388019261933988266126675740797091559541980722545880793708750882230374320698192373040882555154628949384420712168289605526223733016176898368282023301917856921049583659644200174763940543991507836551835324807116188739389620816364505209568211448815747330488813651206715564392791134964121857454359816296832013457790067067190116393364546525054134704119475840526673114964766611499226043189928040037210929720682839683846078550615582181112536768195193557758454282232948765374797970874053642822355832904812487562117265271449547063765654262549173209805579494164339236981348054782533307762260970390747872669357067489756517340817289701322583209366268084923373164395703994945233187987667632964509271169622904359262117908604555420100186491963838567445541249128944592555657626247", 10) 409 for b.Loop() { 410 if checkPrimeFactorsTooClose(n, rounds) != nil { 411 b.Fatal("factored the unfactorable!") 412 } 413 } 414 } 415 416 func BenchmarkFermat1(b *testing.B) { benchFermat(1, b) } 417 func BenchmarkFermat10(b *testing.B) { benchFermat(10, b) } 418 func BenchmarkFermat100(b *testing.B) { benchFermat(100, b) } 419 func BenchmarkFermat1000(b *testing.B) { benchFermat(1000, b) } 420 func BenchmarkFermat10000(b *testing.B) { benchFermat(10000, b) }