OLD | NEW |
(Empty) | |
| 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 |
| 5 package packet |
| 6 |
| 7 import ( |
| 8 "bytes" |
| 9 "code.google.com/p/go.crypto/openpgp/elgamal" |
| 10 "code.google.com/p/go.crypto/openpgp/errors" |
| 11 "code.google.com/p/go.crypto/openpgp/s2k" |
| 12 "crypto/cipher" |
| 13 "crypto/dsa" |
| 14 "crypto/rsa" |
| 15 "crypto/sha1" |
| 16 "io" |
| 17 "io/ioutil" |
| 18 "math/big" |
| 19 "strconv" |
| 20 "time" |
| 21 ) |
| 22 |
| 23 // PrivateKey represents a possibly encrypted private key. See RFC 4880, |
| 24 // section 5.5.3. |
| 25 type PrivateKey struct { |
| 26 PublicKey |
| 27 Encrypted bool // if true then the private key is unavailable until
Decrypt has been called. |
| 28 encryptedData []byte |
| 29 cipher CipherFunction |
| 30 s2k func(out, in []byte) |
| 31 PrivateKey interface{} // An *rsa.PrivateKey or *dsa.PrivateKey. |
| 32 sha1Checksum bool |
| 33 iv []byte |
| 34 } |
| 35 |
| 36 func NewRSAPrivateKey(currentTime time.Time, priv *rsa.PrivateKey) *PrivateKey { |
| 37 pk := new(PrivateKey) |
| 38 pk.PublicKey = *NewRSAPublicKey(currentTime, &priv.PublicKey) |
| 39 pk.PrivateKey = priv |
| 40 return pk |
| 41 } |
| 42 |
| 43 func NewDSAPrivateKey(currentTime time.Time, priv *dsa.PrivateKey) *PrivateKey { |
| 44 pk := new(PrivateKey) |
| 45 pk.PublicKey = *NewDSAPublicKey(currentTime, &priv.PublicKey) |
| 46 pk.PrivateKey = priv |
| 47 return pk |
| 48 } |
| 49 |
| 50 func (pk *PrivateKey) parse(r io.Reader) (err error) { |
| 51 err = (&pk.PublicKey).parse(r) |
| 52 if err != nil { |
| 53 return |
| 54 } |
| 55 var buf [1]byte |
| 56 _, err = readFull(r, buf[:]) |
| 57 if err != nil { |
| 58 return |
| 59 } |
| 60 |
| 61 s2kType := buf[0] |
| 62 |
| 63 switch s2kType { |
| 64 case 0: |
| 65 pk.s2k = nil |
| 66 pk.Encrypted = false |
| 67 case 254, 255: |
| 68 _, err = readFull(r, buf[:]) |
| 69 if err != nil { |
| 70 return |
| 71 } |
| 72 pk.cipher = CipherFunction(buf[0]) |
| 73 pk.Encrypted = true |
| 74 pk.s2k, err = s2k.Parse(r) |
| 75 if err != nil { |
| 76 return |
| 77 } |
| 78 if s2kType == 254 { |
| 79 pk.sha1Checksum = true |
| 80 } |
| 81 default: |
| 82 return errors.UnsupportedError("deprecated s2k function in priva
te key") |
| 83 } |
| 84 |
| 85 if pk.Encrypted { |
| 86 blockSize := pk.cipher.blockSize() |
| 87 if blockSize == 0 { |
| 88 return errors.UnsupportedError("unsupported cipher in pr
ivate key: " + strconv.Itoa(int(pk.cipher))) |
| 89 } |
| 90 pk.iv = make([]byte, blockSize) |
| 91 _, err = readFull(r, pk.iv) |
| 92 if err != nil { |
| 93 return |
| 94 } |
| 95 } |
| 96 |
| 97 pk.encryptedData, err = ioutil.ReadAll(r) |
| 98 if err != nil { |
| 99 return |
| 100 } |
| 101 |
| 102 if !pk.Encrypted { |
| 103 return pk.parsePrivateKey(pk.encryptedData) |
| 104 } |
| 105 |
| 106 return |
| 107 } |
| 108 |
| 109 func mod64kHash(d []byte) uint16 { |
| 110 var h uint16 |
| 111 for _, b := range d { |
| 112 h += uint16(b) |
| 113 } |
| 114 return h |
| 115 } |
| 116 |
| 117 func (pk *PrivateKey) Serialize(w io.Writer) (err error) { |
| 118 // TODO(agl): support encrypted private keys |
| 119 buf := bytes.NewBuffer(nil) |
| 120 err = pk.PublicKey.serializeWithoutHeaders(buf) |
| 121 if err != nil { |
| 122 return |
| 123 } |
| 124 buf.WriteByte(0 /* no encryption */ ) |
| 125 |
| 126 privateKeyBuf := bytes.NewBuffer(nil) |
| 127 |
| 128 switch priv := pk.PrivateKey.(type) { |
| 129 case *rsa.PrivateKey: |
| 130 err = serializeRSAPrivateKey(privateKeyBuf, priv) |
| 131 case *dsa.PrivateKey: |
| 132 err = serializeDSAPrivateKey(privateKeyBuf, priv) |
| 133 default: |
| 134 err = errors.InvalidArgumentError("unknown private key type") |
| 135 } |
| 136 if err != nil { |
| 137 return |
| 138 } |
| 139 |
| 140 ptype := packetTypePrivateKey |
| 141 contents := buf.Bytes() |
| 142 privateKeyBytes := privateKeyBuf.Bytes() |
| 143 if pk.IsSubkey { |
| 144 ptype = packetTypePrivateSubkey |
| 145 } |
| 146 err = serializeHeader(w, ptype, len(contents)+len(privateKeyBytes)+2) |
| 147 if err != nil { |
| 148 return |
| 149 } |
| 150 _, err = w.Write(contents) |
| 151 if err != nil { |
| 152 return |
| 153 } |
| 154 _, err = w.Write(privateKeyBytes) |
| 155 if err != nil { |
| 156 return |
| 157 } |
| 158 |
| 159 checksum := mod64kHash(privateKeyBytes) |
| 160 var checksumBytes [2]byte |
| 161 checksumBytes[0] = byte(checksum >> 8) |
| 162 checksumBytes[1] = byte(checksum) |
| 163 _, err = w.Write(checksumBytes[:]) |
| 164 |
| 165 return |
| 166 } |
| 167 |
| 168 func serializeRSAPrivateKey(w io.Writer, priv *rsa.PrivateKey) error { |
| 169 err := writeBig(w, priv.D) |
| 170 if err != nil { |
| 171 return err |
| 172 } |
| 173 err = writeBig(w, priv.Primes[1]) |
| 174 if err != nil { |
| 175 return err |
| 176 } |
| 177 err = writeBig(w, priv.Primes[0]) |
| 178 if err != nil { |
| 179 return err |
| 180 } |
| 181 return writeBig(w, priv.Precomputed.Qinv) |
| 182 } |
| 183 |
| 184 func serializeDSAPrivateKey(w io.Writer, priv *dsa.PrivateKey) error { |
| 185 return writeBig(w, priv.X) |
| 186 } |
| 187 |
| 188 // Decrypt decrypts an encrypted private key using a passphrase. |
| 189 func (pk *PrivateKey) Decrypt(passphrase []byte) error { |
| 190 if !pk.Encrypted { |
| 191 return nil |
| 192 } |
| 193 |
| 194 key := make([]byte, pk.cipher.KeySize()) |
| 195 pk.s2k(key, passphrase) |
| 196 block := pk.cipher.new(key) |
| 197 cfb := cipher.NewCFBDecrypter(block, pk.iv) |
| 198 |
| 199 data := pk.encryptedData |
| 200 cfb.XORKeyStream(data, data) |
| 201 |
| 202 if pk.sha1Checksum { |
| 203 if len(data) < sha1.Size { |
| 204 return errors.StructuralError("truncated private key dat
a") |
| 205 } |
| 206 h := sha1.New() |
| 207 h.Write(data[:len(data)-sha1.Size]) |
| 208 sum := h.Sum(nil) |
| 209 if !bytes.Equal(sum, data[len(data)-sha1.Size:]) { |
| 210 return errors.StructuralError("private key checksum fail
ure") |
| 211 } |
| 212 data = data[:len(data)-sha1.Size] |
| 213 } else { |
| 214 if len(data) < 2 { |
| 215 return errors.StructuralError("truncated private key dat
a") |
| 216 } |
| 217 var sum uint16 |
| 218 for i := 0; i < len(data)-2; i++ { |
| 219 sum += uint16(data[i]) |
| 220 } |
| 221 if data[len(data)-2] != uint8(sum>>8) || |
| 222 data[len(data)-1] != uint8(sum) { |
| 223 return errors.StructuralError("private key checksum fail
ure") |
| 224 } |
| 225 data = data[:len(data)-2] |
| 226 } |
| 227 |
| 228 return pk.parsePrivateKey(data) |
| 229 } |
| 230 |
| 231 func (pk *PrivateKey) parsePrivateKey(data []byte) (err error) { |
| 232 switch pk.PublicKey.PubKeyAlgo { |
| 233 case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly, PubKeyAlgoRSAEncryptOnly: |
| 234 return pk.parseRSAPrivateKey(data) |
| 235 case PubKeyAlgoDSA: |
| 236 return pk.parseDSAPrivateKey(data) |
| 237 case PubKeyAlgoElGamal: |
| 238 return pk.parseElGamalPrivateKey(data) |
| 239 } |
| 240 panic("impossible") |
| 241 } |
| 242 |
| 243 func (pk *PrivateKey) parseRSAPrivateKey(data []byte) (err error) { |
| 244 rsaPub := pk.PublicKey.PublicKey.(*rsa.PublicKey) |
| 245 rsaPriv := new(rsa.PrivateKey) |
| 246 rsaPriv.PublicKey = *rsaPub |
| 247 |
| 248 buf := bytes.NewBuffer(data) |
| 249 d, _, err := readMPI(buf) |
| 250 if err != nil { |
| 251 return |
| 252 } |
| 253 p, _, err := readMPI(buf) |
| 254 if err != nil { |
| 255 return |
| 256 } |
| 257 q, _, err := readMPI(buf) |
| 258 if err != nil { |
| 259 return |
| 260 } |
| 261 |
| 262 rsaPriv.D = new(big.Int).SetBytes(d) |
| 263 rsaPriv.Primes = make([]*big.Int, 2) |
| 264 rsaPriv.Primes[0] = new(big.Int).SetBytes(p) |
| 265 rsaPriv.Primes[1] = new(big.Int).SetBytes(q) |
| 266 rsaPriv.Precompute() |
| 267 pk.PrivateKey = rsaPriv |
| 268 pk.Encrypted = false |
| 269 pk.encryptedData = nil |
| 270 |
| 271 return nil |
| 272 } |
| 273 |
| 274 func (pk *PrivateKey) parseDSAPrivateKey(data []byte) (err error) { |
| 275 dsaPub := pk.PublicKey.PublicKey.(*dsa.PublicKey) |
| 276 dsaPriv := new(dsa.PrivateKey) |
| 277 dsaPriv.PublicKey = *dsaPub |
| 278 |
| 279 buf := bytes.NewBuffer(data) |
| 280 x, _, err := readMPI(buf) |
| 281 if err != nil { |
| 282 return |
| 283 } |
| 284 |
| 285 dsaPriv.X = new(big.Int).SetBytes(x) |
| 286 pk.PrivateKey = dsaPriv |
| 287 pk.Encrypted = false |
| 288 pk.encryptedData = nil |
| 289 |
| 290 return nil |
| 291 } |
| 292 |
| 293 func (pk *PrivateKey) parseElGamalPrivateKey(data []byte) (err error) { |
| 294 pub := pk.PublicKey.PublicKey.(*elgamal.PublicKey) |
| 295 priv := new(elgamal.PrivateKey) |
| 296 priv.PublicKey = *pub |
| 297 |
| 298 buf := bytes.NewBuffer(data) |
| 299 x, _, err := readMPI(buf) |
| 300 if err != nil { |
| 301 return |
| 302 } |
| 303 |
| 304 priv.X = new(big.Int).SetBytes(x) |
| 305 pk.PrivateKey = priv |
| 306 pk.Encrypted = false |
| 307 pk.encryptedData = nil |
| 308 |
| 309 return nil |
| 310 } |
OLD | NEW |