More parsing stuff

This commit is contained in:
Miek Gieben 2011-07-17 15:47:03 +02:00
parent b2c50a39f6
commit 8c595abe56
7 changed files with 472 additions and 415 deletions

View File

@ -117,15 +117,16 @@ func (k *RR_DNSKEY) ReadPrivateKey(q io.Reader) (PrivateKey, os.Error) {
if _, ok := kv["private-key-format"]; !ok {
return nil, ErrPrivKey
}
if kv["private-key-format"] != "v1.2" || kv["private-key-format"] != "v1.3" {
if kv["private-key-format"] != "v1.2" && kv["private-key-format"] != "v1.3" {
return nil, ErrPrivKey
}
switch kv["algorithm"] {
switch kv["algorithm"] {
case "RSAMD5", "RSASHA1", "RSASHA256", "RSASHA512":
return k.readPrivateKeyRSA(kv)
case "ECDSAP256SHA256", "ECDSAP384SHA384":
return k.readPrivateKeyECDSA(kv)
}
println("SOMETHING WRONG\n\n")
return nil, ErrKey
}
@ -135,38 +136,41 @@ func (k *RR_DNSKEY) readPrivateKeyRSA(kv map[string]string) (PrivateKey, os.Erro
p.Primes = []*big.Int{nil,nil}
for k, v := range kv {
switch k {
case "Modulus", "PublicExponent", "PrivateExponent", "Prime1", "Prime2":
case "modulus", "publicexponent", "privateexponent", "prime1", "prime2":
v1, err := packBase64([]byte(v))
if err != nil {
return nil, err
}
switch k {
case "Modulus":
case "modulus":
p.PublicKey.N = big.NewInt(0)
p.PublicKey.N.SetBytes(v1)
case "PublicExponent":
println("modulus",v)
case "publicexponent":
i := big.NewInt(0)
i.SetBytes(v1)
p.PublicKey.E = int(i.Int64()) // int64 should be large enough
case "PrivateExponent":
println("publicexponent",v)
case "privateexponent":
p.D = big.NewInt(0)
p.D.SetBytes(v1)
case "Prime1":
case "prime1":
p.Primes[0] = big.NewInt(0)
p.Primes[0].SetBytes(v1)
case "Prime2":
case "prime2":
p.Primes[1] = big.NewInt(0)
p.Primes[1].SetBytes(v1)
}
case "Exponent1", "Exponent2", "Coefficient":
case "exponent1", "exponent2", "coefficient":
// not used in Go (yet)
case "Created", "Publish", "Activate":
case "created", "publish", "activate":
// not used in Go (yet)
default:
return nil, ErrKey
}
}
if ! k.setPublicKeyRSA(p.PublicKey.E, p.PublicKey.N) {
println("Failure to set")
return nil, ErrKey
}
return p, nil
@ -177,13 +181,13 @@ func (k *RR_DNSKEY) readPrivateKeyECDSA(kv map[string]string) (PrivateKey, os.Er
p.D = big.NewInt(0)
for k, v := range kv {
switch k {
case "PrivateKey:":
case "privatekey:":
v1, err := packBase64([]byte(v))
if err != nil {
return nil, err
}
p.D.SetBytes(v1)
case "Created:", "Publish:", "Activate:":
case "created:", "publish:", "activate:":
/* not used in Go (yet) */
default:
return nil, ErrKey

140
kparse.go
View File

@ -13,16 +13,19 @@ import (
// line 16 "kparse.go"
var k_start int = 109
var k_first_final int = 109
var k_start int = 111
var k_first_final int = 111
var k_error int = 0
var k_en_main int = 109
var k_en_main int = 111
// line 15 "kparse.rl"
// Parse a private key file as defined in XXX.
// A map[string]string is returned with the values. All the keys
// are in lowercase. The algorithm is returned as m[algorithm] = "RSASHA1"
func Kparse(q io.Reader) (m map[string]string, err os.Error) {
r := bufio.NewReader(q)
@ -34,54 +37,55 @@ func Kparse(q io.Reader) (m map[string]string, err os.Error) {
mark := 0
// line 38 "kparse.go"
// line 41 "kparse.go"
cs = k_start
// line 41 "kparse.go"
// line 44 "kparse.go"
{
if p == pe { goto _test_eof }
switch cs {
case -666: // i am a hack D:
tr13:
// line 30 "kparse.rl"
// line 33 "kparse.rl"
{ m[k] = data[mark:p] }
goto st109
goto st111
tr28:
// line 31 "kparse.rl"
{ m[k] = data[mark:p-1] }
goto st109
// line 34 "kparse.rl"
{ m[k] = strings.ToUpper(data[mark:p-1]) }
goto st111
tr40:
// line 30 "kparse.rl"
// line 33 "kparse.rl"
{ m[k] = data[mark:p] }
// line 31 "kparse.rl"
{ m[k] = data[mark:p-1] }
goto st109
st109:
// line 34 "kparse.rl"
{ m[k] = strings.ToUpper(data[mark:p-1]) }
goto st111
st111:
p++
if p == pe { goto _test_eof109 }
if p == pe { goto _test_eof111 }
fallthrough
case 109:
// line 65 "kparse.go"
case 111:
// line 68 "kparse.go"
switch data[p] {
case 65: goto tr108
case 67: goto tr109
case 69: goto tr110
case 71: goto tr111
case 77: goto tr112
case 80: goto tr113
case 97: goto tr108
case 99: goto tr109
case 101: goto tr110
case 103: goto tr111
case 109: goto tr112
case 112: goto tr113
case 65: goto tr110
case 67: goto tr111
case 69: goto tr112
case 71: goto tr113
case 77: goto tr114
case 80: goto tr115
case 94: goto st109
case 97: goto tr110
case 99: goto tr111
case 101: goto tr112
case 103: goto tr113
case 109: goto tr114
case 112: goto tr115
}
goto st0
st0:
cs = 0;
goto _out;
tr108:
// line 28 "kparse.rl"
tr110:
// line 31 "kparse.rl"
{ mark = p }
goto st1
st1:
@ -89,7 +93,7 @@ st1:
if p == pe { goto _test_eof1 }
fallthrough
case 1:
// line 93 "kparse.go"
// line 97 "kparse.go"
switch data[p] {
case 67: goto st2
case 76: goto st37
@ -165,7 +169,7 @@ case 8:
if data[p] == 58 { goto tr9 }
goto st0
tr9:
// line 29 "kparse.rl"
// line 32 "kparse.rl"
{ k = strings.ToLower(data[mark:p]) }
goto st9
st9:
@ -173,7 +177,7 @@ st9:
if p == pe { goto _test_eof9 }
fallthrough
case 9:
// line 177 "kparse.go"
// line 181 "kparse.go"
if data[p] == 32 { goto st10 }
goto st0
st10:
@ -204,7 +208,7 @@ case 10:
}
goto st0
tr11:
// line 28 "kparse.rl"
// line 31 "kparse.rl"
{ mark = p }
goto st11
st11:
@ -212,7 +216,7 @@ st11:
if p == pe { goto _test_eof11 }
fallthrough
case 11:
// line 216 "kparse.go"
// line 220 "kparse.go"
switch data[p] {
case 10: goto tr13
case 32: goto st11
@ -233,7 +237,7 @@ case 11:
}
goto st0
tr12:
// line 28 "kparse.rl"
// line 31 "kparse.rl"
{ mark = p }
goto st12
st12:
@ -241,7 +245,7 @@ st12:
if p == pe { goto _test_eof12 }
fallthrough
case 12:
// line 245 "kparse.go"
// line 249 "kparse.go"
switch data[p] {
case 9: goto st13
case 10: goto tr13
@ -288,7 +292,7 @@ case 14:
}
goto st0
tr19:
// line 28 "kparse.rl"
// line 31 "kparse.rl"
{ mark = p }
goto st15
st15:
@ -296,7 +300,7 @@ st15:
if p == pe { goto _test_eof15 }
fallthrough
case 15:
// line 300 "kparse.go"
// line 304 "kparse.go"
switch data[p] {
case 83: goto st16
case 115: goto st16
@ -430,7 +434,7 @@ case 26:
}
goto st0
tr31:
// line 28 "kparse.rl"
// line 31 "kparse.rl"
{ mark = p }
goto st27
st27:
@ -438,7 +442,7 @@ st27:
if p == pe { goto _test_eof27 }
fallthrough
case 27:
// line 442 "kparse.go"
// line 446 "kparse.go"
switch data[p] {
case 10: goto tr13
case 32: goto st11
@ -756,8 +760,8 @@ case 43:
case 109: goto st8
}
goto st0
tr109:
// line 28 "kparse.rl"
tr111:
// line 31 "kparse.rl"
{ mark = p }
goto st44
st44:
@ -765,7 +769,7 @@ st44:
if p == pe { goto _test_eof44 }
fallthrough
case 44:
// line 769 "kparse.go"
// line 773 "kparse.go"
switch data[p] {
case 79: goto st45
case 82: goto st54
@ -913,8 +917,8 @@ case 58:
case 100: goto st8
}
goto st0
tr110:
// line 28 "kparse.rl"
tr112:
// line 31 "kparse.rl"
{ mark = p }
goto st59
st59:
@ -922,7 +926,7 @@ st59:
if p == pe { goto _test_eof59 }
fallthrough
case 59:
// line 926 "kparse.go"
// line 930 "kparse.go"
switch data[p] {
case 88: goto st60
case 120: goto st60
@ -995,8 +999,8 @@ st66:
case 66:
if 49 <= data[p] && data[p] <= 50 { goto st8 }
goto st0
tr111:
// line 28 "kparse.rl"
tr113:
// line 31 "kparse.rl"
{ mark = p }
goto st67
st67:
@ -1004,7 +1008,7 @@ st67:
if p == pe { goto _test_eof67 }
fallthrough
case 67:
// line 1008 "kparse.go"
// line 1012 "kparse.go"
switch data[p] {
case 79: goto st68
case 111: goto st68
@ -1067,8 +1071,8 @@ st73:
case 73:
if data[p] == 49 { goto st8 }
goto st0
tr112:
// line 28 "kparse.rl"
tr114:
// line 31 "kparse.rl"
{ mark = p }
goto st74
st74:
@ -1076,7 +1080,7 @@ st74:
if p == pe { goto _test_eof74 }
fallthrough
case 74:
// line 1080 "kparse.go"
// line 1084 "kparse.go"
switch data[p] {
case 79: goto st75
case 111: goto st75
@ -1132,8 +1136,8 @@ case 79:
case 115: goto st8
}
goto st0
tr113:
// line 28 "kparse.rl"
tr115:
// line 31 "kparse.rl"
{ mark = p }
goto st80
st80:
@ -1141,7 +1145,7 @@ st80:
if p == pe { goto _test_eof80 }
fallthrough
case 80:
// line 1145 "kparse.go"
// line 1149 "kparse.go"
switch data[p] {
case 82: goto st81
case 85: goto st103
@ -1433,8 +1437,22 @@ case 108:
case 104: goto st8
}
goto st0
st109:
p++
if p == pe { goto _test_eof109 }
fallthrough
case 109:
if data[p] == 59 { goto st110 }
goto st0
st110:
p++
if p == pe { goto _test_eof110 }
fallthrough
case 110:
if data[p] == 10 { goto st111 }
goto st0
}
_test_eof109: cs = 109; goto _test_eof;
_test_eof111: cs = 111; goto _test_eof;
_test_eof1: cs = 1; goto _test_eof;
_test_eof2: cs = 2; goto _test_eof;
_test_eof3: cs = 3; goto _test_eof;
@ -1543,12 +1561,14 @@ case 108:
_test_eof106: cs = 106; goto _test_eof;
_test_eof107: cs = 107; goto _test_eof;
_test_eof108: cs = 108; goto _test_eof;
_test_eof109: cs = 109; goto _test_eof;
_test_eof110: cs = 110; goto _test_eof;
_test_eof: {}
_out: {}
}
// line 62 "kparse.rl"
// line 66 "kparse.rl"
data, err = r.ReadString('\n')
}

View File

@ -14,6 +14,9 @@ import (
write data;
}%%
// Parse a private key file as defined in XXX.
// A map[string]string is returned with the values. All the keys
// are in lowercase. The algorithm is returned as m[algorithm] = "RSASHA1"
func Kparse(q io.Reader) (m map[string]string, err os.Error) {
r := bufio.NewReader(q)
@ -28,11 +31,12 @@ func Kparse(q io.Reader) (m map[string]string, err os.Error) {
action mark { mark = p }
action setKey { k = strings.ToLower(data[mark:p]) }
action setValue { m[k] = data[mark:p] }
action setAlg { m[k] = data[mark:p-1] }
action setAlg { m[k] = strings.ToUpper(data[mark:p-1]) }
bl = [ \t]+;
base64any = [a-zA-Z0-9.\\/+=() ]+ >mark;
algorithm = ( 'RSASHA1'i | 'RSASHA256'i ) >mark;
comment = /^;/;
key = (
('Private-key-format'i)
@ -54,7 +58,7 @@ func Kparse(q io.Reader) (m map[string]string, err os.Error) {
value = ( base64any %setValue | digit+ bl '(' algorithm ')' %setAlg );
line = key ': ' value;
line = ( key ': ' value | comment );
main := ( line '\n' )*;
write init;

View File

@ -67,10 +67,11 @@ Activate: 20110109154937`
}
}
if k.KeyTag() != 41946 {
t.Logf("%v\n", k)
t.Logf("%d %v\n", k.KeyTag(), k)
t.Log("Keytag should be 41946")
t.Fail()
}
println(k.String())
soa := new(RR_SOA)
soa.Hdr = RR_Header{"miek.nl.", TypeSOA, ClassINET, 14400, 0}
@ -140,17 +141,17 @@ func TestDotInName(t *testing.T) {
// Make this a decend test case. For now, good enough
// New style (Ragel) parsing
func TestParse(t *testing.T) {
rr, _ := Zparse("miek.nl. 3600 IN A 127.0.0.1")
rr, _ := Zparse(strings.NewReader("miek.nl. 3600 IN A 127.0.0.1"))
fmt.Printf("Seen a:\n%v\n", rr)
rr, _ = Zparse("miek.nl. 3600 IN MX 10 elektron.atoom.net.")
rr, _ = Zparse(strings.NewReader("miek.nl. 3600 IN MX 10 elektron.atoom.net."))
fmt.Printf("Seen a:\n%v\n", rr)
rr, _ = Zparse("nlnetlabs.nl. 3175 IN DNSKEY 256 3 8 AwEAAdR7XR95OaAN9Rz7TbtPalQ9guQk7zfxTHYNKhsiwTZA9z+F16nD0VeBlk7dNik3ETpT2GLAwr9sntG898JwurCDe353wHPvjZtMCdiTVp3cRCrjuCEvoFpmZNN82H0gaH/4v8mkv/QBDAkDSncYjz/FqHKAeYy3cMcjY6RyVweh");
rr, _ = Zparse(strings.NewReader("nlnetlabs.nl. 3175 IN DNSKEY 256 3 8 AwEAAdR7XR95OaAN9Rz7TbtPalQ9guQk7zfxTHYNKhsiwTZA9z+F16nD0VeBlk7dNik3ETpT2GLAwr9sntG898JwurCDe353wHPvjZtMCdiTVp3cRCrjuCEvoFpmZNN82H0gaH/4v8mkv/QBDAkDSncYjz/FqHKAeYy3cMcjY6RyVweh"))
fmt.Printf("Seen a:\n%v\n", rr)
rr, _ = Zparse("miek.nl. IN A 127.0.0.1")
rr, _ = Zparse(strings.NewReader("miek.nl. IN A 127.0.0.1"))
fmt.Printf("Seen a:\n%v\n", rr)
rr, _ = Zparse("miek.nl. IN 3600 A 127.0.0.1")
rr, _ = Zparse(strings.NewReader("miek.nl. IN 3600 A 127.0.0.1"))
fmt.Printf("Seen a:\n%v\n", rr)
rr, _ = Zparse("miek.nl. A 127.0.0.1")
rr, _ = Zparse(strings.NewReader("miek.nl. A 127.0.0.1"))
fmt.Printf("Seen a:\n%v\n", rr)
}
@ -171,6 +172,6 @@ Activate: 20110302104537
`
m, _ := Kparse(strings.NewReader(a))
for k, v := range m {
fmt.Printf("%s = %s\n", k, v)
fmt.Printf("{%s}={%s}\n", k, v)
}
}

View File

@ -2,56 +2,56 @@
machine z;
action rdata_a {
r.(*RR_A).Hdr = *hdr
r.(*RR_A).A = net.ParseIP(data[mark:p])
rr.(*RR_A).Hdr = *hdr
rr.(*RR_A).A = net.ParseIP(data[mark:p])
}
action rdata_ns {
r.(*RR_NS).Hdr = *hdr
r.(*RR_NS).Ns = tok.T[0]
rr.(*RR_NS).Hdr = *hdr
rr.(*RR_NS).Ns = tok.T[0]
}
action rdata_cname {
r.(*RR_CNAME).Hdr = *hdr
r.(*RR_CNAME).Cname = tok.T[0]
rr.(*RR_CNAME).Hdr = *hdr
rr.(*RR_CNAME).Cname = tok.T[0]
}
action rdata_soa {
r.(*RR_SOA).Hdr = *hdr
r.(*RR_SOA).Ns = tok.T[0]
r.(*RR_SOA).Mbox = tok.T[1]
r.(*RR_SOA).Serial = uint32(tok.N[0])
r.(*RR_SOA).Refresh = uint32(tok.N[1])
r.(*RR_SOA).Retry = uint32(tok.N[2])
r.(*RR_SOA).Expire = uint32(tok.N[3])
r.(*RR_SOA).Minttl = uint32(tok.N[4])
rr.(*RR_SOA).Hdr = *hdr
rr.(*RR_SOA).Ns = tok.T[0]
rr.(*RR_SOA).Mbox = tok.T[1]
rr.(*RR_SOA).Serial = uint32(tok.N[0])
rr.(*RR_SOA).Refresh = uint32(tok.N[1])
rr.(*RR_SOA).Retry = uint32(tok.N[2])
rr.(*RR_SOA).Expire = uint32(tok.N[3])
rr.(*RR_SOA).Minttl = uint32(tok.N[4])
}
action rdata_mx {
r.(*RR_MX).Hdr = *hdr;
r.(*RR_MX).Pref = uint16(tok.N[0])
r.(*RR_MX).Mx = tok.T[0]
rr.(*RR_MX).Hdr = *hdr;
rr.(*RR_MX).Pref = uint16(tok.N[0])
rr.(*RR_MX).Mx = tok.T[0]
}
action rdata_ds {
r.(*RR_DS).Hdr = *hdr;
r.(*RR_DS).KeyTag = uint16(tok.N[0])
r.(*RR_DS).Algorithm = uint8(tok.N[1])
r.(*RR_DS).DigestType = uint8(tok.N[2])
r.(*RR_DS).Digest = tok.T[0]
rr.(*RR_DS).Hdr = *hdr;
rr.(*RR_DS).KeyTag = uint16(tok.N[0])
rr.(*RR_DS).Algorithm = uint8(tok.N[1])
rr.(*RR_DS).DigestType = uint8(tok.N[2])
rr.(*RR_DS).Digest = tok.T[0]
}
action rdata_dnskey {
r.(*RR_DNSKEY).Hdr = *hdr;
r.(*RR_DNSKEY).Flags = uint16(tok.N[0])
r.(*RR_DNSKEY).Protocol = uint8(tok.N[1])
r.(*RR_DNSKEY).Algorithm = uint8(tok.N[2])
r.(*RR_DNSKEY).PublicKey = tok.T[0]
rr.(*RR_DNSKEY).Hdr = *hdr;
rr.(*RR_DNSKEY).Flags = uint16(tok.N[0])
rr.(*RR_DNSKEY).Protocol = uint8(tok.N[1])
rr.(*RR_DNSKEY).Algorithm = uint8(tok.N[2])
rr.(*RR_DNSKEY).PublicKey = tok.T[0]
}
action rdata_rrsig {
r.(*RR_RRSIG).Hdr = *hdr;
r.(*RR_RRSIG).TypeCovered = uint16(tok.N[0])
r.(*RR_RRSIG).Algorithm = uint8(tok.N[1])
r.(*RR_RRSIG).Labels = uint8(tok.N[2])
r.(*RR_RRSIG).OrigTtl = uint32(tok.N[3])
r.(*RR_RRSIG).Expiration = uint32(tok.N[4])
r.(*RR_RRSIG).Inception = uint32(tok.N[5])
r.(*RR_RRSIG).KeyTag = uint16(tok.N[6])
r.(*RR_RRSIG).SignerName = tok.T[0]
r.(*RR_RRSIG).Signature = tok.T[1]
rr.(*RR_RRSIG).Hdr = *hdr;
rr.(*RR_RRSIG).TypeCovered = uint16(tok.N[0])
rr.(*RR_RRSIG).Algorithm = uint8(tok.N[1])
rr.(*RR_RRSIG).Labels = uint8(tok.N[2])
rr.(*RR_RRSIG).OrigTtl = uint32(tok.N[3])
rr.(*RR_RRSIG).Expiration = uint32(tok.N[4])
rr.(*RR_RRSIG).Inception = uint32(tok.N[5])
rr.(*RR_RRSIG).KeyTag = uint16(tok.N[6])
rr.(*RR_RRSIG).SignerName = tok.T[0]
rr.(*RR_RRSIG).Signature = tok.T[1]
}
}%%

600
zparse.go

File diff suppressed because it is too large Load Diff

View File

@ -5,11 +5,14 @@ package dns
import (
"os"
"io"
"net"
"bufio"
"strconv"
)
const _RDATAMAX = 7
const _IOBUF = 65365
// Save up tokens, after we've seen the entire rdata
// we can use this.
@ -59,7 +62,18 @@ func (to *token) reset() {
write data;
}%%
func Zparse(data string) (r RR, err os.Error) {
// only works for short io.Readers as we put the whole thing
// in a string -- needs to be extended for large files (sliding window).
func Zparse(q io.Reader) (rr RR, err os.Error) {
r := bufio.NewReader(q)
buf := make([]byte, _IOBUF)
n, err := r.Read(buf)
if err != nil {
return nil, err
}
buf = buf[:n]
data := string(buf)
cs, p, pe, eof := 0, 0, len(data), len(data)
mark := 0
hdr := new(RR_Header)
@ -81,7 +95,7 @@ func Zparse(data string) (r RR, err os.Error) {
if ! known {
// ...
}
r = mk()
rr = mk()
hdr.Rrtype = i
}
@ -132,5 +146,5 @@ func Zparse(data string) (r RR, err os.Error) {
return nil, nil
}
}
return r ,nil
return rr, nil
}