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