You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

280 lines
8.0 KiB

  1. // Copyright 2013 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package packet
  5. import (
  6. "crypto"
  7. "crypto/md5"
  8. "crypto/rsa"
  9. "encoding/binary"
  10. "fmt"
  11. "hash"
  12. "io"
  13. "math/big"
  14. "strconv"
  15. "time"
  16. "golang.org/x/crypto/openpgp/errors"
  17. )
  18. // PublicKeyV3 represents older, version 3 public keys. These keys are less secure and
  19. // should not be used for signing or encrypting. They are supported here only for
  20. // parsing version 3 key material and validating signatures.
  21. // See RFC 4880, section 5.5.2.
  22. type PublicKeyV3 struct {
  23. CreationTime time.Time
  24. DaysToExpire uint16
  25. PubKeyAlgo PublicKeyAlgorithm
  26. PublicKey *rsa.PublicKey
  27. Fingerprint [16]byte
  28. KeyId uint64
  29. IsSubkey bool
  30. n, e parsedMPI
  31. }
  32. // newRSAPublicKeyV3 returns a PublicKey that wraps the given rsa.PublicKey.
  33. // Included here for testing purposes only. RFC 4880, section 5.5.2:
  34. // "an implementation MUST NOT generate a V3 key, but MAY accept it."
  35. func newRSAPublicKeyV3(creationTime time.Time, pub *rsa.PublicKey) *PublicKeyV3 {
  36. pk := &PublicKeyV3{
  37. CreationTime: creationTime,
  38. PublicKey: pub,
  39. n: fromBig(pub.N),
  40. e: fromBig(big.NewInt(int64(pub.E))),
  41. }
  42. pk.setFingerPrintAndKeyId()
  43. return pk
  44. }
  45. func (pk *PublicKeyV3) parse(r io.Reader) (err error) {
  46. // RFC 4880, section 5.5.2
  47. var buf [8]byte
  48. if _, err = readFull(r, buf[:]); err != nil {
  49. return
  50. }
  51. if buf[0] < 2 || buf[0] > 3 {
  52. return errors.UnsupportedError("public key version")
  53. }
  54. pk.CreationTime = time.Unix(int64(uint32(buf[1])<<24|uint32(buf[2])<<16|uint32(buf[3])<<8|uint32(buf[4])), 0)
  55. pk.DaysToExpire = binary.BigEndian.Uint16(buf[5:7])
  56. pk.PubKeyAlgo = PublicKeyAlgorithm(buf[7])
  57. switch pk.PubKeyAlgo {
  58. case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly, PubKeyAlgoRSASignOnly:
  59. err = pk.parseRSA(r)
  60. default:
  61. err = errors.UnsupportedError("public key type: " + strconv.Itoa(int(pk.PubKeyAlgo)))
  62. }
  63. if err != nil {
  64. return
  65. }
  66. pk.setFingerPrintAndKeyId()
  67. return
  68. }
  69. func (pk *PublicKeyV3) setFingerPrintAndKeyId() {
  70. // RFC 4880, section 12.2
  71. fingerPrint := md5.New()
  72. fingerPrint.Write(pk.n.bytes)
  73. fingerPrint.Write(pk.e.bytes)
  74. fingerPrint.Sum(pk.Fingerprint[:0])
  75. pk.KeyId = binary.BigEndian.Uint64(pk.n.bytes[len(pk.n.bytes)-8:])
  76. }
  77. // parseRSA parses RSA public key material from the given Reader. See RFC 4880,
  78. // section 5.5.2.
  79. func (pk *PublicKeyV3) parseRSA(r io.Reader) (err error) {
  80. if pk.n.bytes, pk.n.bitLength, err = readMPI(r); err != nil {
  81. return
  82. }
  83. if pk.e.bytes, pk.e.bitLength, err = readMPI(r); err != nil {
  84. return
  85. }
  86. // RFC 4880 Section 12.2 requires the low 8 bytes of the
  87. // modulus to form the key id.
  88. if len(pk.n.bytes) < 8 {
  89. return errors.StructuralError("v3 public key modulus is too short")
  90. }
  91. if len(pk.e.bytes) > 3 {
  92. err = errors.UnsupportedError("large public exponent")
  93. return
  94. }
  95. rsa := &rsa.PublicKey{N: new(big.Int).SetBytes(pk.n.bytes)}
  96. for i := 0; i < len(pk.e.bytes); i++ {
  97. rsa.E <<= 8
  98. rsa.E |= int(pk.e.bytes[i])
  99. }
  100. pk.PublicKey = rsa
  101. return
  102. }
  103. // SerializeSignaturePrefix writes the prefix for this public key to the given Writer.
  104. // The prefix is used when calculating a signature over this public key. See
  105. // RFC 4880, section 5.2.4.
  106. func (pk *PublicKeyV3) SerializeSignaturePrefix(w io.Writer) {
  107. var pLength uint16
  108. switch pk.PubKeyAlgo {
  109. case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly, PubKeyAlgoRSASignOnly:
  110. pLength += 2 + uint16(len(pk.n.bytes))
  111. pLength += 2 + uint16(len(pk.e.bytes))
  112. default:
  113. panic("unknown public key algorithm")
  114. }
  115. pLength += 6
  116. w.Write([]byte{0x99, byte(pLength >> 8), byte(pLength)})
  117. return
  118. }
  119. func (pk *PublicKeyV3) Serialize(w io.Writer) (err error) {
  120. length := 8 // 8 byte header
  121. switch pk.PubKeyAlgo {
  122. case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly, PubKeyAlgoRSASignOnly:
  123. length += 2 + len(pk.n.bytes)
  124. length += 2 + len(pk.e.bytes)
  125. default:
  126. panic("unknown public key algorithm")
  127. }
  128. packetType := packetTypePublicKey
  129. if pk.IsSubkey {
  130. packetType = packetTypePublicSubkey
  131. }
  132. if err = serializeHeader(w, packetType, length); err != nil {
  133. return
  134. }
  135. return pk.serializeWithoutHeaders(w)
  136. }
  137. // serializeWithoutHeaders marshals the PublicKey to w in the form of an
  138. // OpenPGP public key packet, not including the packet header.
  139. func (pk *PublicKeyV3) serializeWithoutHeaders(w io.Writer) (err error) {
  140. var buf [8]byte
  141. // Version 3
  142. buf[0] = 3
  143. // Creation time
  144. t := uint32(pk.CreationTime.Unix())
  145. buf[1] = byte(t >> 24)
  146. buf[2] = byte(t >> 16)
  147. buf[3] = byte(t >> 8)
  148. buf[4] = byte(t)
  149. // Days to expire
  150. buf[5] = byte(pk.DaysToExpire >> 8)
  151. buf[6] = byte(pk.DaysToExpire)
  152. // Public key algorithm
  153. buf[7] = byte(pk.PubKeyAlgo)
  154. if _, err = w.Write(buf[:]); err != nil {
  155. return
  156. }
  157. switch pk.PubKeyAlgo {
  158. case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly, PubKeyAlgoRSASignOnly:
  159. return writeMPIs(w, pk.n, pk.e)
  160. }
  161. return errors.InvalidArgumentError("bad public-key algorithm")
  162. }
  163. // CanSign returns true iff this public key can generate signatures
  164. func (pk *PublicKeyV3) CanSign() bool {
  165. return pk.PubKeyAlgo != PubKeyAlgoRSAEncryptOnly
  166. }
  167. // VerifySignatureV3 returns nil iff sig is a valid signature, made by this
  168. // public key, of the data hashed into signed. signed is mutated by this call.
  169. func (pk *PublicKeyV3) VerifySignatureV3(signed hash.Hash, sig *SignatureV3) (err error) {
  170. if !pk.CanSign() {
  171. return errors.InvalidArgumentError("public key cannot generate signatures")
  172. }
  173. suffix := make([]byte, 5)
  174. suffix[0] = byte(sig.SigType)
  175. binary.BigEndian.PutUint32(suffix[1:], uint32(sig.CreationTime.Unix()))
  176. signed.Write(suffix)
  177. hashBytes := signed.Sum(nil)
  178. if hashBytes[0] != sig.HashTag[0] || hashBytes[1] != sig.HashTag[1] {
  179. return errors.SignatureError("hash tag doesn't match")
  180. }
  181. if pk.PubKeyAlgo != sig.PubKeyAlgo {
  182. return errors.InvalidArgumentError("public key and signature use different algorithms")
  183. }
  184. switch pk.PubKeyAlgo {
  185. case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly:
  186. if err = rsa.VerifyPKCS1v15(pk.PublicKey, sig.Hash, hashBytes, sig.RSASignature.bytes); err != nil {
  187. return errors.SignatureError("RSA verification failure")
  188. }
  189. return
  190. default:
  191. // V3 public keys only support RSA.
  192. panic("shouldn't happen")
  193. }
  194. }
  195. // VerifyUserIdSignatureV3 returns nil iff sig is a valid signature, made by this
  196. // public key, that id is the identity of pub.
  197. func (pk *PublicKeyV3) VerifyUserIdSignatureV3(id string, pub *PublicKeyV3, sig *SignatureV3) (err error) {
  198. h, err := userIdSignatureV3Hash(id, pk, sig.Hash)
  199. if err != nil {
  200. return err
  201. }
  202. return pk.VerifySignatureV3(h, sig)
  203. }
  204. // VerifyKeySignatureV3 returns nil iff sig is a valid signature, made by this
  205. // public key, of signed.
  206. func (pk *PublicKeyV3) VerifyKeySignatureV3(signed *PublicKeyV3, sig *SignatureV3) (err error) {
  207. h, err := keySignatureHash(pk, signed, sig.Hash)
  208. if err != nil {
  209. return err
  210. }
  211. return pk.VerifySignatureV3(h, sig)
  212. }
  213. // userIdSignatureV3Hash returns a Hash of the message that needs to be signed
  214. // to assert that pk is a valid key for id.
  215. func userIdSignatureV3Hash(id string, pk signingKey, hfn crypto.Hash) (h hash.Hash, err error) {
  216. if !hfn.Available() {
  217. return nil, errors.UnsupportedError("hash function")
  218. }
  219. h = hfn.New()
  220. // RFC 4880, section 5.2.4
  221. pk.SerializeSignaturePrefix(h)
  222. pk.serializeWithoutHeaders(h)
  223. h.Write([]byte(id))
  224. return
  225. }
  226. // KeyIdString returns the public key's fingerprint in capital hex
  227. // (e.g. "6C7EE1B8621CC013").
  228. func (pk *PublicKeyV3) KeyIdString() string {
  229. return fmt.Sprintf("%X", pk.KeyId)
  230. }
  231. // KeyIdShortString returns the short form of public key's fingerprint
  232. // in capital hex, as shown by gpg --list-keys (e.g. "621CC013").
  233. func (pk *PublicKeyV3) KeyIdShortString() string {
  234. return fmt.Sprintf("%X", pk.KeyId&0xFFFFFFFF)
  235. }
  236. // BitLength returns the bit length for the given public key.
  237. func (pk *PublicKeyV3) BitLength() (bitLength uint16, err error) {
  238. switch pk.PubKeyAlgo {
  239. case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly, PubKeyAlgoRSASignOnly:
  240. bitLength = pk.n.bitLength
  241. default:
  242. err = errors.InvalidArgumentError("bad public-key algorithm")
  243. }
  244. return
  245. }