diff options
Diffstat (limited to 'vendor/github.com/miekg/dns/dnssec_keyscan.go')
-rw-r--r-- | vendor/github.com/miekg/dns/dnssec_keyscan.go | 255 |
1 files changed, 134 insertions, 121 deletions
diff --git a/vendor/github.com/miekg/dns/dnssec_keyscan.go b/vendor/github.com/miekg/dns/dnssec_keyscan.go index e2d9d8f..6cbc284 100644 --- a/vendor/github.com/miekg/dns/dnssec_keyscan.go +++ b/vendor/github.com/miekg/dns/dnssec_keyscan.go @@ -1,9 +1,8 @@ package dns import ( - "bytes" + "bufio" "crypto" - "crypto/dsa" "crypto/ecdsa" "crypto/rsa" "io" @@ -44,26 +43,7 @@ func (k *DNSKEY) ReadPrivateKey(q io.Reader, file string) (crypto.PrivateKey, er return nil, ErrPrivKey } switch uint8(algo) { - case DSA: - priv, err := readPrivateKeyDSA(m) - if err != nil { - return nil, err - } - pub := k.publicKeyDSA() - if pub == nil { - return nil, ErrKey - } - priv.PublicKey = *pub - return priv, nil - case RSAMD5: - fallthrough - case RSASHA1: - fallthrough - case RSASHA1NSEC3SHA1: - fallthrough - case RSASHA256: - fallthrough - case RSASHA512: + case RSASHA1, RSASHA1NSEC3SHA1, RSASHA256, RSASHA512: priv, err := readPrivateKeyRSA(m) if err != nil { return nil, err @@ -74,11 +54,7 @@ func (k *DNSKEY) ReadPrivateKey(q io.Reader, file string) (crypto.PrivateKey, er } priv.PublicKey = *pub return priv, nil - case ECCGOST: - return nil, ErrPrivKey - case ECDSAP256SHA256: - fallthrough - case ECDSAP384SHA384: + case ECDSAP256SHA256, ECDSAP384SHA384: priv, err := readPrivateKeyECDSA(m) if err != nil { return nil, err @@ -92,7 +68,7 @@ func (k *DNSKEY) ReadPrivateKey(q io.Reader, file string) (crypto.PrivateKey, er case ED25519: return readPrivateKeyED25519(m) default: - return nil, ErrPrivKey + return nil, ErrAlg } } @@ -109,21 +85,16 @@ func readPrivateKeyRSA(m map[string]string) (*rsa.PrivateKey, error) { } switch k { case "modulus": - p.PublicKey.N = big.NewInt(0) - p.PublicKey.N.SetBytes(v1) + p.PublicKey.N = new(big.Int).SetBytes(v1) case "publicexponent": - i := big.NewInt(0) - i.SetBytes(v1) + i := new(big.Int).SetBytes(v1) p.PublicKey.E = int(i.Int64()) // int64 should be large enough case "privateexponent": - p.D = big.NewInt(0) - p.D.SetBytes(v1) + p.D = new(big.Int).SetBytes(v1) case "prime1": - p.Primes[0] = big.NewInt(0) - p.Primes[0].SetBytes(v1) + p.Primes[0] = new(big.Int).SetBytes(v1) case "prime2": - p.Primes[1] = big.NewInt(0) - p.Primes[1].SetBytes(v1) + p.Primes[1] = new(big.Int).SetBytes(v1) } case "exponent1", "exponent2", "coefficient": // not used in Go (yet) @@ -134,27 +105,9 @@ func readPrivateKeyRSA(m map[string]string) (*rsa.PrivateKey, error) { return p, nil } -func readPrivateKeyDSA(m map[string]string) (*dsa.PrivateKey, error) { - p := new(dsa.PrivateKey) - p.X = big.NewInt(0) - for k, v := range m { - switch k { - case "private_value(x)": - v1, err := fromBase64([]byte(v)) - if err != nil { - return nil, err - } - p.X.SetBytes(v1) - case "created", "publish", "activate": - /* not used in Go (yet) */ - } - } - return p, nil -} - func readPrivateKeyECDSA(m map[string]string) (*ecdsa.PrivateKey, error) { p := new(ecdsa.PrivateKey) - p.D = big.NewInt(0) + p.D = new(big.Int) // TODO: validate that the required flags are present for k, v := range m { switch k { @@ -181,22 +134,10 @@ func readPrivateKeyED25519(m map[string]string) (ed25519.PrivateKey, error) { if err != nil { return nil, err } - if len(p1) != 32 { + if len(p1) != ed25519.SeedSize { return nil, ErrPrivKey } - // RFC 8080 and Golang's x/crypto/ed25519 differ as to how the - // private keys are represented. RFC 8080 specifies that private - // keys be stored solely as the seed value (p1 above) while the - // ed25519 package represents them as the seed value concatenated - // to the public key, which is derived from the seed value. - // - // ed25519.GenerateKey reads exactly 32 bytes from the passed in - // io.Reader and uses them as the seed. It also derives the - // public key and produces a compatible private key. - _, p, err = ed25519.GenerateKey(bytes.NewReader(p1)) - if err != nil { - return nil, err - } + p = ed25519.NewKeyFromSeed(p1) case "created", "publish", "activate": /* not used in Go (yet) */ } @@ -207,23 +148,12 @@ func readPrivateKeyED25519(m map[string]string) (ed25519.PrivateKey, error) { // parseKey reads a private key from r. It returns a map[string]string, // with the key-value pairs, or an error when the file is not correct. func parseKey(r io.Reader, file string) (map[string]string, error) { - s, cancel := scanInit(r) m := make(map[string]string) - c := make(chan lex) - k := "" - defer func() { - cancel() - // zlexer can send up to two tokens, the next one and possibly 1 remainders. - // Do a non-blocking read. - _, ok := <-c - _, ok = <-c - if !ok { - // too bad - } - }() - // Start the lexer - go klexer(s, c) - for l := range c { + var k string + + c := newKLexer(r) + + for l, ok := c.Next(); ok; l, ok = c.Next() { // It should alternate switch l.value { case zKey: @@ -232,41 +162,111 @@ func parseKey(r io.Reader, file string) (map[string]string, error) { if k == "" { return nil, &ParseError{file, "no private key seen", l} } - //println("Setting", strings.ToLower(k), "to", l.token, "b") + m[strings.ToLower(k)] = l.token k = "" } } + + // Surface any read errors from r. + if err := c.Err(); err != nil { + return nil, &ParseError{file: file, err: err.Error()} + } + return m, nil } -// klexer scans the sourcefile and returns tokens on the channel c. -func klexer(s *scan, c chan lex) { - var l lex - str := "" // Hold the current read text - commt := false - key := true - x, err := s.tokenText() - defer close(c) - for err == nil { - l.column = s.position.Column - l.line = s.position.Line +type klexer struct { + br io.ByteReader + + readErr error + + line int + column int + + key bool + + eol bool // end-of-line +} + +func newKLexer(r io.Reader) *klexer { + br, ok := r.(io.ByteReader) + if !ok { + br = bufio.NewReaderSize(r, 1024) + } + + return &klexer{ + br: br, + + line: 1, + + key: true, + } +} + +func (kl *klexer) Err() error { + if kl.readErr == io.EOF { + return nil + } + + return kl.readErr +} + +// readByte returns the next byte from the input +func (kl *klexer) readByte() (byte, bool) { + if kl.readErr != nil { + return 0, false + } + + c, err := kl.br.ReadByte() + if err != nil { + kl.readErr = err + return 0, false + } + + // delay the newline handling until the next token is delivered, + // fixes off-by-one errors when reporting a parse error. + if kl.eol { + kl.line++ + kl.column = 0 + kl.eol = false + } + + if c == '\n' { + kl.eol = true + } else { + kl.column++ + } + + return c, true +} + +func (kl *klexer) Next() (lex, bool) { + var ( + l lex + + str strings.Builder + + commt bool + ) + + for x, ok := kl.readByte(); ok; x, ok = kl.readByte() { + l.line, l.column = kl.line, kl.column + switch x { case ':': - if commt { + if commt || !kl.key { break } - l.token = str - if key { - l.value = zKey - c <- l - // Next token is a space, eat it - s.tokenText() - key = false - str = "" - } else { - l.value = zValue - } + + kl.key = false + + // Next token is a space, eat it + kl.readByte() + + l.value = zKey + l.token = str.String() + return l, true case ';': commt = true case '\n': @@ -274,24 +274,37 @@ func klexer(s *scan, c chan lex) { // Reset a comment commt = false } + + if kl.key && str.Len() == 0 { + // ignore empty lines + break + } + + kl.key = true + l.value = zValue - l.token = str - c <- l - str = "" - commt = false - key = true + l.token = str.String() + return l, true default: if commt { break } - str += string(x) + + str.WriteByte(x) } - x, err = s.tokenText() } - if len(str) > 0 { + + if kl.readErr != nil && kl.readErr != io.EOF { + // Don't return any tokens after a read error occurs. + return lex{value: zEOF}, false + } + + if str.Len() > 0 { // Send remainder - l.token = str l.value = zValue - c <- l + l.token = str.String() + return l, true } + + return lex{value: zEOF}, false } |