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.
21 "golang.org/x/crypto/openpgp/elgamal"
22 "golang.org/x/crypto/openpgp/errors"
23 "golang.org/x/crypto/openpgp/s2k"
26 // PrivateKey represents a possibly encrypted private key. See RFC 4880,
28 type PrivateKey struct {
30 Encrypted bool // if true then the private key is unavailable until Decrypt has been called.
33 s2k func(out, in []byte)
34 PrivateKey interface{} // An *{rsa|dsa|ecdsa}.PrivateKey or a crypto.Signer.
39 func NewRSAPrivateKey(currentTime time.Time, priv *rsa.PrivateKey) *PrivateKey {
41 pk.PublicKey = *NewRSAPublicKey(currentTime, &priv.PublicKey)
46 func NewDSAPrivateKey(currentTime time.Time, priv *dsa.PrivateKey) *PrivateKey {
48 pk.PublicKey = *NewDSAPublicKey(currentTime, &priv.PublicKey)
53 func NewElGamalPrivateKey(currentTime time.Time, priv *elgamal.PrivateKey) *PrivateKey {
55 pk.PublicKey = *NewElGamalPublicKey(currentTime, &priv.PublicKey)
60 func NewECDSAPrivateKey(currentTime time.Time, priv *ecdsa.PrivateKey) *PrivateKey {
62 pk.PublicKey = *NewECDSAPublicKey(currentTime, &priv.PublicKey)
67 // NewSignerPrivateKey creates a sign-only PrivateKey from a crypto.Signer that
68 // implements RSA or ECDSA.
69 func NewSignerPrivateKey(currentTime time.Time, signer crypto.Signer) *PrivateKey {
71 switch pubkey := signer.Public().(type) {
73 pk.PublicKey = *NewRSAPublicKey(currentTime, &pubkey)
74 pk.PubKeyAlgo = PubKeyAlgoRSASignOnly
76 pk.PublicKey = *NewECDSAPublicKey(currentTime, &pubkey)
78 panic("openpgp: unknown crypto.Signer type in NewSignerPrivateKey")
80 pk.PrivateKey = signer
84 func (pk *PrivateKey) parse(r io.Reader) (err error) {
85 err = (&pk.PublicKey).parse(r)
90 _, err = readFull(r, buf[:])
102 _, err = readFull(r, buf[:])
106 pk.cipher = CipherFunction(buf[0])
108 pk.s2k, err = s2k.Parse(r)
113 pk.sha1Checksum = true
116 return errors.UnsupportedError("deprecated s2k function in private key")
120 blockSize := pk.cipher.blockSize()
122 return errors.UnsupportedError("unsupported cipher in private key: " + strconv.Itoa(int(pk.cipher)))
124 pk.iv = make([]byte, blockSize)
125 _, err = readFull(r, pk.iv)
131 pk.encryptedData, err = ioutil.ReadAll(r)
137 return pk.parsePrivateKey(pk.encryptedData)
143 func mod64kHash(d []byte) uint16 {
145 for _, b := range d {
151 func (pk *PrivateKey) Serialize(w io.Writer) (err error) {
152 // TODO(agl): support encrypted private keys
153 buf := bytes.NewBuffer(nil)
154 err = pk.PublicKey.serializeWithoutHeaders(buf)
158 buf.WriteByte(0 /* no encryption */)
160 privateKeyBuf := bytes.NewBuffer(nil)
162 switch priv := pk.PrivateKey.(type) {
163 case *rsa.PrivateKey:
164 err = serializeRSAPrivateKey(privateKeyBuf, priv)
165 case *dsa.PrivateKey:
166 err = serializeDSAPrivateKey(privateKeyBuf, priv)
167 case *elgamal.PrivateKey:
168 err = serializeElGamalPrivateKey(privateKeyBuf, priv)
169 case *ecdsa.PrivateKey:
170 err = serializeECDSAPrivateKey(privateKeyBuf, priv)
172 err = errors.InvalidArgumentError("unknown private key type")
178 ptype := packetTypePrivateKey
179 contents := buf.Bytes()
180 privateKeyBytes := privateKeyBuf.Bytes()
182 ptype = packetTypePrivateSubkey
184 err = serializeHeader(w, ptype, len(contents)+len(privateKeyBytes)+2)
188 _, err = w.Write(contents)
192 _, err = w.Write(privateKeyBytes)
197 checksum := mod64kHash(privateKeyBytes)
198 var checksumBytes [2]byte
199 checksumBytes[0] = byte(checksum >> 8)
200 checksumBytes[1] = byte(checksum)
201 _, err = w.Write(checksumBytes[:])
206 func serializeRSAPrivateKey(w io.Writer, priv *rsa.PrivateKey) error {
207 err := writeBig(w, priv.D)
211 err = writeBig(w, priv.Primes[1])
215 err = writeBig(w, priv.Primes[0])
219 return writeBig(w, priv.Precomputed.Qinv)
222 func serializeDSAPrivateKey(w io.Writer, priv *dsa.PrivateKey) error {
223 return writeBig(w, priv.X)
226 func serializeElGamalPrivateKey(w io.Writer, priv *elgamal.PrivateKey) error {
227 return writeBig(w, priv.X)
230 func serializeECDSAPrivateKey(w io.Writer, priv *ecdsa.PrivateKey) error {
231 return writeBig(w, priv.D)
234 // Decrypt decrypts an encrypted private key using a passphrase.
235 func (pk *PrivateKey) Decrypt(passphrase []byte) error {
240 key := make([]byte, pk.cipher.KeySize())
241 pk.s2k(key, passphrase)
242 block := pk.cipher.new(key)
243 cfb := cipher.NewCFBDecrypter(block, pk.iv)
245 data := make([]byte, len(pk.encryptedData))
246 cfb.XORKeyStream(data, pk.encryptedData)
249 if len(data) < sha1.Size {
250 return errors.StructuralError("truncated private key data")
253 h.Write(data[:len(data)-sha1.Size])
255 if !bytes.Equal(sum, data[len(data)-sha1.Size:]) {
256 return errors.StructuralError("private key checksum failure")
258 data = data[:len(data)-sha1.Size]
261 return errors.StructuralError("truncated private key data")
264 for i := 0; i < len(data)-2; i++ {
265 sum += uint16(data[i])
267 if data[len(data)-2] != uint8(sum>>8) ||
268 data[len(data)-1] != uint8(sum) {
269 return errors.StructuralError("private key checksum failure")
271 data = data[:len(data)-2]
274 return pk.parsePrivateKey(data)
277 func (pk *PrivateKey) parsePrivateKey(data []byte) (err error) {
278 switch pk.PublicKey.PubKeyAlgo {
279 case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly, PubKeyAlgoRSAEncryptOnly:
280 return pk.parseRSAPrivateKey(data)
282 return pk.parseDSAPrivateKey(data)
283 case PubKeyAlgoElGamal:
284 return pk.parseElGamalPrivateKey(data)
285 case PubKeyAlgoECDSA:
286 return pk.parseECDSAPrivateKey(data)
291 func (pk *PrivateKey) parseRSAPrivateKey(data []byte) (err error) {
292 rsaPub := pk.PublicKey.PublicKey.(*rsa.PublicKey)
293 rsaPriv := new(rsa.PrivateKey)
294 rsaPriv.PublicKey = *rsaPub
296 buf := bytes.NewBuffer(data)
297 d, _, err := readMPI(buf)
301 p, _, err := readMPI(buf)
305 q, _, err := readMPI(buf)
310 rsaPriv.D = new(big.Int).SetBytes(d)
311 rsaPriv.Primes = make([]*big.Int, 2)
312 rsaPriv.Primes[0] = new(big.Int).SetBytes(p)
313 rsaPriv.Primes[1] = new(big.Int).SetBytes(q)
314 if err := rsaPriv.Validate(); err != nil {
318 pk.PrivateKey = rsaPriv
320 pk.encryptedData = nil
325 func (pk *PrivateKey) parseDSAPrivateKey(data []byte) (err error) {
326 dsaPub := pk.PublicKey.PublicKey.(*dsa.PublicKey)
327 dsaPriv := new(dsa.PrivateKey)
328 dsaPriv.PublicKey = *dsaPub
330 buf := bytes.NewBuffer(data)
331 x, _, err := readMPI(buf)
336 dsaPriv.X = new(big.Int).SetBytes(x)
337 pk.PrivateKey = dsaPriv
339 pk.encryptedData = nil
344 func (pk *PrivateKey) parseElGamalPrivateKey(data []byte) (err error) {
345 pub := pk.PublicKey.PublicKey.(*elgamal.PublicKey)
346 priv := new(elgamal.PrivateKey)
347 priv.PublicKey = *pub
349 buf := bytes.NewBuffer(data)
350 x, _, err := readMPI(buf)
355 priv.X = new(big.Int).SetBytes(x)
358 pk.encryptedData = nil
363 func (pk *PrivateKey) parseECDSAPrivateKey(data []byte) (err error) {
364 ecdsaPub := pk.PublicKey.PublicKey.(*ecdsa.PublicKey)
366 buf := bytes.NewBuffer(data)
367 d, _, err := readMPI(buf)
372 pk.PrivateKey = &ecdsa.PrivateKey{
373 PublicKey: *ecdsaPub,
374 D: new(big.Int).SetBytes(d),
377 pk.encryptedData = nil