summaryrefslogtreecommitdiff
path: root/src/pkg/crypto/openpgp/packet/encrypted_key.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/pkg/crypto/openpgp/packet/encrypted_key.go')
-rw-r--r--src/pkg/crypto/openpgp/packet/encrypted_key.go66
1 files changed, 66 insertions, 0 deletions
diff --git a/src/pkg/crypto/openpgp/packet/encrypted_key.go b/src/pkg/crypto/openpgp/packet/encrypted_key.go
new file mode 100644
index 000000000..4a926cdb1
--- /dev/null
+++ b/src/pkg/crypto/openpgp/packet/encrypted_key.go
@@ -0,0 +1,66 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package packet
+
+import (
+ "crypto/openpgp/error"
+ "crypto/rand"
+ "crypto/rsa"
+ "encoding/binary"
+ "io"
+ "os"
+ "strconv"
+)
+
+// EncryptedKey represents a public-key encrypted session key. See RFC 4880,
+// section 5.1.
+type EncryptedKey struct {
+ KeyId uint64
+ Algo PublicKeyAlgorithm
+ Encrypted []byte
+ CipherFunc CipherFunction // only valid after a sucessful Decrypt
+ Key []byte // only valid after a sucessful Decrypt
+}
+
+func (e *EncryptedKey) parse(r io.Reader) (err os.Error) {
+ var buf [10]byte
+ _, err = readFull(r, buf[:])
+ if err != nil {
+ return
+ }
+ if buf[0] != 3 {
+ return error.UnsupportedError("unknown EncryptedKey version " + strconv.Itoa(int(buf[0])))
+ }
+ e.KeyId = binary.BigEndian.Uint64(buf[1:9])
+ e.Algo = PublicKeyAlgorithm(buf[9])
+ if e.Algo == PubKeyAlgoRSA || e.Algo == PubKeyAlgoRSAEncryptOnly {
+ e.Encrypted, _, err = readMPI(r)
+ }
+ _, err = consumeAll(r)
+ return
+}
+
+// DecryptRSA decrypts an RSA encrypted session key with the given private key.
+func (e *EncryptedKey) DecryptRSA(priv *rsa.PrivateKey) (err os.Error) {
+ if e.Algo != PubKeyAlgoRSA && e.Algo != PubKeyAlgoRSAEncryptOnly {
+ return error.InvalidArgumentError("EncryptedKey not RSA encrypted")
+ }
+ b, err := rsa.DecryptPKCS1v15(rand.Reader, priv, e.Encrypted)
+ if err != nil {
+ return
+ }
+ e.CipherFunc = CipherFunction(b[0])
+ e.Key = b[1 : len(b)-2]
+ expectedChecksum := uint16(b[len(b)-2])<<8 | uint16(b[len(b)-1])
+ var checksum uint16
+ for _, v := range e.Key {
+ checksum += uint16(v)
+ }
+ if checksum != expectedChecksum {
+ return error.StructuralError("EncryptedKey checksum incorrect")
+ }
+
+ return
+}