public_key.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414
  1. // Copyright 2011 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. "code.google.com/p/go.crypto/openpgp/elgamal"
  7. "code.google.com/p/go.crypto/openpgp/errors"
  8. "crypto/dsa"
  9. "crypto/rsa"
  10. "crypto/sha1"
  11. "encoding/binary"
  12. "fmt"
  13. "hash"
  14. "io"
  15. "math/big"
  16. "strconv"
  17. "time"
  18. )
  19. // PublicKey represents an OpenPGP public key. See RFC 4880, section 5.5.2.
  20. type PublicKey struct {
  21. CreationTime time.Time
  22. PubKeyAlgo PublicKeyAlgorithm
  23. PublicKey interface{} // Either a *rsa.PublicKey or *dsa.PublicKey
  24. Fingerprint [20]byte
  25. KeyId uint64
  26. IsSubkey bool
  27. n, e, p, q, g, y parsedMPI
  28. }
  29. func fromBig(n *big.Int) parsedMPI {
  30. return parsedMPI{
  31. bytes: n.Bytes(),
  32. bitLength: uint16(n.BitLen()),
  33. }
  34. }
  35. // NewRSAPublicKey returns a PublicKey that wraps the given rsa.PublicKey.
  36. func NewRSAPublicKey(creationTime time.Time, pub *rsa.PublicKey) *PublicKey {
  37. pk := &PublicKey{
  38. CreationTime: creationTime,
  39. PubKeyAlgo: PubKeyAlgoRSA,
  40. PublicKey: pub,
  41. n: fromBig(pub.N),
  42. e: fromBig(big.NewInt(int64(pub.E))),
  43. }
  44. pk.setFingerPrintAndKeyId()
  45. return pk
  46. }
  47. // NewDSAPublicKey returns a PublicKey that wraps the given rsa.PublicKey.
  48. func NewDSAPublicKey(creationTime time.Time, pub *dsa.PublicKey) *PublicKey {
  49. pk := &PublicKey{
  50. CreationTime: creationTime,
  51. PubKeyAlgo: PubKeyAlgoDSA,
  52. PublicKey: pub,
  53. p: fromBig(pub.P),
  54. q: fromBig(pub.Q),
  55. g: fromBig(pub.G),
  56. y: fromBig(pub.Y),
  57. }
  58. pk.setFingerPrintAndKeyId()
  59. return pk
  60. }
  61. func (pk *PublicKey) parse(r io.Reader) (err error) {
  62. // RFC 4880, section 5.5.2
  63. var buf [6]byte
  64. _, err = readFull(r, buf[:])
  65. if err != nil {
  66. return
  67. }
  68. if buf[0] != 4 {
  69. return errors.UnsupportedError("public key version")
  70. }
  71. pk.CreationTime = time.Unix(int64(uint32(buf[1])<<24|uint32(buf[2])<<16|uint32(buf[3])<<8|uint32(buf[4])), 0)
  72. pk.PubKeyAlgo = PublicKeyAlgorithm(buf[5])
  73. switch pk.PubKeyAlgo {
  74. case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly, PubKeyAlgoRSASignOnly:
  75. err = pk.parseRSA(r)
  76. case PubKeyAlgoDSA:
  77. err = pk.parseDSA(r)
  78. case PubKeyAlgoElGamal:
  79. err = pk.parseElGamal(r)
  80. default:
  81. err = errors.UnsupportedError("public key type: " + strconv.Itoa(int(pk.PubKeyAlgo)))
  82. }
  83. if err != nil {
  84. return
  85. }
  86. pk.setFingerPrintAndKeyId()
  87. return
  88. }
  89. func (pk *PublicKey) setFingerPrintAndKeyId() {
  90. // RFC 4880, section 12.2
  91. fingerPrint := sha1.New()
  92. pk.SerializeSignaturePrefix(fingerPrint)
  93. pk.serializeWithoutHeaders(fingerPrint)
  94. copy(pk.Fingerprint[:], fingerPrint.Sum(nil))
  95. pk.KeyId = binary.BigEndian.Uint64(pk.Fingerprint[12:20])
  96. }
  97. // parseRSA parses RSA public key material from the given Reader. See RFC 4880,
  98. // section 5.5.2.
  99. func (pk *PublicKey) parseRSA(r io.Reader) (err error) {
  100. pk.n.bytes, pk.n.bitLength, err = readMPI(r)
  101. if err != nil {
  102. return
  103. }
  104. pk.e.bytes, pk.e.bitLength, err = readMPI(r)
  105. if err != nil {
  106. return
  107. }
  108. if len(pk.e.bytes) > 3 {
  109. err = errors.UnsupportedError("large public exponent")
  110. return
  111. }
  112. rsa := &rsa.PublicKey{
  113. N: new(big.Int).SetBytes(pk.n.bytes),
  114. E: 0,
  115. }
  116. for i := 0; i < len(pk.e.bytes); i++ {
  117. rsa.E <<= 8
  118. rsa.E |= int(pk.e.bytes[i])
  119. }
  120. pk.PublicKey = rsa
  121. return
  122. }
  123. // parseDSA parses DSA public key material from the given Reader. See RFC 4880,
  124. // section 5.5.2.
  125. func (pk *PublicKey) parseDSA(r io.Reader) (err error) {
  126. pk.p.bytes, pk.p.bitLength, err = readMPI(r)
  127. if err != nil {
  128. return
  129. }
  130. pk.q.bytes, pk.q.bitLength, err = readMPI(r)
  131. if err != nil {
  132. return
  133. }
  134. pk.g.bytes, pk.g.bitLength, err = readMPI(r)
  135. if err != nil {
  136. return
  137. }
  138. pk.y.bytes, pk.y.bitLength, err = readMPI(r)
  139. if err != nil {
  140. return
  141. }
  142. dsa := new(dsa.PublicKey)
  143. dsa.P = new(big.Int).SetBytes(pk.p.bytes)
  144. dsa.Q = new(big.Int).SetBytes(pk.q.bytes)
  145. dsa.G = new(big.Int).SetBytes(pk.g.bytes)
  146. dsa.Y = new(big.Int).SetBytes(pk.y.bytes)
  147. pk.PublicKey = dsa
  148. return
  149. }
  150. // parseElGamal parses ElGamal public key material from the given Reader. See
  151. // RFC 4880, section 5.5.2.
  152. func (pk *PublicKey) parseElGamal(r io.Reader) (err error) {
  153. pk.p.bytes, pk.p.bitLength, err = readMPI(r)
  154. if err != nil {
  155. return
  156. }
  157. pk.g.bytes, pk.g.bitLength, err = readMPI(r)
  158. if err != nil {
  159. return
  160. }
  161. pk.y.bytes, pk.y.bitLength, err = readMPI(r)
  162. if err != nil {
  163. return
  164. }
  165. elgamal := new(elgamal.PublicKey)
  166. elgamal.P = new(big.Int).SetBytes(pk.p.bytes)
  167. elgamal.G = new(big.Int).SetBytes(pk.g.bytes)
  168. elgamal.Y = new(big.Int).SetBytes(pk.y.bytes)
  169. pk.PublicKey = elgamal
  170. return
  171. }
  172. // SerializeSignaturePrefix writes the prefix for this public key to the given Writer.
  173. // The prefix is used when calculating a signature over this public key. See
  174. // RFC 4880, section 5.2.4.
  175. func (pk *PublicKey) SerializeSignaturePrefix(h hash.Hash) {
  176. var pLength uint16
  177. switch pk.PubKeyAlgo {
  178. case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly, PubKeyAlgoRSASignOnly:
  179. pLength += 2 + uint16(len(pk.n.bytes))
  180. pLength += 2 + uint16(len(pk.e.bytes))
  181. case PubKeyAlgoDSA:
  182. pLength += 2 + uint16(len(pk.p.bytes))
  183. pLength += 2 + uint16(len(pk.q.bytes))
  184. pLength += 2 + uint16(len(pk.g.bytes))
  185. pLength += 2 + uint16(len(pk.y.bytes))
  186. case PubKeyAlgoElGamal:
  187. pLength += 2 + uint16(len(pk.p.bytes))
  188. pLength += 2 + uint16(len(pk.g.bytes))
  189. pLength += 2 + uint16(len(pk.y.bytes))
  190. default:
  191. panic("unknown public key algorithm")
  192. }
  193. pLength += 6
  194. h.Write([]byte{0x99, byte(pLength >> 8), byte(pLength)})
  195. return
  196. }
  197. func (pk *PublicKey) Serialize(w io.Writer) (err error) {
  198. length := 6 // 6 byte header
  199. switch pk.PubKeyAlgo {
  200. case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly, PubKeyAlgoRSASignOnly:
  201. length += 2 + len(pk.n.bytes)
  202. length += 2 + len(pk.e.bytes)
  203. case PubKeyAlgoDSA:
  204. length += 2 + len(pk.p.bytes)
  205. length += 2 + len(pk.q.bytes)
  206. length += 2 + len(pk.g.bytes)
  207. length += 2 + len(pk.y.bytes)
  208. case PubKeyAlgoElGamal:
  209. length += 2 + len(pk.p.bytes)
  210. length += 2 + len(pk.g.bytes)
  211. length += 2 + len(pk.y.bytes)
  212. default:
  213. panic("unknown public key algorithm")
  214. }
  215. packetType := packetTypePublicKey
  216. if pk.IsSubkey {
  217. packetType = packetTypePublicSubkey
  218. }
  219. err = serializeHeader(w, packetType, length)
  220. if err != nil {
  221. return
  222. }
  223. return pk.serializeWithoutHeaders(w)
  224. }
  225. // serializeWithoutHeaders marshals the PublicKey to w in the form of an
  226. // OpenPGP public key packet, not including the packet header.
  227. func (pk *PublicKey) serializeWithoutHeaders(w io.Writer) (err error) {
  228. var buf [6]byte
  229. buf[0] = 4
  230. t := uint32(pk.CreationTime.Unix())
  231. buf[1] = byte(t >> 24)
  232. buf[2] = byte(t >> 16)
  233. buf[3] = byte(t >> 8)
  234. buf[4] = byte(t)
  235. buf[5] = byte(pk.PubKeyAlgo)
  236. _, err = w.Write(buf[:])
  237. if err != nil {
  238. return
  239. }
  240. switch pk.PubKeyAlgo {
  241. case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly, PubKeyAlgoRSASignOnly:
  242. return writeMPIs(w, pk.n, pk.e)
  243. case PubKeyAlgoDSA:
  244. return writeMPIs(w, pk.p, pk.q, pk.g, pk.y)
  245. case PubKeyAlgoElGamal:
  246. return writeMPIs(w, pk.p, pk.g, pk.y)
  247. }
  248. return errors.InvalidArgumentError("bad public-key algorithm")
  249. }
  250. // CanSign returns true iff this public key can generate signatures
  251. func (pk *PublicKey) CanSign() bool {
  252. return pk.PubKeyAlgo != PubKeyAlgoRSAEncryptOnly && pk.PubKeyAlgo != PubKeyAlgoElGamal
  253. }
  254. // VerifySignature returns nil iff sig is a valid signature, made by this
  255. // public key, of the data hashed into signed. signed is mutated by this call.
  256. func (pk *PublicKey) VerifySignature(signed hash.Hash, sig *Signature) (err error) {
  257. if !pk.CanSign() {
  258. return errors.InvalidArgumentError("public key cannot generate signatures")
  259. }
  260. signed.Write(sig.HashSuffix)
  261. hashBytes := signed.Sum(nil)
  262. if hashBytes[0] != sig.HashTag[0] || hashBytes[1] != sig.HashTag[1] {
  263. return errors.SignatureError("hash tag doesn't match")
  264. }
  265. if pk.PubKeyAlgo != sig.PubKeyAlgo {
  266. return errors.InvalidArgumentError("public key and signature use different algorithms")
  267. }
  268. switch pk.PubKeyAlgo {
  269. case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly:
  270. rsaPublicKey, _ := pk.PublicKey.(*rsa.PublicKey)
  271. err = rsa.VerifyPKCS1v15(rsaPublicKey, sig.Hash, hashBytes, sig.RSASignature.bytes)
  272. if err != nil {
  273. return errors.SignatureError("RSA verification failure")
  274. }
  275. return nil
  276. case PubKeyAlgoDSA:
  277. dsaPublicKey, _ := pk.PublicKey.(*dsa.PublicKey)
  278. // Need to truncate hashBytes to match FIPS 186-3 section 4.6.
  279. subgroupSize := (dsaPublicKey.Q.BitLen() + 7) / 8
  280. if len(hashBytes) > subgroupSize {
  281. hashBytes = hashBytes[:subgroupSize]
  282. }
  283. if !dsa.Verify(dsaPublicKey, hashBytes, new(big.Int).SetBytes(sig.DSASigR.bytes), new(big.Int).SetBytes(sig.DSASigS.bytes)) {
  284. return errors.SignatureError("DSA verification failure")
  285. }
  286. return nil
  287. default:
  288. panic("shouldn't happen")
  289. }
  290. panic("unreachable")
  291. }
  292. // keySignatureHash returns a Hash of the message that needs to be signed for
  293. // pk to assert a subkey relationship to signed.
  294. func keySignatureHash(pk, signed *PublicKey, sig *Signature) (h hash.Hash, err error) {
  295. h = sig.Hash.New()
  296. if h == nil {
  297. return nil, errors.UnsupportedError("hash function")
  298. }
  299. // RFC 4880, section 5.2.4
  300. pk.SerializeSignaturePrefix(h)
  301. pk.serializeWithoutHeaders(h)
  302. signed.SerializeSignaturePrefix(h)
  303. signed.serializeWithoutHeaders(h)
  304. return
  305. }
  306. // VerifyKeySignature returns nil iff sig is a valid signature, made by this
  307. // public key, of signed.
  308. func (pk *PublicKey) VerifyKeySignature(signed *PublicKey, sig *Signature) (err error) {
  309. h, err := keySignatureHash(pk, signed, sig)
  310. if err != nil {
  311. return err
  312. }
  313. return pk.VerifySignature(h, sig)
  314. }
  315. // userIdSignatureHash returns a Hash of the message that needs to be signed
  316. // to assert that pk is a valid key for id.
  317. func userIdSignatureHash(id string, pk *PublicKey, sig *Signature) (h hash.Hash, err error) {
  318. h = sig.Hash.New()
  319. if h == nil {
  320. return nil, errors.UnsupportedError("hash function")
  321. }
  322. // RFC 4880, section 5.2.4
  323. pk.SerializeSignaturePrefix(h)
  324. pk.serializeWithoutHeaders(h)
  325. var buf [5]byte
  326. buf[0] = 0xb4
  327. buf[1] = byte(len(id) >> 24)
  328. buf[2] = byte(len(id) >> 16)
  329. buf[3] = byte(len(id) >> 8)
  330. buf[4] = byte(len(id))
  331. h.Write(buf[:])
  332. h.Write([]byte(id))
  333. return
  334. }
  335. // VerifyUserIdSignature returns nil iff sig is a valid signature, made by this
  336. // public key, of id.
  337. func (pk *PublicKey) VerifyUserIdSignature(id string, sig *Signature) (err error) {
  338. h, err := userIdSignatureHash(id, pk, sig)
  339. if err != nil {
  340. return err
  341. }
  342. return pk.VerifySignature(h, sig)
  343. }
  344. // KeyIdString returns the public key's fingerprint in capital hex
  345. // (e.g. "6C7EE1B8621CC013").
  346. func (pk *PublicKey) KeyIdString() string {
  347. return fmt.Sprintf("%X", pk.Fingerprint[12:20])
  348. }
  349. // KeyIdShortString returns the short form of public key's fingerprint
  350. // in capital hex, as shown by gpg --list-keys (e.g. "621CC013").
  351. func (pk *PublicKey) KeyIdShortString() string {
  352. return fmt.Sprintf("%X", pk.Fingerprint[16:20])
  353. }
  354. // A parsedMPI is used to store the contents of a big integer, along with the
  355. // bit length that was specified in the original input. This allows the MPI to
  356. // be reserialized exactly.
  357. type parsedMPI struct {
  358. bytes []byte
  359. bitLength uint16
  360. }
  361. // writeMPIs is a utility function for serializing several big integers to the
  362. // given Writer.
  363. func writeMPIs(w io.Writer, mpis ...parsedMPI) (err error) {
  364. for _, mpi := range mpis {
  365. err = writeMPI(w, mpi.bitLength, mpi.bytes)
  366. if err != nil {
  367. return
  368. }
  369. }
  370. return
  371. }