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.
11 "crypto/openpgp/elgamal"
12 error_ "crypto/openpgp/error"
23 // PrivateKey represents a possibly encrypted private key. See RFC 4880,
25 type PrivateKey struct {
27 Encrypted bool // if true then the private key is unavailable until Decrypt has been called.
30 s2k func(out, in []byte)
31 PrivateKey interface{} // An *rsa.PrivateKey.
36 func NewRSAPrivateKey(currentTime time.Time, priv *rsa.PrivateKey, isSubkey bool) *PrivateKey {
38 pk.PublicKey = *NewRSAPublicKey(currentTime, &priv.PublicKey, isSubkey)
43 func (pk *PrivateKey) parse(r io.Reader) (err error) {
44 err = (&pk.PublicKey).parse(r)
49 _, err = readFull(r, buf[:])
61 _, err = readFull(r, buf[:])
65 pk.cipher = CipherFunction(buf[0])
67 pk.s2k, err = s2k.Parse(r)
72 pk.sha1Checksum = true
75 return error_.UnsupportedError("deprecated s2k function in private key")
79 blockSize := pk.cipher.blockSize()
81 return error_.UnsupportedError("unsupported cipher in private key: " + strconv.Itoa(int(pk.cipher)))
83 pk.iv = make([]byte, blockSize)
84 _, err = readFull(r, pk.iv)
90 pk.encryptedData, err = ioutil.ReadAll(r)
96 return pk.parsePrivateKey(pk.encryptedData)
102 func mod64kHash(d []byte) uint16 {
104 for _, b := range d {
110 func (pk *PrivateKey) Serialize(w io.Writer) (err error) {
111 // TODO(agl): support encrypted private keys
112 buf := bytes.NewBuffer(nil)
113 err = pk.PublicKey.serializeWithoutHeaders(buf)
117 buf.WriteByte(0 /* no encryption */ )
119 privateKeyBuf := bytes.NewBuffer(nil)
121 switch priv := pk.PrivateKey.(type) {
122 case *rsa.PrivateKey:
123 err = serializeRSAPrivateKey(privateKeyBuf, priv)
125 err = error_.InvalidArgumentError("non-RSA private key")
131 ptype := packetTypePrivateKey
132 contents := buf.Bytes()
133 privateKeyBytes := privateKeyBuf.Bytes()
135 ptype = packetTypePrivateSubkey
137 err = serializeHeader(w, ptype, len(contents)+len(privateKeyBytes)+2)
141 _, err = w.Write(contents)
145 _, err = w.Write(privateKeyBytes)
150 checksum := mod64kHash(privateKeyBytes)
151 var checksumBytes [2]byte
152 checksumBytes[0] = byte(checksum >> 8)
153 checksumBytes[1] = byte(checksum)
154 _, err = w.Write(checksumBytes[:])
159 func serializeRSAPrivateKey(w io.Writer, priv *rsa.PrivateKey) error {
160 err := writeBig(w, priv.D)
164 err = writeBig(w, priv.Primes[1])
168 err = writeBig(w, priv.Primes[0])
172 return writeBig(w, priv.Precomputed.Qinv)
175 // Decrypt decrypts an encrypted private key using a passphrase.
176 func (pk *PrivateKey) Decrypt(passphrase []byte) error {
181 key := make([]byte, pk.cipher.KeySize())
182 pk.s2k(key, passphrase)
183 block := pk.cipher.new(key)
184 cfb := cipher.NewCFBDecrypter(block, pk.iv)
186 data := pk.encryptedData
187 cfb.XORKeyStream(data, data)
190 if len(data) < sha1.Size {
191 return error_.StructuralError("truncated private key data")
194 h.Write(data[:len(data)-sha1.Size])
196 if !bytes.Equal(sum, data[len(data)-sha1.Size:]) {
197 return error_.StructuralError("private key checksum failure")
199 data = data[:len(data)-sha1.Size]
202 return error_.StructuralError("truncated private key data")
205 for i := 0; i < len(data)-2; i++ {
206 sum += uint16(data[i])
208 if data[len(data)-2] != uint8(sum>>8) ||
209 data[len(data)-1] != uint8(sum) {
210 return error_.StructuralError("private key checksum failure")
212 data = data[:len(data)-2]
215 return pk.parsePrivateKey(data)
218 func (pk *PrivateKey) parsePrivateKey(data []byte) (err error) {
219 switch pk.PublicKey.PubKeyAlgo {
220 case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly, PubKeyAlgoRSAEncryptOnly:
221 return pk.parseRSAPrivateKey(data)
223 return pk.parseDSAPrivateKey(data)
224 case PubKeyAlgoElGamal:
225 return pk.parseElGamalPrivateKey(data)
230 func (pk *PrivateKey) parseRSAPrivateKey(data []byte) (err error) {
231 rsaPub := pk.PublicKey.PublicKey.(*rsa.PublicKey)
232 rsaPriv := new(rsa.PrivateKey)
233 rsaPriv.PublicKey = *rsaPub
235 buf := bytes.NewBuffer(data)
236 d, _, err := readMPI(buf)
240 p, _, err := readMPI(buf)
244 q, _, err := readMPI(buf)
249 rsaPriv.D = new(big.Int).SetBytes(d)
250 rsaPriv.Primes = make([]*big.Int, 2)
251 rsaPriv.Primes[0] = new(big.Int).SetBytes(p)
252 rsaPriv.Primes[1] = new(big.Int).SetBytes(q)
254 pk.PrivateKey = rsaPriv
256 pk.encryptedData = nil
261 func (pk *PrivateKey) parseDSAPrivateKey(data []byte) (err error) {
262 dsaPub := pk.PublicKey.PublicKey.(*dsa.PublicKey)
263 dsaPriv := new(dsa.PrivateKey)
264 dsaPriv.PublicKey = *dsaPub
266 buf := bytes.NewBuffer(data)
267 x, _, err := readMPI(buf)
272 dsaPriv.X = new(big.Int).SetBytes(x)
273 pk.PrivateKey = dsaPriv
275 pk.encryptedData = nil
280 func (pk *PrivateKey) parseElGamalPrivateKey(data []byte) (err error) {
281 pub := pk.PublicKey.PublicKey.(*elgamal.PublicKey)
282 priv := new(elgamal.PrivateKey)
283 priv.PublicKey = *pub
285 buf := bytes.NewBuffer(data)
286 x, _, err := readMPI(buf)
291 priv.X = new(big.Int).SetBytes(x)
294 pk.encryptedData = nil