@@ -22,20 +22,17 @@ const maxSessionKeySizeInBytes = 64
22
22
// 4880, section 5.3.
23
23
type SymmetricKeyEncrypted struct {
24
24
CipherFunc CipherFunction
25
- Encrypted bool
26
- Key []byte // Empty unless Encrypted is false.
27
25
s2k func (out , in []byte )
28
26
encryptedKey []byte
29
27
}
30
28
31
29
const symmetricKeyEncryptedVersion = 4
32
30
33
- func (ske * SymmetricKeyEncrypted ) parse (r io.Reader ) ( err error ) {
31
+ func (ske * SymmetricKeyEncrypted ) parse (r io.Reader ) error {
34
32
// RFC 4880, section 5.3.
35
33
var buf [2 ]byte
36
- _ , err = readFull (r , buf [:])
37
- if err != nil {
38
- return
34
+ if _ , err := readFull (r , buf [:]); err != nil {
35
+ return err
39
36
}
40
37
if buf [0 ] != symmetricKeyEncryptedVersion {
41
38
return errors .UnsupportedError ("SymmetricKeyEncrypted version" )
@@ -46,62 +43,56 @@ func (ske *SymmetricKeyEncrypted) parse(r io.Reader) (err error) {
46
43
return errors .UnsupportedError ("unknown cipher: " + strconv .Itoa (int (buf [1 ])))
47
44
}
48
45
46
+ var err error
49
47
ske .s2k , err = s2k .Parse (r )
50
48
if err != nil {
51
- return
49
+ return err
52
50
}
53
51
54
52
encryptedKey := make ([]byte , maxSessionKeySizeInBytes )
55
53
// The session key may follow. We just have to try and read to find
56
54
// out. If it exists then we limit it to maxSessionKeySizeInBytes.
57
55
n , err := readFull (r , encryptedKey )
58
56
if err != nil && err != io .ErrUnexpectedEOF {
59
- return
57
+ return err
60
58
}
61
- err = nil
59
+
62
60
if n != 0 {
63
61
if n == maxSessionKeySizeInBytes {
64
62
return errors .UnsupportedError ("oversized encrypted session key" )
65
63
}
66
64
ske .encryptedKey = encryptedKey [:n ]
67
65
}
68
66
69
- ske .Encrypted = true
70
-
71
- return
67
+ return nil
72
68
}
73
69
74
- // Decrypt attempts to decrypt an encrypted session key. If it returns nil,
75
- // ske.Key will contain the session key.
76
- func (ske * SymmetricKeyEncrypted ) Decrypt (passphrase []byte ) error {
77
- if ! ske .Encrypted {
78
- return nil
79
- }
80
-
70
+ // Decrypt attempts to decrypt an encrypted session key and returns the key and
71
+ // the cipher to use when decrypting a subsequent Symmetrically Encrypted Data
72
+ // packet.
73
+ func (ske * SymmetricKeyEncrypted ) Decrypt (passphrase []byte ) ([]byte , CipherFunction , error ) {
81
74
key := make ([]byte , ske .CipherFunc .KeySize ())
82
75
ske .s2k (key , passphrase )
83
76
84
77
if len (ske .encryptedKey ) == 0 {
85
- ske .Key = key
86
- } else {
87
- // the IV is all zeros
88
- iv := make ([]byte , ske .CipherFunc .blockSize ())
89
- c := cipher .NewCFBDecrypter (ske .CipherFunc .new (key ), iv )
90
- c .XORKeyStream (ske .encryptedKey , ske .encryptedKey )
91
- ske .CipherFunc = CipherFunction (ske .encryptedKey [0 ])
92
- if ske .CipherFunc .blockSize () == 0 {
93
- return errors .UnsupportedError ("unknown cipher: " + strconv .Itoa (int (ske .CipherFunc )))
94
- }
95
- ske .CipherFunc = CipherFunction (ske .encryptedKey [0 ])
96
- ske .Key = ske .encryptedKey [1 :]
97
- if len (ske .Key )% ske .CipherFunc .blockSize () != 0 {
98
- ske .Key = nil
99
- return errors .StructuralError ("length of decrypted key not a multiple of block size" )
100
- }
78
+ return key , ske .CipherFunc , nil
101
79
}
102
80
103
- ske .Encrypted = false
104
- return nil
81
+ // the IV is all zeros
82
+ iv := make ([]byte , ske .CipherFunc .blockSize ())
83
+ c := cipher .NewCFBDecrypter (ske .CipherFunc .new (key ), iv )
84
+ plaintextKey := make ([]byte , len (ske .encryptedKey ))
85
+ c .XORKeyStream (plaintextKey , ske .encryptedKey )
86
+ cipherFunc := CipherFunction (plaintextKey [0 ])
87
+ if cipherFunc .blockSize () == 0 {
88
+ return nil , ske .CipherFunc , errors .UnsupportedError ("unknown cipher: " + strconv .Itoa (int (ske .CipherFunc )))
89
+ }
90
+ plaintextKey = plaintextKey [1 :]
91
+ if l := len (plaintextKey ); l == 0 || l % cipherFunc .blockSize () != 0 {
92
+ return nil , cipherFunc , errors .StructuralError ("length of decrypted key not a multiple of block size" )
93
+ }
94
+
95
+ return plaintextKey , cipherFunc , nil
105
96
}
106
97
107
98
// SerializeSymmetricKeyEncrypted serializes a symmetric key packet to w. The
0 commit comments