38
if buf[0] != encryptedKeyVersion {
34
39
return error.UnsupportedError("unknown EncryptedKey version " + strconv.Itoa(int(buf[0])))
36
41
e.KeyId = binary.BigEndian.Uint64(buf[1:9])
37
42
e.Algo = PublicKeyAlgorithm(buf[9])
38
if e.Algo == PubKeyAlgoRSA || e.Algo == PubKeyAlgoRSAEncryptOnly {
39
e.Encrypted, _, err = readMPI(r)
44
case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly:
45
e.encryptedMPI1, _, err = readMPI(r)
46
case PubKeyAlgoElGamal:
47
e.encryptedMPI1, _, err = readMPI(r)
51
e.encryptedMPI2, _, err = readMPI(r)
41
53
_, err = consumeAll(r)
45
// DecryptRSA decrypts an RSA encrypted session key with the given private key.
46
func (e *EncryptedKey) DecryptRSA(priv *rsa.PrivateKey) (err os.Error) {
47
if e.Algo != PubKeyAlgoRSA && e.Algo != PubKeyAlgoRSAEncryptOnly {
48
return error.InvalidArgumentError("EncryptedKey not RSA encrypted")
50
b, err := rsa.DecryptPKCS1v15(rand.Reader, priv, e.Encrypted)
57
func checksumKeyMaterial(key []byte) uint16 {
59
for _, v := range key {
65
// Decrypt decrypts an encrypted session key with the given private key. The
66
// private key must have been decrypted first.
67
func (e *EncryptedKey) Decrypt(priv *PrivateKey) os.Error {
71
// TODO(agl): use session key decryption routines here to avoid
72
// padding oracle attacks.
73
switch priv.PubKeyAlgo {
74
case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly:
75
b, err = rsa.DecryptPKCS1v15(rand.Reader, priv.PrivateKey.(*rsa.PrivateKey), e.encryptedMPI1)
76
case PubKeyAlgoElGamal:
77
c1 := new(big.Int).SetBytes(e.encryptedMPI1)
78
c2 := new(big.Int).SetBytes(e.encryptedMPI2)
79
b, err = elgamal.Decrypt(priv.PrivateKey.(*elgamal.PrivateKey), c1, c2)
81
err = error.InvalidArgumentError("cannot decrypted encrypted session key with private key of type " + strconv.Itoa(int(priv.PubKeyAlgo)))
54
88
e.CipherFunc = CipherFunction(b[0])
55
89
e.Key = b[1 : len(b)-2]
56
90
expectedChecksum := uint16(b[len(b)-2])<<8 | uint16(b[len(b)-1])
58
for _, v := range e.Key {
91
checksum := checksumKeyMaterial(e.Key)
61
92
if checksum != expectedChecksum {
62
93
return error.StructuralError("EncryptedKey checksum incorrect")
99
// SerializeEncryptedKey serializes an encrypted key packet to w that contains
100
// key, encrypted to pub.
101
func SerializeEncryptedKey(w io.Writer, rand io.Reader, pub *PublicKey, cipherFunc CipherFunction, key []byte) os.Error {
103
buf[0] = encryptedKeyVersion
104
binary.BigEndian.PutUint64(buf[1:9], pub.KeyId)
105
buf[9] = byte(pub.PubKeyAlgo)
107
keyBlock := make([]byte, 1 /* cipher type */ +len(key)+2 /* checksum */ )
108
keyBlock[0] = byte(cipherFunc)
109
copy(keyBlock[1:], key)
110
checksum := checksumKeyMaterial(key)
111
keyBlock[1+len(key)] = byte(checksum >> 8)
112
keyBlock[1+len(key)+1] = byte(checksum)
114
switch pub.PubKeyAlgo {
115
case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly:
116
return serializeEncryptedKeyRSA(w, rand, buf, pub.PublicKey.(*rsa.PublicKey), keyBlock)
117
case PubKeyAlgoElGamal:
118
return serializeEncryptedKeyElGamal(w, rand, buf, pub.PublicKey.(*elgamal.PublicKey), keyBlock)
119
case PubKeyAlgoDSA, PubKeyAlgoRSASignOnly:
120
return error.InvalidArgumentError("cannot encrypt to public key of type " + strconv.Itoa(int(pub.PubKeyAlgo)))
123
return error.UnsupportedError("encrypting a key to public key of type " + strconv.Itoa(int(pub.PubKeyAlgo)))
126
func serializeEncryptedKeyRSA(w io.Writer, rand io.Reader, header [10]byte, pub *rsa.PublicKey, keyBlock []byte) os.Error {
127
cipherText, err := rsa.EncryptPKCS1v15(rand, pub, keyBlock)
129
return error.InvalidArgumentError("RSA encryption failed: " + err.String())
132
packetLen := 10 /* header length */ + 2 /* mpi size */ + len(cipherText)
134
err = serializeHeader(w, packetTypeEncryptedKey, packetLen)
138
_, err = w.Write(header[:])
142
return writeMPI(w, 8*uint16(len(cipherText)), cipherText)
145
func serializeEncryptedKeyElGamal(w io.Writer, rand io.Reader, header [10]byte, pub *elgamal.PublicKey, keyBlock []byte) os.Error {
146
c1, c2, err := elgamal.Encrypt(rand, pub, keyBlock)
148
return error.InvalidArgumentError("ElGamal encryption failed: " + err.String())
151
packetLen := 10 /* header length */
152
packetLen += 2 /* mpi size */ + (c1.BitLen()+7)/8
153
packetLen += 2 /* mpi size */ + (c2.BitLen()+7)/8
155
err = serializeHeader(w, packetTypeEncryptedKey, packetLen)
159
_, err = w.Write(header[:])
163
err = writeBig(w, c1)
167
return writeBig(w, c2)