15 "github.com/bytom/vapor/crypto/ed25519"
18 // NewPrivateKey returns a PrivateKey by parsing the string s.
19 // s should be in the same form of the BIND private key files.
20 func (k *DNSKEY) NewPrivateKey(s string) (crypto.PrivateKey, error) {
21 if s == "" || s[len(s)-1] != '\n' { // We need a closing newline
22 return k.ReadPrivateKey(strings.NewReader(s+"\n"), "")
24 return k.ReadPrivateKey(strings.NewReader(s), "")
27 // ReadPrivateKey reads a private key from the io.Reader q. The string file is
28 // only used in error reporting.
29 // The public key must be known, because some cryptographic algorithms embed
30 // the public inside the privatekey.
31 func (k *DNSKEY) ReadPrivateKey(q io.Reader, file string) (crypto.PrivateKey, error) {
32 m, err := parseKey(q, file)
36 if _, ok := m["private-key-format"]; !ok {
37 return nil, ErrPrivKey
39 if m["private-key-format"] != "v1.2" && m["private-key-format"] != "v1.3" {
40 return nil, ErrPrivKey
42 // TODO(mg): check if the pubkey matches the private key
43 algo, err := strconv.ParseUint(strings.SplitN(m["algorithm"], " ", 2)[0], 10, 8)
45 return nil, ErrPrivKey
49 priv, err := readPrivateKeyDSA(m)
53 pub := k.publicKeyDSA()
63 case RSASHA1NSEC3SHA1:
68 priv, err := readPrivateKeyRSA(m)
72 pub := k.publicKeyRSA()
79 return nil, ErrPrivKey
83 priv, err := readPrivateKeyECDSA(m)
87 pub := k.publicKeyECDSA()
94 return readPrivateKeyED25519(m)
96 return nil, ErrPrivKey
100 // Read a private key (file) string and create a public key. Return the private key.
101 func readPrivateKeyRSA(m map[string]string) (*rsa.PrivateKey, error) {
102 p := new(rsa.PrivateKey)
103 p.Primes = []*big.Int{nil, nil}
104 for k, v := range m {
106 case "modulus", "publicexponent", "privateexponent", "prime1", "prime2":
107 v1, err := fromBase64([]byte(v))
113 p.PublicKey.N = big.NewInt(0)
114 p.PublicKey.N.SetBytes(v1)
115 case "publicexponent":
118 p.PublicKey.E = int(i.Int64()) // int64 should be large enough
119 case "privateexponent":
123 p.Primes[0] = big.NewInt(0)
124 p.Primes[0].SetBytes(v1)
126 p.Primes[1] = big.NewInt(0)
127 p.Primes[1].SetBytes(v1)
129 case "exponent1", "exponent2", "coefficient":
130 // not used in Go (yet)
131 case "created", "publish", "activate":
132 // not used in Go (yet)
138 func readPrivateKeyDSA(m map[string]string) (*dsa.PrivateKey, error) {
139 p := new(dsa.PrivateKey)
141 for k, v := range m {
143 case "private_value(x)":
144 v1, err := fromBase64([]byte(v))
149 case "created", "publish", "activate":
150 /* not used in Go (yet) */
156 func readPrivateKeyECDSA(m map[string]string) (*ecdsa.PrivateKey, error) {
157 p := new(ecdsa.PrivateKey)
159 // TODO: validate that the required flags are present
160 for k, v := range m {
163 v1, err := fromBase64([]byte(v))
168 case "created", "publish", "activate":
169 /* not used in Go (yet) */
175 func readPrivateKeyED25519(m map[string]string) (ed25519.PrivateKey, error) {
176 var p ed25519.PrivateKey
177 // TODO: validate that the required flags are present
178 for k, v := range m {
181 p1, err := fromBase64([]byte(v))
185 if len(p1) != ed25519.SeedSize {
186 return nil, ErrPrivKey
188 p = ed25519.NewKeyFromSeed(p1)
189 case "created", "publish", "activate":
190 /* not used in Go (yet) */
196 // parseKey reads a private key from r. It returns a map[string]string,
197 // with the key-value pairs, or an error when the file is not correct.
198 func parseKey(r io.Reader, file string) (map[string]string, error) {
199 m := make(map[string]string)
204 for l, ok := c.Next(); ok; l, ok = c.Next() {
205 // It should alternate
211 return nil, &ParseError{file, "no private key seen", l}
214 m[strings.ToLower(k)] = l.token
219 // Surface any read errors from r.
220 if err := c.Err(); err != nil {
221 return nil, &ParseError{file: file, err: err.Error()}
237 eol bool // end-of-line
240 func newKLexer(r io.Reader) *klexer {
241 br, ok := r.(io.ByteReader)
243 br = bufio.NewReaderSize(r, 1024)
255 func (kl *klexer) Err() error {
256 if kl.readErr == io.EOF {
263 // readByte returns the next byte from the input
264 func (kl *klexer) readByte() (byte, bool) {
265 if kl.readErr != nil {
269 c, err := kl.br.ReadByte()
275 // delay the newline handling until the next token is delivered,
276 // fixes off-by-one errors when reporting a parse error.
292 func (kl *klexer) Next() (lex, bool) {
301 for x, ok := kl.readByte(); ok; x, ok = kl.readByte() {
302 l.line, l.column = kl.line, kl.column
306 if commt || !kl.key {
312 // Next token is a space, eat it
316 l.token = str.String()
326 if kl.key && str.Len() == 0 {
327 // ignore empty lines
334 l.token = str.String()
345 if kl.readErr != nil && kl.readErr != io.EOF {
346 // Don't return any tokens after a read error occurs.
347 return lex{value: zEOF}, false
353 l.token = str.String()
357 return lex{value: zEOF}, false