1package dns 2 3import ( 4 "crypto" 5 "crypto/ecdsa" 6 "crypto/rsa" 7 "reflect" 8 "strings" 9 "testing" 10 "time" 11) 12 13func getKey() *DNSKEY { 14 key := new(DNSKEY) 15 key.Hdr.Name = "miek.nl." 16 key.Hdr.Class = ClassINET 17 key.Hdr.Ttl = 14400 18 key.Flags = 256 19 key.Protocol = 3 20 key.Algorithm = RSASHA256 21 key.PublicKey = "AwEAAcNEU67LJI5GEgF9QLNqLO1SMq1EdoQ6E9f85ha0k0ewQGCblyW2836GiVsm6k8Kr5ECIoMJ6fZWf3CQSQ9ycWfTyOHfmI3eQ/1Covhb2y4bAmL/07PhrL7ozWBW3wBfM335Ft9xjtXHPy7ztCbV9qZ4TVDTW/Iyg0PiwgoXVesz" 22 return key 23} 24 25func getSoa() *SOA { 26 soa := new(SOA) 27 soa.Hdr = RR_Header{"miek.nl.", TypeSOA, ClassINET, 14400, 0} 28 soa.Ns = "open.nlnetlabs.nl." 29 soa.Mbox = "miekg.atoom.net." 30 soa.Serial = 1293945905 31 soa.Refresh = 14400 32 soa.Retry = 3600 33 soa.Expire = 604800 34 soa.Minttl = 86400 35 return soa 36} 37 38func TestGenerateEC(t *testing.T) { 39 if testing.Short() { 40 t.Skip("skipping test in short mode.") 41 } 42 key := new(DNSKEY) 43 key.Hdr.Rrtype = TypeDNSKEY 44 key.Hdr.Name = "miek.nl." 45 key.Hdr.Class = ClassINET 46 key.Hdr.Ttl = 14400 47 key.Flags = 256 48 key.Protocol = 3 49 key.Algorithm = ECDSAP256SHA256 50 privkey, _ := key.Generate(256) 51 t.Log(key.String()) 52 t.Log(key.PrivateKeyString(privkey)) 53} 54 55func TestGenerateDSA(t *testing.T) { 56 if testing.Short() { 57 t.Skip("skipping test in short mode.") 58 } 59 key := new(DNSKEY) 60 key.Hdr.Rrtype = TypeDNSKEY 61 key.Hdr.Name = "miek.nl." 62 key.Hdr.Class = ClassINET 63 key.Hdr.Ttl = 14400 64 key.Flags = 256 65 key.Protocol = 3 66 key.Algorithm = DSA 67 privkey, _ := key.Generate(1024) 68 t.Log(key.String()) 69 t.Log(key.PrivateKeyString(privkey)) 70} 71 72func TestGenerateRSA(t *testing.T) { 73 if testing.Short() { 74 t.Skip("skipping test in short mode.") 75 } 76 key := new(DNSKEY) 77 key.Hdr.Rrtype = TypeDNSKEY 78 key.Hdr.Name = "miek.nl." 79 key.Hdr.Class = ClassINET 80 key.Hdr.Ttl = 14400 81 key.Flags = 256 82 key.Protocol = 3 83 key.Algorithm = RSASHA256 84 privkey, _ := key.Generate(1024) 85 t.Log(key.String()) 86 t.Log(key.PrivateKeyString(privkey)) 87} 88 89func TestSecure(t *testing.T) { 90 soa := getSoa() 91 92 sig := new(RRSIG) 93 sig.Hdr = RR_Header{"miek.nl.", TypeRRSIG, ClassINET, 14400, 0} 94 sig.TypeCovered = TypeSOA 95 sig.Algorithm = RSASHA256 96 sig.Labels = 2 97 sig.Expiration = 1296534305 // date -u '+%s' -d"2011-02-01 04:25:05" 98 sig.Inception = 1293942305 // date -u '+%s' -d"2011-01-02 04:25:05" 99 sig.OrigTtl = 14400 100 sig.KeyTag = 12051 101 sig.SignerName = "miek.nl." 102 sig.Signature = "oMCbslaAVIp/8kVtLSms3tDABpcPRUgHLrOR48OOplkYo+8TeEGWwkSwaz/MRo2fB4FxW0qj/hTlIjUGuACSd+b1wKdH5GvzRJc2pFmxtCbm55ygAh4EUL0F6U5cKtGJGSXxxg6UFCQ0doJCmiGFa78LolaUOXImJrk6AFrGa0M=" 103 104 key := new(DNSKEY) 105 key.Hdr.Name = "miek.nl." 106 key.Hdr.Class = ClassINET 107 key.Hdr.Ttl = 14400 108 key.Flags = 256 109 key.Protocol = 3 110 key.Algorithm = RSASHA256 111 key.PublicKey = "AwEAAcNEU67LJI5GEgF9QLNqLO1SMq1EdoQ6E9f85ha0k0ewQGCblyW2836GiVsm6k8Kr5ECIoMJ6fZWf3CQSQ9ycWfTyOHfmI3eQ/1Covhb2y4bAmL/07PhrL7ozWBW3wBfM335Ft9xjtXHPy7ztCbV9qZ4TVDTW/Iyg0PiwgoXVesz" 112 113 // It should validate. Period is checked separately, so this will keep on working 114 if sig.Verify(key, []RR{soa}) != nil { 115 t.Error("failure to validate") 116 } 117} 118 119func TestSignature(t *testing.T) { 120 sig := new(RRSIG) 121 sig.Hdr.Name = "miek.nl." 122 sig.Hdr.Class = ClassINET 123 sig.Hdr.Ttl = 3600 124 sig.TypeCovered = TypeDNSKEY 125 sig.Algorithm = RSASHA1 126 sig.Labels = 2 127 sig.OrigTtl = 4000 128 sig.Expiration = 1000 //Thu Jan 1 02:06:40 CET 1970 129 sig.Inception = 800 //Thu Jan 1 01:13:20 CET 1970 130 sig.KeyTag = 34641 131 sig.SignerName = "miek.nl." 132 sig.Signature = "AwEAAaHIwpx3w4VHKi6i1LHnTaWeHCL154Jug0Rtc9ji5qwPXpBo6A5sRv7cSsPQKPIwxLpyCrbJ4mr2L0EPOdvP6z6YfljK2ZmTbogU9aSU2fiq/4wjxbdkLyoDVgtO+JsxNN4bjr4WcWhsmk1Hg93FV9ZpkWb0Tbad8DFqNDzr//kZ" 133 134 // Should not be valid 135 if sig.ValidityPeriod(time.Now()) { 136 t.Error("should not be valid") 137 } 138 139 sig.Inception = 315565800 //Tue Jan 1 10:10:00 CET 1980 140 sig.Expiration = 4102477800 //Fri Jan 1 10:10:00 CET 2100 141 if !sig.ValidityPeriod(time.Now()) { 142 t.Error("should be valid") 143 } 144} 145 146func TestSignVerify(t *testing.T) { 147 // The record we want to sign 148 soa := new(SOA) 149 soa.Hdr = RR_Header{"miek.nl.", TypeSOA, ClassINET, 14400, 0} 150 soa.Ns = "open.nlnetlabs.nl." 151 soa.Mbox = "miekg.atoom.net." 152 soa.Serial = 1293945905 153 soa.Refresh = 14400 154 soa.Retry = 3600 155 soa.Expire = 604800 156 soa.Minttl = 86400 157 158 soa1 := new(SOA) 159 soa1.Hdr = RR_Header{"*.miek.nl.", TypeSOA, ClassINET, 14400, 0} 160 soa1.Ns = "open.nlnetlabs.nl." 161 soa1.Mbox = "miekg.atoom.net." 162 soa1.Serial = 1293945905 163 soa1.Refresh = 14400 164 soa1.Retry = 3600 165 soa1.Expire = 604800 166 soa1.Minttl = 86400 167 168 srv := new(SRV) 169 srv.Hdr = RR_Header{"srv.miek.nl.", TypeSRV, ClassINET, 14400, 0} 170 srv.Port = 1000 171 srv.Weight = 800 172 srv.Target = "web1.miek.nl." 173 174 hinfo := &HINFO{ 175 Hdr: RR_Header{ 176 Name: "miek.nl.", 177 Rrtype: TypeHINFO, 178 Class: ClassINET, 179 Ttl: 3789, 180 }, 181 Cpu: "X", 182 Os: "Y", 183 } 184 185 // With this key 186 key := new(DNSKEY) 187 key.Hdr.Rrtype = TypeDNSKEY 188 key.Hdr.Name = "miek.nl." 189 key.Hdr.Class = ClassINET 190 key.Hdr.Ttl = 14400 191 key.Flags = 256 192 key.Protocol = 3 193 key.Algorithm = RSASHA256 194 privkey, _ := key.Generate(512) 195 196 // Fill in the values of the Sig, before signing 197 sig := new(RRSIG) 198 sig.Hdr = RR_Header{"miek.nl.", TypeRRSIG, ClassINET, 14400, 0} 199 sig.TypeCovered = soa.Hdr.Rrtype 200 sig.Labels = uint8(CountLabel(soa.Hdr.Name)) // works for all 3 201 sig.OrigTtl = soa.Hdr.Ttl 202 sig.Expiration = 1296534305 // date -u '+%s' -d"2011-02-01 04:25:05" 203 sig.Inception = 1293942305 // date -u '+%s' -d"2011-01-02 04:25:05" 204 sig.KeyTag = key.KeyTag() // Get the keyfrom the Key 205 sig.SignerName = key.Hdr.Name 206 sig.Algorithm = RSASHA256 207 208 for _, r := range []RR{soa, soa1, srv, hinfo} { 209 if err := sig.Sign(privkey.(*rsa.PrivateKey), []RR{r}); err != nil { 210 t.Error("failure to sign the record:", err) 211 continue 212 } 213 if err := sig.Verify(key, []RR{r}); err != nil { 214 t.Error("failure to validate") 215 continue 216 } 217 t.Logf("validated: %s", r.Header().Name) 218 } 219} 220 221func Test65534(t *testing.T) { 222 t6 := new(RFC3597) 223 t6.Hdr = RR_Header{"miek.nl.", 65534, ClassINET, 14400, 0} 224 t6.Rdata = "505D870001" 225 key := new(DNSKEY) 226 key.Hdr.Name = "miek.nl." 227 key.Hdr.Rrtype = TypeDNSKEY 228 key.Hdr.Class = ClassINET 229 key.Hdr.Ttl = 14400 230 key.Flags = 256 231 key.Protocol = 3 232 key.Algorithm = RSASHA256 233 privkey, _ := key.Generate(1024) 234 235 sig := new(RRSIG) 236 sig.Hdr = RR_Header{"miek.nl.", TypeRRSIG, ClassINET, 14400, 0} 237 sig.TypeCovered = t6.Hdr.Rrtype 238 sig.Labels = uint8(CountLabel(t6.Hdr.Name)) 239 sig.OrigTtl = t6.Hdr.Ttl 240 sig.Expiration = 1296534305 // date -u '+%s' -d"2011-02-01 04:25:05" 241 sig.Inception = 1293942305 // date -u '+%s' -d"2011-01-02 04:25:05" 242 sig.KeyTag = key.KeyTag() 243 sig.SignerName = key.Hdr.Name 244 sig.Algorithm = RSASHA256 245 if err := sig.Sign(privkey.(*rsa.PrivateKey), []RR{t6}); err != nil { 246 t.Error(err) 247 t.Error("failure to sign the TYPE65534 record") 248 } 249 if err := sig.Verify(key, []RR{t6}); err != nil { 250 t.Error(err) 251 t.Error("failure to validate") 252 } else { 253 t.Logf("validated: %s", t6.Header().Name) 254 } 255} 256 257func TestDnskey(t *testing.T) { 258 pubkey, err := ReadRR(strings.NewReader(` 259miek.nl. IN DNSKEY 256 3 10 AwEAAZuMCu2FdugHkTrXYgl5qixvcDw1aDDlvL46/xJKbHBAHY16fNUb2b65cwko2Js/aJxUYJbZk5dwCDZxYfrfbZVtDPQuc3o8QaChVxC7/JYz2AHc9qHvqQ1j4VrH71RWINlQo6VYjzN/BGpMhOZoZOEwzp1HfsOE3lNYcoWU1smL ;{id = 5240 (zsk), size = 1024b} 260`), "Kmiek.nl.+010+05240.key") 261 if err != nil { 262 t.Fatal(err) 263 } 264 privStr := `Private-key-format: v1.3 265Algorithm: 10 (RSASHA512) 266Modulus: m4wK7YV26AeROtdiCXmqLG9wPDVoMOW8vjr/EkpscEAdjXp81RvZvrlzCSjYmz9onFRgltmTl3AINnFh+t9tlW0M9C5zejxBoKFXELv8ljPYAdz2oe+pDWPhWsfvVFYg2VCjpViPM38EakyE5mhk4TDOnUd+w4TeU1hyhZTWyYs= 267PublicExponent: AQAB 268PrivateExponent: UfCoIQ/Z38l8vB6SSqOI/feGjHEl/fxIPX4euKf0D/32k30fHbSaNFrFOuIFmWMB3LimWVEs6u3dpbB9CQeCVg7hwU5puG7OtuiZJgDAhNeOnxvo5btp4XzPZrJSxR4WNQnwIiYWbl0aFlL1VGgHC/3By89ENZyWaZcMLW4KGWE= 269Prime1: yxwC6ogAu8aVcDx2wg1V0b5M5P6jP8qkRFVMxWNTw60Vkn+ECvw6YAZZBHZPaMyRYZLzPgUlyYRd0cjupy4+fQ== 270Prime2: xA1bF8M0RTIQ6+A11AoVG6GIR/aPGg5sogRkIZ7ID/sF6g9HMVU/CM2TqVEBJLRPp73cv6ZeC3bcqOCqZhz+pw== 271Exponent1: xzkblyZ96bGYxTVZm2/vHMOXswod4KWIyMoOepK6B/ZPcZoIT6omLCgtypWtwHLfqyCz3MK51Nc0G2EGzg8rFQ== 272Exponent2: Pu5+mCEb7T5F+kFNZhQadHUklt0JUHbi3hsEvVoHpEGSw3BGDQrtIflDde0/rbWHgDPM4WQY+hscd8UuTXrvLw== 273Coefficient: UuRoNqe7YHnKmQzE6iDWKTMIWTuoqqrFAmXPmKQnC+Y+BQzOVEHUo9bXdDnoI9hzXP1gf8zENMYwYLeWpuYlFQ== 274` 275 privkey, err := pubkey.(*DNSKEY).ReadPrivateKey(strings.NewReader(privStr), 276 "Kmiek.nl.+010+05240.private") 277 if err != nil { 278 t.Fatal(err) 279 } 280 if pubkey.(*DNSKEY).PublicKey != "AwEAAZuMCu2FdugHkTrXYgl5qixvcDw1aDDlvL46/xJKbHBAHY16fNUb2b65cwko2Js/aJxUYJbZk5dwCDZxYfrfbZVtDPQuc3o8QaChVxC7/JYz2AHc9qHvqQ1j4VrH71RWINlQo6VYjzN/BGpMhOZoZOEwzp1HfsOE3lNYcoWU1smL" { 281 t.Error("pubkey is not what we've read") 282 } 283 if pubkey.(*DNSKEY).PrivateKeyString(privkey) != privStr { 284 t.Error("privkey is not what we've read") 285 t.Errorf("%v", pubkey.(*DNSKEY).PrivateKeyString(privkey)) 286 } 287} 288 289func TestTag(t *testing.T) { 290 key := new(DNSKEY) 291 key.Hdr.Name = "miek.nl." 292 key.Hdr.Rrtype = TypeDNSKEY 293 key.Hdr.Class = ClassINET 294 key.Hdr.Ttl = 3600 295 key.Flags = 256 296 key.Protocol = 3 297 key.Algorithm = RSASHA256 298 key.PublicKey = "AwEAAcNEU67LJI5GEgF9QLNqLO1SMq1EdoQ6E9f85ha0k0ewQGCblyW2836GiVsm6k8Kr5ECIoMJ6fZWf3CQSQ9ycWfTyOHfmI3eQ/1Covhb2y4bAmL/07PhrL7ozWBW3wBfM335Ft9xjtXHPy7ztCbV9qZ4TVDTW/Iyg0PiwgoXVesz" 299 300 tag := key.KeyTag() 301 if tag != 12051 { 302 t.Errorf("wrong key tag: %d for key %v", tag, key) 303 } 304} 305 306func TestKeyRSA(t *testing.T) { 307 if testing.Short() { 308 t.Skip("skipping test in short mode.") 309 } 310 key := new(DNSKEY) 311 key.Hdr.Name = "miek.nl." 312 key.Hdr.Rrtype = TypeDNSKEY 313 key.Hdr.Class = ClassINET 314 key.Hdr.Ttl = 3600 315 key.Flags = 256 316 key.Protocol = 3 317 key.Algorithm = RSASHA256 318 priv, _ := key.Generate(2048) 319 320 soa := new(SOA) 321 soa.Hdr = RR_Header{"miek.nl.", TypeSOA, ClassINET, 14400, 0} 322 soa.Ns = "open.nlnetlabs.nl." 323 soa.Mbox = "miekg.atoom.net." 324 soa.Serial = 1293945905 325 soa.Refresh = 14400 326 soa.Retry = 3600 327 soa.Expire = 604800 328 soa.Minttl = 86400 329 330 sig := new(RRSIG) 331 sig.Hdr = RR_Header{"miek.nl.", TypeRRSIG, ClassINET, 14400, 0} 332 sig.TypeCovered = TypeSOA 333 sig.Algorithm = RSASHA256 334 sig.Labels = 2 335 sig.Expiration = 1296534305 // date -u '+%s' -d"2011-02-01 04:25:05" 336 sig.Inception = 1293942305 // date -u '+%s' -d"2011-01-02 04:25:05" 337 sig.OrigTtl = soa.Hdr.Ttl 338 sig.KeyTag = key.KeyTag() 339 sig.SignerName = key.Hdr.Name 340 341 if err := sig.Sign(priv.(*rsa.PrivateKey), []RR{soa}); err != nil { 342 t.Error("failed to sign") 343 return 344 } 345 if err := sig.Verify(key, []RR{soa}); err != nil { 346 t.Error("failed to verify") 347 } 348} 349 350func TestKeyToDS(t *testing.T) { 351 key := new(DNSKEY) 352 key.Hdr.Name = "miek.nl." 353 key.Hdr.Rrtype = TypeDNSKEY 354 key.Hdr.Class = ClassINET 355 key.Hdr.Ttl = 3600 356 key.Flags = 256 357 key.Protocol = 3 358 key.Algorithm = RSASHA256 359 key.PublicKey = "AwEAAcNEU67LJI5GEgF9QLNqLO1SMq1EdoQ6E9f85ha0k0ewQGCblyW2836GiVsm6k8Kr5ECIoMJ6fZWf3CQSQ9ycWfTyOHfmI3eQ/1Covhb2y4bAmL/07PhrL7ozWBW3wBfM335Ft9xjtXHPy7ztCbV9qZ4TVDTW/Iyg0PiwgoXVesz" 360 361 ds := key.ToDS(SHA1) 362 if strings.ToUpper(ds.Digest) != "B5121BDB5B8D86D0CC5FFAFBAAABE26C3E20BAC1" { 363 t.Errorf("wrong DS digest for SHA1\n%v", ds) 364 } 365} 366 367func TestSignRSA(t *testing.T) { 368 pub := "miek.nl. IN DNSKEY 256 3 5 AwEAAb+8lGNCxJgLS8rYVer6EnHVuIkQDghdjdtewDzU3G5R7PbMbKVRvH2Ma7pQyYceoaqWZQirSj72euPWfPxQnMy9ucCylA+FuH9cSjIcPf4PqJfdupHk9X6EBYjxrCLY4p1/yBwgyBIRJtZtAqM3ceAH2WovEJD6rTtOuHo5AluJ" 369 370 priv := `Private-key-format: v1.3 371Algorithm: 5 (RSASHA1) 372Modulus: v7yUY0LEmAtLythV6voScdW4iRAOCF2N217APNTcblHs9sxspVG8fYxrulDJhx6hqpZlCKtKPvZ649Z8/FCczL25wLKUD4W4f1xKMhw9/g+ol926keT1foQFiPGsItjinX/IHCDIEhEm1m0Cozdx4AfZai8QkPqtO064ejkCW4k= 373PublicExponent: AQAB 374PrivateExponent: YPwEmwjk5HuiROKU4xzHQ6l1hG8Iiha4cKRG3P5W2b66/EN/GUh07ZSf0UiYB67o257jUDVEgwCuPJz776zfApcCB4oGV+YDyEu7Hp/rL8KcSN0la0k2r9scKwxTp4BTJT23zyBFXsV/1wRDK1A5NxsHPDMYi2SoK63Enm/1ptk= 375Prime1: /wjOG+fD0ybNoSRn7nQ79udGeR1b0YhUA5mNjDx/x2fxtIXzygYk0Rhx9QFfDy6LOBvz92gbNQlzCLz3DJt5hw== 376Prime2: wHZsJ8OGhkp5p3mrJFZXMDc2mbYusDVTA+t+iRPdS797Tj0pjvU2HN4vTnTj8KBQp6hmnY7dLp9Y1qserySGbw== 377Exponent1: N0A7FsSRIg+IAN8YPQqlawoTtG1t1OkJ+nWrurPootScApX6iMvn8fyvw3p2k51rv84efnzpWAYiC8SUaQDNxQ== 378Exponent2: SvuYRaGyvo0zemE3oS+WRm2scxR8eiA8WJGeOc+obwOKCcBgeZblXzfdHGcEC1KaOcetOwNW/vwMA46lpLzJNw== 379Coefficient: 8+7ZN/JgByqv0NfULiFKTjtyegUcijRuyij7yNxYbCBneDvZGxJwKNi4YYXWx743pcAj4Oi4Oh86gcmxLs+hGw== 380Created: 20110302104537 381Publish: 20110302104537 382Activate: 20110302104537` 383 384 xk, _ := NewRR(pub) 385 k := xk.(*DNSKEY) 386 p, err := k.NewPrivateKey(priv) 387 if err != nil { 388 t.Error(err) 389 } 390 switch priv := p.(type) { 391 case *rsa.PrivateKey: 392 if 65537 != priv.PublicKey.E { 393 t.Error("exponenent should be 65537") 394 } 395 default: 396 t.Errorf("we should have read an RSA key: %v", priv) 397 } 398 if k.KeyTag() != 37350 { 399 t.Errorf("keytag should be 37350, got %d %v", k.KeyTag(), k) 400 } 401 402 soa := new(SOA) 403 soa.Hdr = RR_Header{"miek.nl.", TypeSOA, ClassINET, 14400, 0} 404 soa.Ns = "open.nlnetlabs.nl." 405 soa.Mbox = "miekg.atoom.net." 406 soa.Serial = 1293945905 407 soa.Refresh = 14400 408 soa.Retry = 3600 409 soa.Expire = 604800 410 soa.Minttl = 86400 411 412 sig := new(RRSIG) 413 sig.Hdr = RR_Header{"miek.nl.", TypeRRSIG, ClassINET, 14400, 0} 414 sig.Expiration = 1296534305 // date -u '+%s' -d"2011-02-01 04:25:05" 415 sig.Inception = 1293942305 // date -u '+%s' -d"2011-01-02 04:25:05" 416 sig.KeyTag = k.KeyTag() 417 sig.SignerName = k.Hdr.Name 418 sig.Algorithm = k.Algorithm 419 420 sig.Sign(p.(*rsa.PrivateKey), []RR{soa}) 421 if sig.Signature != "D5zsobpQcmMmYsUMLxCVEtgAdCvTu8V/IEeP4EyLBjqPJmjt96bwM9kqihsccofA5LIJ7DN91qkCORjWSTwNhzCv7bMyr2o5vBZElrlpnRzlvsFIoAZCD9xg6ZY7ZyzUJmU6IcTwG4v3xEYajcpbJJiyaw/RqR90MuRdKPiBzSo=" { 422 t.Errorf("signature is not correct: %v", sig) 423 } 424} 425 426func TestSignVerifyECDSA(t *testing.T) { 427 pub := `example.net. 3600 IN DNSKEY 257 3 14 ( 428 xKYaNhWdGOfJ+nPrL8/arkwf2EY3MDJ+SErKivBVSum1 429 w/egsXvSADtNJhyem5RCOpgQ6K8X1DRSEkrbYQ+OB+v8 430 /uX45NBwY8rp65F6Glur8I/mlVNgF6W/qTI37m40 )` 431 priv := `Private-key-format: v1.2 432Algorithm: 14 (ECDSAP384SHA384) 433PrivateKey: WURgWHCcYIYUPWgeLmiPY2DJJk02vgrmTfitxgqcL4vwW7BOrbawVmVe0d9V94SR` 434 435 eckey, err := NewRR(pub) 436 if err != nil { 437 t.Fatal(err) 438 } 439 privkey, err := eckey.(*DNSKEY).NewPrivateKey(priv) 440 if err != nil { 441 t.Fatal(err) 442 } 443 // TODO: Create separate test for this 444 ds := eckey.(*DNSKEY).ToDS(SHA384) 445 if ds.KeyTag != 10771 { 446 t.Fatal("wrong keytag on DS") 447 } 448 if ds.Digest != "72d7b62976ce06438e9c0bf319013cf801f09ecc84b8d7e9495f27e305c6a9b0563a9b5f4d288405c3008a946df983d6" { 449 t.Fatal("wrong DS Digest") 450 } 451 a, _ := NewRR("www.example.net. 3600 IN A 192.0.2.1") 452 sig := new(RRSIG) 453 sig.Hdr = RR_Header{"example.net.", TypeRRSIG, ClassINET, 14400, 0} 454 sig.Expiration, _ = StringToTime("20100909102025") 455 sig.Inception, _ = StringToTime("20100812102025") 456 sig.KeyTag = eckey.(*DNSKEY).KeyTag() 457 sig.SignerName = eckey.(*DNSKEY).Hdr.Name 458 sig.Algorithm = eckey.(*DNSKEY).Algorithm 459 460 if sig.Sign(privkey.(*ecdsa.PrivateKey), []RR{a}) != nil { 461 t.Fatal("failure to sign the record") 462 } 463 464 if err := sig.Verify(eckey.(*DNSKEY), []RR{a}); err != nil { 465 t.Fatalf("failure to validate:\n%s\n%s\n%s\n\n%s\n\n%v", 466 eckey.(*DNSKEY).String(), 467 a.String(), 468 sig.String(), 469 eckey.(*DNSKEY).PrivateKeyString(privkey), 470 err, 471 ) 472 } 473} 474 475func TestSignVerifyECDSA2(t *testing.T) { 476 srv1, err := NewRR("srv.miek.nl. IN SRV 1000 800 0 web1.miek.nl.") 477 if err != nil { 478 t.Fatal(err) 479 } 480 srv := srv1.(*SRV) 481 482 // With this key 483 key := new(DNSKEY) 484 key.Hdr.Rrtype = TypeDNSKEY 485 key.Hdr.Name = "miek.nl." 486 key.Hdr.Class = ClassINET 487 key.Hdr.Ttl = 14400 488 key.Flags = 256 489 key.Protocol = 3 490 key.Algorithm = ECDSAP256SHA256 491 privkey, err := key.Generate(256) 492 if err != nil { 493 t.Fatal("failure to generate key") 494 } 495 496 // Fill in the values of the Sig, before signing 497 sig := new(RRSIG) 498 sig.Hdr = RR_Header{"miek.nl.", TypeRRSIG, ClassINET, 14400, 0} 499 sig.TypeCovered = srv.Hdr.Rrtype 500 sig.Labels = uint8(CountLabel(srv.Hdr.Name)) // works for all 3 501 sig.OrigTtl = srv.Hdr.Ttl 502 sig.Expiration = 1296534305 // date -u '+%s' -d"2011-02-01 04:25:05" 503 sig.Inception = 1293942305 // date -u '+%s' -d"2011-01-02 04:25:05" 504 sig.KeyTag = key.KeyTag() // Get the keyfrom the Key 505 sig.SignerName = key.Hdr.Name 506 sig.Algorithm = ECDSAP256SHA256 507 508 if sig.Sign(privkey.(*ecdsa.PrivateKey), []RR{srv}) != nil { 509 t.Fatal("failure to sign the record") 510 } 511 512 err = sig.Verify(key, []RR{srv}) 513 if err != nil { 514 t.Logf("failure to validate:\n%s\n%s\n%s\n\n%s\n\n%v", 515 key.String(), 516 srv.String(), 517 sig.String(), 518 key.PrivateKeyString(privkey), 519 err, 520 ) 521 } 522} 523 524// Here the test vectors from the relevant RFCs are checked. 525// rfc6605 6.1 526func TestRFC6605P256(t *testing.T) { 527 exDNSKEY := `example.net. 3600 IN DNSKEY 257 3 13 ( 528 GojIhhXUN/u4v54ZQqGSnyhWJwaubCvTmeexv7bR6edb 529 krSqQpF64cYbcB7wNcP+e+MAnLr+Wi9xMWyQLc8NAA== )` 530 exPriv := `Private-key-format: v1.2 531Algorithm: 13 (ECDSAP256SHA256) 532PrivateKey: GU6SnQ/Ou+xC5RumuIUIuJZteXT2z0O/ok1s38Et6mQ=` 533 rrDNSKEY, err := NewRR(exDNSKEY) 534 if err != nil { 535 t.Fatal(err) 536 } 537 priv, err := rrDNSKEY.(*DNSKEY).NewPrivateKey(exPriv) 538 if err != nil { 539 t.Fatal(err) 540 } 541 542 exDS := `example.net. 3600 IN DS 55648 13 2 ( 543 b4c8c1fe2e7477127b27115656ad6256f424625bf5c1 544 e2770ce6d6e37df61d17 )` 545 rrDS, err := NewRR(exDS) 546 if err != nil { 547 t.Fatal(err) 548 } 549 ourDS := rrDNSKEY.(*DNSKEY).ToDS(SHA256) 550 if !reflect.DeepEqual(ourDS, rrDS.(*DS)) { 551 t.Errorf("DS record differs:\n%v\n%v", ourDS, rrDS.(*DS)) 552 } 553 554 exA := `www.example.net. 3600 IN A 192.0.2.1` 555 exRRSIG := `www.example.net. 3600 IN RRSIG A 13 3 3600 ( 556 20100909100439 20100812100439 55648 example.net. 557 qx6wLYqmh+l9oCKTN6qIc+bw6ya+KJ8oMz0YP107epXA 558 yGmt+3SNruPFKG7tZoLBLlUzGGus7ZwmwWep666VCw== )` 559 rrA, err := NewRR(exA) 560 if err != nil { 561 t.Fatal(err) 562 } 563 rrRRSIG, err := NewRR(exRRSIG) 564 if err != nil { 565 t.Fatal(err) 566 } 567 if err = rrRRSIG.(*RRSIG).Verify(rrDNSKEY.(*DNSKEY), []RR{rrA}); err != nil { 568 t.Errorf("failure to validate the spec RRSIG: %v", err) 569 } 570 571 ourRRSIG := &RRSIG{ 572 Hdr: RR_Header{ 573 Ttl: rrA.Header().Ttl, 574 }, 575 KeyTag: rrDNSKEY.(*DNSKEY).KeyTag(), 576 SignerName: rrDNSKEY.(*DNSKEY).Hdr.Name, 577 Algorithm: rrDNSKEY.(*DNSKEY).Algorithm, 578 } 579 ourRRSIG.Expiration, _ = StringToTime("20100909100439") 580 ourRRSIG.Inception, _ = StringToTime("20100812100439") 581 err = ourRRSIG.Sign(priv.(*ecdsa.PrivateKey), []RR{rrA}) 582 if err != nil { 583 t.Fatal(err) 584 } 585 586 if err = ourRRSIG.Verify(rrDNSKEY.(*DNSKEY), []RR{rrA}); err != nil { 587 t.Errorf("failure to validate our RRSIG: %v", err) 588 } 589 590 // Signatures are randomized 591 rrRRSIG.(*RRSIG).Signature = "" 592 ourRRSIG.Signature = "" 593 if !reflect.DeepEqual(ourRRSIG, rrRRSIG.(*RRSIG)) { 594 t.Fatalf("RRSIG record differs:\n%v\n%v", ourRRSIG, rrRRSIG.(*RRSIG)) 595 } 596} 597 598// rfc6605 6.2 599func TestRFC6605P384(t *testing.T) { 600 exDNSKEY := `example.net. 3600 IN DNSKEY 257 3 14 ( 601 xKYaNhWdGOfJ+nPrL8/arkwf2EY3MDJ+SErKivBVSum1 602 w/egsXvSADtNJhyem5RCOpgQ6K8X1DRSEkrbYQ+OB+v8 603 /uX45NBwY8rp65F6Glur8I/mlVNgF6W/qTI37m40 )` 604 exPriv := `Private-key-format: v1.2 605Algorithm: 14 (ECDSAP384SHA384) 606PrivateKey: WURgWHCcYIYUPWgeLmiPY2DJJk02vgrmTfitxgqcL4vwW7BOrbawVmVe0d9V94SR` 607 rrDNSKEY, err := NewRR(exDNSKEY) 608 if err != nil { 609 t.Fatal(err) 610 } 611 priv, err := rrDNSKEY.(*DNSKEY).NewPrivateKey(exPriv) 612 if err != nil { 613 t.Fatal(err) 614 } 615 616 exDS := `example.net. 3600 IN DS 10771 14 4 ( 617 72d7b62976ce06438e9c0bf319013cf801f09ecc84b8 618 d7e9495f27e305c6a9b0563a9b5f4d288405c3008a94 619 6df983d6 )` 620 rrDS, err := NewRR(exDS) 621 if err != nil { 622 t.Fatal(err) 623 } 624 ourDS := rrDNSKEY.(*DNSKEY).ToDS(SHA384) 625 if !reflect.DeepEqual(ourDS, rrDS.(*DS)) { 626 t.Fatalf("DS record differs:\n%v\n%v", ourDS, rrDS.(*DS)) 627 } 628 629 exA := `www.example.net. 3600 IN A 192.0.2.1` 630 exRRSIG := `www.example.net. 3600 IN RRSIG A 14 3 3600 ( 631 20100909102025 20100812102025 10771 example.net. 632 /L5hDKIvGDyI1fcARX3z65qrmPsVz73QD1Mr5CEqOiLP 633 95hxQouuroGCeZOvzFaxsT8Glr74hbavRKayJNuydCuz 634 WTSSPdz7wnqXL5bdcJzusdnI0RSMROxxwGipWcJm )` 635 rrA, err := NewRR(exA) 636 if err != nil { 637 t.Fatal(err) 638 } 639 rrRRSIG, err := NewRR(exRRSIG) 640 if err != nil { 641 t.Fatal(err) 642 } 643 if err = rrRRSIG.(*RRSIG).Verify(rrDNSKEY.(*DNSKEY), []RR{rrA}); err != nil { 644 t.Errorf("failure to validate the spec RRSIG: %v", err) 645 } 646 647 ourRRSIG := &RRSIG{ 648 Hdr: RR_Header{ 649 Ttl: rrA.Header().Ttl, 650 }, 651 KeyTag: rrDNSKEY.(*DNSKEY).KeyTag(), 652 SignerName: rrDNSKEY.(*DNSKEY).Hdr.Name, 653 Algorithm: rrDNSKEY.(*DNSKEY).Algorithm, 654 } 655 ourRRSIG.Expiration, _ = StringToTime("20100909102025") 656 ourRRSIG.Inception, _ = StringToTime("20100812102025") 657 err = ourRRSIG.Sign(priv.(*ecdsa.PrivateKey), []RR{rrA}) 658 if err != nil { 659 t.Fatal(err) 660 } 661 662 if err = ourRRSIG.Verify(rrDNSKEY.(*DNSKEY), []RR{rrA}); err != nil { 663 t.Errorf("failure to validate our RRSIG: %v", err) 664 } 665 666 // Signatures are randomized 667 rrRRSIG.(*RRSIG).Signature = "" 668 ourRRSIG.Signature = "" 669 if !reflect.DeepEqual(ourRRSIG, rrRRSIG.(*RRSIG)) { 670 t.Fatalf("RRSIG record differs:\n%v\n%v", ourRRSIG, rrRRSIG.(*RRSIG)) 671 } 672} 673 674func TestInvalidRRSet(t *testing.T) { 675 goodRecords := make([]RR, 2) 676 goodRecords[0] = &TXT{Hdr: RR_Header{Name: "name.cloudflare.com.", Rrtype: TypeTXT, Class: ClassINET, Ttl: 0}, Txt: []string{"Hello world"}} 677 goodRecords[1] = &TXT{Hdr: RR_Header{Name: "name.cloudflare.com.", Rrtype: TypeTXT, Class: ClassINET, Ttl: 0}, Txt: []string{"_o/"}} 678 679 // Generate key 680 keyname := "cloudflare.com." 681 key := &DNSKEY{ 682 Hdr: RR_Header{Name: keyname, Rrtype: TypeDNSKEY, Class: ClassINET, Ttl: 0}, 683 Algorithm: ECDSAP256SHA256, 684 Flags: ZONE, 685 Protocol: 3, 686 } 687 privatekey, err := key.Generate(256) 688 if err != nil { 689 t.Fatal(err.Error()) 690 } 691 692 // Need to fill in: Inception, Expiration, KeyTag, SignerName and Algorithm 693 curTime := time.Now() 694 signature := &RRSIG{ 695 Inception: uint32(curTime.Unix()), 696 Expiration: uint32(curTime.Add(time.Hour).Unix()), 697 KeyTag: key.KeyTag(), 698 SignerName: keyname, 699 Algorithm: ECDSAP256SHA256, 700 } 701 702 // Inconsistent name between records 703 badRecords := make([]RR, 2) 704 badRecords[0] = &TXT{Hdr: RR_Header{Name: "name.cloudflare.com.", Rrtype: TypeTXT, Class: ClassINET, Ttl: 0}, Txt: []string{"Hello world"}} 705 badRecords[1] = &TXT{Hdr: RR_Header{Name: "nama.cloudflare.com.", Rrtype: TypeTXT, Class: ClassINET, Ttl: 0}, Txt: []string{"_o/"}} 706 707 if IsRRset(badRecords) { 708 t.Fatal("Record set with inconsistent names considered valid") 709 } 710 711 badRecords[0] = &TXT{Hdr: RR_Header{Name: "name.cloudflare.com.", Rrtype: TypeTXT, Class: ClassINET, Ttl: 0}, Txt: []string{"Hello world"}} 712 badRecords[1] = &A{Hdr: RR_Header{Name: "name.cloudflare.com.", Rrtype: TypeA, Class: ClassINET, Ttl: 0}} 713 714 if IsRRset(badRecords) { 715 t.Fatal("Record set with inconsistent record types considered valid") 716 } 717 718 badRecords[0] = &TXT{Hdr: RR_Header{Name: "name.cloudflare.com.", Rrtype: TypeTXT, Class: ClassINET, Ttl: 0}, Txt: []string{"Hello world"}} 719 badRecords[1] = &TXT{Hdr: RR_Header{Name: "name.cloudflare.com.", Rrtype: TypeTXT, Class: ClassCHAOS, Ttl: 0}, Txt: []string{"_o/"}} 720 721 if IsRRset(badRecords) { 722 t.Fatal("Record set with inconsistent record class considered valid") 723 } 724 725 // Sign the good record set and then make sure verification fails on the bad record set 726 if err := signature.Sign(privatekey.(crypto.Signer), goodRecords); err != nil { 727 t.Fatal("Signing good records failed") 728 } 729 730 if err := signature.Verify(key, badRecords); err != ErrRRset { 731 t.Fatal("Verification did not return ErrRRset with inconsistent records") 732 } 733} 734