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