dnssec_privkey.go 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. package dns
  2. import (
  3. "crypto"
  4. "crypto/dsa"
  5. "crypto/ecdsa"
  6. "crypto/rsa"
  7. "math/big"
  8. "strconv"
  9. )
  10. const format = "Private-key-format: v1.3\n"
  11. // PrivateKeyString converts a PrivateKey to a string. This string has the same
  12. // format as the private-key-file of BIND9 (Private-key-format: v1.3).
  13. // It needs some info from the key (the algorithm), so its a method of the DNSKEY
  14. // It supports rsa.PrivateKey, ecdsa.PrivateKey and dsa.PrivateKey
  15. func (r *DNSKEY) PrivateKeyString(p crypto.PrivateKey) string {
  16. algorithm := strconv.Itoa(int(r.Algorithm))
  17. algorithm += " (" + AlgorithmToString[r.Algorithm] + ")"
  18. switch p := p.(type) {
  19. case *rsa.PrivateKey:
  20. modulus := toBase64(p.PublicKey.N.Bytes())
  21. e := big.NewInt(int64(p.PublicKey.E))
  22. publicExponent := toBase64(e.Bytes())
  23. privateExponent := toBase64(p.D.Bytes())
  24. prime1 := toBase64(p.Primes[0].Bytes())
  25. prime2 := toBase64(p.Primes[1].Bytes())
  26. // Calculate Exponent1/2 and Coefficient as per: http://en.wikipedia.org/wiki/RSA#Using_the_Chinese_remainder_algorithm
  27. // and from: http://code.google.com/p/go/issues/detail?id=987
  28. one := big.NewInt(1)
  29. p1 := big.NewInt(0).Sub(p.Primes[0], one)
  30. q1 := big.NewInt(0).Sub(p.Primes[1], one)
  31. exp1 := big.NewInt(0).Mod(p.D, p1)
  32. exp2 := big.NewInt(0).Mod(p.D, q1)
  33. coeff := big.NewInt(0).ModInverse(p.Primes[1], p.Primes[0])
  34. exponent1 := toBase64(exp1.Bytes())
  35. exponent2 := toBase64(exp2.Bytes())
  36. coefficient := toBase64(coeff.Bytes())
  37. return format +
  38. "Algorithm: " + algorithm + "\n" +
  39. "Modulus: " + modulus + "\n" +
  40. "PublicExponent: " + publicExponent + "\n" +
  41. "PrivateExponent: " + privateExponent + "\n" +
  42. "Prime1: " + prime1 + "\n" +
  43. "Prime2: " + prime2 + "\n" +
  44. "Exponent1: " + exponent1 + "\n" +
  45. "Exponent2: " + exponent2 + "\n" +
  46. "Coefficient: " + coefficient + "\n"
  47. case *ecdsa.PrivateKey:
  48. var intlen int
  49. switch r.Algorithm {
  50. case ECDSAP256SHA256:
  51. intlen = 32
  52. case ECDSAP384SHA384:
  53. intlen = 48
  54. }
  55. private := toBase64(intToBytes(p.D, intlen))
  56. return format +
  57. "Algorithm: " + algorithm + "\n" +
  58. "PrivateKey: " + private + "\n"
  59. case *dsa.PrivateKey:
  60. T := divRoundUp(divRoundUp(p.PublicKey.Parameters.G.BitLen(), 8)-64, 8)
  61. prime := toBase64(intToBytes(p.PublicKey.Parameters.P, 64+T*8))
  62. subprime := toBase64(intToBytes(p.PublicKey.Parameters.Q, 20))
  63. base := toBase64(intToBytes(p.PublicKey.Parameters.G, 64+T*8))
  64. priv := toBase64(intToBytes(p.X, 20))
  65. pub := toBase64(intToBytes(p.PublicKey.Y, 64+T*8))
  66. return format +
  67. "Algorithm: " + algorithm + "\n" +
  68. "Prime(p): " + prime + "\n" +
  69. "Subprime(q): " + subprime + "\n" +
  70. "Base(g): " + base + "\n" +
  71. "Private_value(x): " + priv + "\n" +
  72. "Public_value(y): " + pub + "\n"
  73. default:
  74. return ""
  75. }
  76. }