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 var testingPolicy = &KeyPolicy{
17 AllowRSA: true,
18 AllowECDSANISTP256: true,
19 AllowECDSANISTP384: true,
20 }
21
22 func TestUnknownKeyType(t *testing.T) {
23 notAKey := struct{}{}
24 err := testingPolicy.GoodKey(context.Background(), notAKey)
25 test.AssertError(t, err, "Should have rejected a key of unknown type")
26 test.AssertEquals(t, err.Error(), "unsupported key type struct {}")
27
28
29 testingPolicyWithBlockedKeys := *testingPolicy
30 testingPolicyWithBlockedKeys.blockedList = &blockedKeys{}
31 err = testingPolicyWithBlockedKeys.GoodKey(context.Background(), notAKey)
32 test.AssertError(t, err, "Should have rejected a key of unknown type")
33 test.AssertEquals(t, err.Error(), "unsupported key type struct {}")
34 }
35
36 func TestNilKey(t *testing.T) {
37 err := testingPolicy.GoodKey(context.Background(), nil)
38 test.AssertError(t, err, "Should have rejected a nil key")
39 test.AssertEquals(t, err.Error(), "unsupported key type <nil>")
40 }
41
42 func TestSmallModulus(t *testing.T) {
43 pubKey := rsa.PublicKey{
44 N: big.NewInt(0),
45 E: 65537,
46 }
47
48 _, ok := pubKey.N.SetString("104192126510885102608953552259747211060428328569316484779167706297543848858189721071301121307701498317286069484848193969810800653457088975832436062805901725915630417996487259956349018066196416400386483594314258078114607080545265502078791826837453107382149801328758721235866366842649389274931060463277516954884108984101391466769505088222180613883737986792254164577832157921425082478871935498631777878563742033332460445633026471887331001305450139473524438241478798689974351175769895824322173301257621327448162705637127373457350813027123239805772024171112299987923305882261194120410409098448380641378552305583392176287", 10)
49 if !ok {
50 t.Errorf("error parsing pubkey modulus")
51 }
52 err := testingPolicy.GoodKey(context.Background(), &pubKey)
53 test.AssertError(t, err, "Should have rejected too-short key")
54 test.AssertEquals(t, err.Error(), "key size not supported: 2040")
55 }
56
57 func TestLargeModulus(t *testing.T) {
58 pubKey := rsa.PublicKey{
59 N: big.NewInt(0),
60 E: 65537,
61 }
62
63 _, ok := pubKey.N.SetString("1528586537844618544364689295678280797814937047039447018548513699782432768815684971832418418955305671838918285565080181315448131784543332408348488544125812746629522583979538961638790013578302979210481729874191053412386396889481430969071543569003141391030053024684850548909056275565684242965892176703473950844930842702506635531145654194239072799616096020023445127233557468234181352398708456163013484600764686209741158795461806441111028922165846800488957692595308009319392149669715238691709012014980470238746838534949750493558807218940354555205690667168930634644030378921382266510932028134500172599110460167962515262077587741235811653717121760943005253103187409557573174347385738572144714188928416780963680160418832333908040737262282830643745963536624555340279793555475547508851494656512855403492456740439533790565640263514349940712999516725281940465613417922773583725174223806589481568984323871222072582132221706797917380250216291620957692131931099423995355390698925093903005385497308399692769135287821632877871068909305276870015125960884987746154344006895331078411141197233179446805991116541744285238281451294472577537413640009811940462311100056023815261650331552185459228689469446389165886801876700815724561451940764544990177661873073", 10)
64 if !ok {
65 t.Errorf("error parsing pubkey modulus")
66 }
67 err := testingPolicy.GoodKey(context.Background(), &pubKey)
68 test.AssertError(t, err, "Should have rejected too-long key")
69 test.AssertEquals(t, err.Error(), "key size not supported: 4097")
70 }
71
72 func TestModulusModulo8(t *testing.T) {
73 bigOne := big.NewInt(1)
74 key := rsa.PublicKey{
75 N: bigOne.Lsh(bigOne, 2048),
76 E: 5,
77 }
78 err := testingPolicy.GoodKey(context.Background(), &key)
79 test.AssertError(t, err, "Should have rejected modulus with length not divisible by 8")
80 test.AssertEquals(t, err.Error(), "key size not supported: 2049")
81 }
82
83 var mod2048 = big.NewInt(0).Sub(big.NewInt(0).Lsh(big.NewInt(1), 2048), big.NewInt(1))
84
85 func TestNonStandardExp(t *testing.T) {
86 evenMod := big.NewInt(0).Add(big.NewInt(1).Lsh(big.NewInt(1), 2047), big.NewInt(2))
87 key := rsa.PublicKey{
88 N: evenMod,
89 E: (1 << 16),
90 }
91 err := testingPolicy.GoodKey(context.Background(), &key)
92 test.AssertError(t, err, "Should have rejected non-standard exponent")
93 test.AssertEquals(t, err.Error(), "key exponent must be 65537")
94 }
95
96 func TestEvenModulus(t *testing.T) {
97 evenMod := big.NewInt(0).Add(big.NewInt(1).Lsh(big.NewInt(1), 2047), big.NewInt(2))
98 key := rsa.PublicKey{
99 N: evenMod,
100 E: (1 << 16) + 1,
101 }
102 err := testingPolicy.GoodKey(context.Background(), &key)
103 test.AssertError(t, err, "Should have rejected even modulus")
104 test.AssertEquals(t, err.Error(), "key divisible by small prime")
105 }
106
107 func TestModulusDivisibleBySmallPrime(t *testing.T) {
108 key := rsa.PublicKey{
109 N: mod2048,
110 E: (1 << 16) + 1,
111 }
112 err := testingPolicy.GoodKey(context.Background(), &key)
113 test.AssertError(t, err, "Should have rejected modulus divisible by 3")
114 test.AssertEquals(t, err.Error(), "key divisible by small prime")
115 }
116
117 func TestROCA(t *testing.T) {
118 n, ok := big.NewInt(1).SetString("19089470491547632015867380494603366846979936677899040455785311493700173635637619562546319438505971838982429681121352968394792665704951454132311441831732124044135181992768774222852895664400681270897445415599851900461316070972022018317962889565731866601557238345786316235456299813772607869009873279585912430769332375239444892105064608255089298943707214066350230292124208314161171265468111771687514518823144499250339825049199688099820304852696380797616737008621384107235756455735861506433065173933123259184114000282435500939123478591192413006994709825840573671701120771013072419520134975733578923370992644987545261926257", 10)
119 if !ok {
120 t.Fatal("failed to parse")
121 }
122 key := rsa.PublicKey{
123 N: n,
124 E: 65537,
125 }
126 err := testingPolicy.GoodKey(context.Background(), &key)
127 test.AssertError(t, err, "Should have rejected ROCA-weak key")
128 test.AssertEquals(t, err.Error(), "key generated by vulnerable Infineon-based hardware")
129 }
130
131 func TestGoodKey(t *testing.T) {
132 private, err := rsa.GenerateKey(rand.Reader, 2048)
133 test.AssertNotError(t, err, "Error generating key")
134 test.AssertNotError(t, testingPolicy.GoodKey(context.Background(), &private.PublicKey), "Should have accepted good key")
135 }
136
137 func TestECDSABadCurve(t *testing.T) {
138 for _, curve := range invalidCurves {
139 private, err := ecdsa.GenerateKey(curve, rand.Reader)
140 test.AssertNotError(t, err, "Error generating key")
141 err = testingPolicy.GoodKey(context.Background(), &private.PublicKey)
142 test.AssertError(t, err, "Should have rejected key with unsupported curve")
143 test.AssertEquals(t, err.Error(), fmt.Sprintf("ECDSA curve %s not allowed", curve.Params().Name))
144 }
145 }
146
147 var invalidCurves = []elliptic.Curve{
148 elliptic.P224(),
149 elliptic.P521(),
150 }
151
152 var validCurves = []elliptic.Curve{
153 elliptic.P256(),
154 elliptic.P384(),
155 }
156
157 func TestECDSAGoodKey(t *testing.T) {
158 for _, curve := range validCurves {
159 private, err := ecdsa.GenerateKey(curve, rand.Reader)
160 test.AssertNotError(t, err, "Error generating key")
161 test.AssertNotError(t, testingPolicy.GoodKey(context.Background(), &private.PublicKey), "Should have accepted good key")
162 }
163 }
164
165 func TestECDSANotOnCurveX(t *testing.T) {
166 for _, curve := range validCurves {
167
168 private, err := ecdsa.GenerateKey(curve, rand.Reader)
169 test.AssertNotError(t, err, "Error generating key")
170
171 private.X.Add(private.X, big.NewInt(1))
172 err = testingPolicy.GoodKey(context.Background(), &private.PublicKey)
173 test.AssertError(t, err, "Should not have accepted key not on the curve")
174 test.AssertEquals(t, err.Error(), "key point is not on the curve")
175 }
176 }
177
178 func TestECDSANotOnCurveY(t *testing.T) {
179 for _, curve := range validCurves {
180
181 private, err := ecdsa.GenerateKey(curve, rand.Reader)
182 test.AssertNotError(t, err, "Error generating key")
183
184
185 private.Y.Add(private.Y, big.NewInt(1))
186 err = testingPolicy.GoodKey(context.Background(), &private.PublicKey)
187 test.AssertError(t, err, "Should not have accepted key not on the curve")
188 test.AssertEquals(t, err.Error(), "key point is not on the curve")
189 }
190 }
191
192 func TestECDSANegative(t *testing.T) {
193 for _, curve := range validCurves {
194
195 private, err := ecdsa.GenerateKey(curve, rand.Reader)
196 test.AssertNotError(t, err, "Error generating key")
197
198 private.X.Neg(private.X)
199 err = testingPolicy.GoodKey(context.Background(), &private.PublicKey)
200 test.AssertError(t, err, "Should not have accepted key with negative X")
201 test.AssertEquals(t, err.Error(), "key x, y must not be negative")
202
203
204 private.X.Neg(private.X)
205 private.Y.Neg(private.Y)
206 err = testingPolicy.GoodKey(context.Background(), &private.PublicKey)
207 test.AssertError(t, err, "Should not have accepted key with negative Y")
208 test.AssertEquals(t, err.Error(), "key x, y must not be negative")
209 }
210 }
211
212 func TestECDSAXOutsideField(t *testing.T) {
213 for _, curve := range validCurves {
214
215 private, err := ecdsa.GenerateKey(curve, rand.Reader)
216 test.AssertNotError(t, err, "Error generating key")
217
218 private.X.Mul(private.X, private.Curve.Params().P)
219 err = testingPolicy.GoodKey(context.Background(), &private.PublicKey)
220 test.AssertError(t, err, "Should not have accepted key with a X > p-1")
221 test.AssertEquals(t, err.Error(), "key x, y must not exceed P-1")
222 }
223 }
224
225 func TestECDSAYOutsideField(t *testing.T) {
226 for _, curve := range validCurves {
227
228 private, err := ecdsa.GenerateKey(curve, rand.Reader)
229 test.AssertNotError(t, err, "Error generating key")
230
231 private.X.Mul(private.Y, private.Curve.Params().P)
232 err = testingPolicy.GoodKey(context.Background(), &private.PublicKey)
233 test.AssertError(t, err, "Should not have accepted key with a Y > p-1")
234 test.AssertEquals(t, err.Error(), "key x, y must not exceed P-1")
235 }
236 }
237
238 func TestECDSAIdentity(t *testing.T) {
239 for _, curve := range validCurves {
240
241 public := ecdsa.PublicKey{
242 Curve: curve,
243 X: big.NewInt(0),
244 Y: big.NewInt(0),
245 }
246
247 err := testingPolicy.GoodKey(context.Background(), &public)
248 test.AssertError(t, err, "Should not have accepted key with point at infinity")
249 test.AssertEquals(t, err.Error(), "key x, y must not be the point at infinity")
250 }
251 }
252
253 func TestNonRefKey(t *testing.T) {
254 private, err := rsa.GenerateKey(rand.Reader, 2048)
255 test.AssertNotError(t, err, "Error generating key")
256 test.AssertError(t, testingPolicy.GoodKey(context.Background(), private.PublicKey), "Accepted non-reference key")
257 }
258
259 func TestDBBlocklistAccept(t *testing.T) {
260 for _, testCheck := range []BlockedKeyCheckFunc{
261 nil,
262 func(context.Context, []byte) (bool, error) {
263 return false, nil
264 },
265 } {
266 policy, err := NewKeyPolicy(&Config{}, testCheck)
267 test.AssertNotError(t, err, "NewKeyPolicy failed")
268
269 k, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
270 test.AssertNotError(t, err, "ecdsa.GenerateKey failed")
271 err = policy.GoodKey(context.Background(), k.Public())
272 test.AssertNotError(t, err, "GoodKey failed with a non-blocked key")
273 }
274 }
275
276 func TestDBBlocklistReject(t *testing.T) {
277 testCheck := func(context.Context, []byte) (bool, error) {
278 return true, nil
279 }
280
281 policy, err := NewKeyPolicy(&Config{}, testCheck)
282 test.AssertNotError(t, err, "NewKeyPolicy failed")
283
284 k, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
285 test.AssertNotError(t, err, "ecdsa.GenerateKey failed")
286 err = policy.GoodKey(context.Background(), k.Public())
287 test.AssertError(t, err, "GoodKey didn't fail with a blocked key")
288 test.AssertErrorIs(t, err, ErrBadKey)
289 test.AssertEquals(t, err.Error(), "public key is forbidden")
290 }
291
292 func TestRSAStrangeSize(t *testing.T) {
293 k := &rsa.PublicKey{N: big.NewInt(10)}
294 err := testingPolicy.GoodKey(context.Background(), k)
295 test.AssertError(t, err, "expected GoodKey to fail")
296 test.AssertEquals(t, err.Error(), "key size not supported: 4")
297 }
298
299 func TestCheckPrimeFactorsTooClose(t *testing.T) {
300
301
302
303 n := big.NewInt(5959)
304 err := checkPrimeFactorsTooClose(n, 2)
305 test.AssertNotError(t, err, "factored n in too few iterations")
306 err = checkPrimeFactorsTooClose(n, 3)
307 test.AssertError(t, err, "failed to factor n")
308 test.AssertContains(t, err.Error(), "p: 101")
309 test.AssertContains(t, err.Error(), "q: 59")
310
311
312
313 p, ok := new(big.Int).SetString("12451309173743450529024753538187635497858772172998414407116324997634262083672423797183640278969532658774374576700091736519352600717664126766443002156788367", 10)
314 test.Assert(t, ok, "failed to create large prime")
315 q, ok := new(big.Int).SetString("12451309173743450529024753538187635497858772172998414407116324997634262083672423797183640278969532658774374576700091736519352600717664126766443002156788337", 10)
316 test.Assert(t, ok, "failed to create large prime")
317 n = n.Mul(p, q)
318 err = checkPrimeFactorsTooClose(n, 0)
319 test.AssertNotError(t, err, "factored n in too few iterations")
320 err = checkPrimeFactorsTooClose(n, 1)
321 test.AssertError(t, err, "failed to factor n")
322 test.AssertContains(t, err.Error(), fmt.Sprintf("p: %s", p))
323 test.AssertContains(t, err.Error(), fmt.Sprintf("q: %s", q))
324
325
326 p, ok = p.SetString("11779932606551869095289494662458707049283241949932278009554252037480401854504909149712949171865707598142483830639739537075502512627849249573564209082969463", 10)
327 test.Assert(t, ok, "failed to create large prime")
328 q, ok = q.SetString("11779932606551869095289494662458707049283241949932278009554252037480401854503793357623711855670284027157475142731886267090836872063809791989556295953329083", 10)
329 test.Assert(t, ok, "failed to create large prime")
330 n = n.Mul(p, q)
331 err = checkPrimeFactorsTooClose(n, 13)
332 test.AssertNotError(t, err, "factored n in too few iterations")
333 err = checkPrimeFactorsTooClose(n, 14)
334 test.AssertError(t, err, "failed to factor n")
335 test.AssertContains(t, err.Error(), fmt.Sprintf("p: %s", p))
336 test.AssertContains(t, err.Error(), fmt.Sprintf("q: %s", q))
337 }
338
339 func benchFermat(rounds int, b *testing.B) {
340 n := big.NewInt(0)
341 n.SetString("801622717394169050106926578578301725055526605503706912100006286161529273473377413824975745384114446662904851914935980611269769546695796451504160869649117000521094368058953989236438103975426680952076533198797388295193391779933559668812684470909409457778161223896975426492372231040386646816154793996920467596916193680611886097694746368434138296683172992347929528214464827172059378866098534956467670429228681248968588692628197119606249988365750115578731538804653322115223303388019261933988266126675740797091559541980722545880793708750882230374320698192373040882555154628949384420712168289605526223733016176898368282023301917856921049583659644200174763940543991507836551835324807116188739389620816364505209568211448815747330488813651206715564392791134964121857454359816296832013457790067067190116393364546525054134704119475840526673114964766611499226043189928040037210929720682839683846078550615582181112536768195193557758454282232948765374797970874053642822355832904812487562117265271449547063765654262549173209805579494164339236981348054782533307762260970390747872669357067489756517340817289701322583209366268084923373164395703994945233187987667632964509271169622904359262117908604555420100186491963838567445541249128944592555657626247", 10)
342 for i := 0; i < b.N; i++ {
343 if checkPrimeFactorsTooClose(n, rounds) != nil {
344 b.Fatal("factored the unfactorable!")
345 }
346 }
347 }
348
349 func BenchmarkFermat1(b *testing.B) { benchFermat(1, b) }
350 func BenchmarkFermat10(b *testing.B) { benchFermat(10, b) }
351 func BenchmarkFermat100(b *testing.B) { benchFermat(100, b) }
352 func BenchmarkFermat1000(b *testing.B) { benchFermat(1000, b) }
353 func BenchmarkFermat10000(b *testing.B) { benchFermat(10000, b) }
354
View as plain text