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.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282
  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. "encoding/binary"
  9. "fmt"
  10. "hash"
  11. "io"
  12. "math/big"
  13. "strconv"
  14. "time"
  15. "github.com/keybase/go-crypto/openpgp/errors"
  16. "github.com/keybase/go-crypto/rsa"
  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) > 7 {
  92. err = errors.UnsupportedError("large public exponent")
  93. return
  94. }
  95. rsa := &rsa.PublicKey{N: new(big.Int).SetBytes(pk.n.bytes)}
  96. // Warning: incompatibility with crypto/rsa: keybase fork uses
  97. // int64 public exponents instead of int32.
  98. for i := 0; i < len(pk.e.bytes); i++ {
  99. rsa.E <<= 8
  100. rsa.E |= int64(pk.e.bytes[i])
  101. }
  102. pk.PublicKey = rsa
  103. return
  104. }
  105. // SerializeSignaturePrefix writes the prefix for this public key to the given Writer.
  106. // The prefix is used when calculating a signature over this public key. See
  107. // RFC 4880, section 5.2.4.
  108. func (pk *PublicKeyV3) SerializeSignaturePrefix(w io.Writer) {
  109. var pLength uint16
  110. switch pk.PubKeyAlgo {
  111. case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly, PubKeyAlgoRSASignOnly:
  112. pLength += 2 + uint16(len(pk.n.bytes))
  113. pLength += 2 + uint16(len(pk.e.bytes))
  114. default:
  115. panic("unknown public key algorithm")
  116. }
  117. pLength += 6
  118. w.Write([]byte{0x99, byte(pLength >> 8), byte(pLength)})
  119. return
  120. }
  121. func (pk *PublicKeyV3) Serialize(w io.Writer) (err error) {
  122. length := 8 // 8 byte header
  123. switch pk.PubKeyAlgo {
  124. case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly, PubKeyAlgoRSASignOnly:
  125. length += 2 + len(pk.n.bytes)
  126. length += 2 + len(pk.e.bytes)
  127. default:
  128. panic("unknown public key algorithm")
  129. }
  130. packetType := packetTypePublicKey
  131. if pk.IsSubkey {
  132. packetType = packetTypePublicSubkey
  133. }
  134. if err = serializeHeader(w, packetType, length); err != nil {
  135. return
  136. }
  137. return pk.serializeWithoutHeaders(w)
  138. }
  139. // serializeWithoutHeaders marshals the PublicKey to w in the form of an
  140. // OpenPGP public key packet, not including the packet header.
  141. func (pk *PublicKeyV3) serializeWithoutHeaders(w io.Writer) (err error) {
  142. var buf [8]byte
  143. // Version 3
  144. buf[0] = 3
  145. // Creation time
  146. t := uint32(pk.CreationTime.Unix())
  147. buf[1] = byte(t >> 24)
  148. buf[2] = byte(t >> 16)
  149. buf[3] = byte(t >> 8)
  150. buf[4] = byte(t)
  151. // Days to expire
  152. buf[5] = byte(pk.DaysToExpire >> 8)
  153. buf[6] = byte(pk.DaysToExpire)
  154. // Public key algorithm
  155. buf[7] = byte(pk.PubKeyAlgo)
  156. if _, err = w.Write(buf[:]); err != nil {
  157. return
  158. }
  159. switch pk.PubKeyAlgo {
  160. case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly, PubKeyAlgoRSASignOnly:
  161. return writeMPIs(w, pk.n, pk.e)
  162. }
  163. return errors.InvalidArgumentError("bad public-key algorithm")
  164. }
  165. // CanSign returns true iff this public key can generate signatures
  166. func (pk *PublicKeyV3) CanSign() bool {
  167. return pk.PubKeyAlgo != PubKeyAlgoRSAEncryptOnly
  168. }
  169. // VerifySignatureV3 returns nil iff sig is a valid signature, made by this
  170. // public key, of the data hashed into signed. signed is mutated by this call.
  171. func (pk *PublicKeyV3) VerifySignatureV3(signed hash.Hash, sig *SignatureV3) (err error) {
  172. if !pk.CanSign() {
  173. return errors.InvalidArgumentError("public key cannot generate signatures")
  174. }
  175. suffix := make([]byte, 5)
  176. suffix[0] = byte(sig.SigType)
  177. binary.BigEndian.PutUint32(suffix[1:], uint32(sig.CreationTime.Unix()))
  178. signed.Write(suffix)
  179. hashBytes := signed.Sum(nil)
  180. if hashBytes[0] != sig.HashTag[0] || hashBytes[1] != sig.HashTag[1] {
  181. return errors.SignatureError("hash tag doesn't match")
  182. }
  183. if pk.PubKeyAlgo != sig.PubKeyAlgo {
  184. return errors.InvalidArgumentError("public key and signature use different algorithms")
  185. }
  186. switch pk.PubKeyAlgo {
  187. case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly:
  188. if err = rsa.VerifyPKCS1v15(pk.PublicKey, sig.Hash, hashBytes, sig.RSASignature.bytes); err != nil {
  189. return errors.SignatureError("RSA verification failure")
  190. }
  191. return
  192. default:
  193. // V3 public keys only support RSA.
  194. panic("shouldn't happen")
  195. }
  196. panic("unreachable")
  197. }
  198. // VerifyUserIdSignatureV3 returns nil iff sig is a valid signature, made by this
  199. // public key, that id is the identity of pub.
  200. func (pk *PublicKeyV3) VerifyUserIdSignatureV3(id string, pub *PublicKeyV3, sig *SignatureV3) (err error) {
  201. h, err := userIdSignatureV3Hash(id, pk, sig.Hash)
  202. if err != nil {
  203. return err
  204. }
  205. return pk.VerifySignatureV3(h, sig)
  206. }
  207. // VerifyKeySignatureV3 returns nil iff sig is a valid signature, made by this
  208. // public key, of signed.
  209. func (pk *PublicKeyV3) VerifyKeySignatureV3(signed *PublicKeyV3, sig *SignatureV3) (err error) {
  210. h, err := keySignatureHash(pk, signed, sig.Hash)
  211. if err != nil {
  212. return err
  213. }
  214. return pk.VerifySignatureV3(h, sig)
  215. }
  216. // userIdSignatureV3Hash returns a Hash of the message that needs to be signed
  217. // to assert that pk is a valid key for id.
  218. func userIdSignatureV3Hash(id string, pk signingKey, hfn crypto.Hash) (h hash.Hash, err error) {
  219. if !hfn.Available() {
  220. return nil, errors.UnsupportedError("hash function")
  221. }
  222. h = hfn.New()
  223. // RFC 4880, section 5.2.4
  224. pk.SerializeSignaturePrefix(h)
  225. pk.serializeWithoutHeaders(h)
  226. h.Write([]byte(id))
  227. return
  228. }
  229. // KeyIdString returns the public key's fingerprint in capital hex
  230. // (e.g. "6C7EE1B8621CC013").
  231. func (pk *PublicKeyV3) KeyIdString() string {
  232. return fmt.Sprintf("%X", pk.KeyId)
  233. }
  234. // KeyIdShortString returns the short form of public key's fingerprint
  235. // in capital hex, as shown by gpg --list-keys (e.g. "621CC013").
  236. func (pk *PublicKeyV3) KeyIdShortString() string {
  237. return fmt.Sprintf("%X", pk.KeyId&0xFFFFFFFF)
  238. }
  239. // BitLength returns the bit length for the given public key.
  240. func (pk *PublicKeyV3) BitLength() (bitLength uint16, err error) {
  241. switch pk.PubKeyAlgo {
  242. case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly, PubKeyAlgoRSASignOnly:
  243. bitLength = pk.n.bitLength
  244. default:
  245. err = errors.InvalidArgumentError("bad public-key algorithm")
  246. }
  247. return
  248. }