~juju-qa/ubuntu/xenial/juju/2.0-rc2

« back to all changes in this revision

Viewing changes to src/golang.org/x/crypto/openpgp/packet/symmetric_key_encrypted.go

  • Committer: Nicholas Skaggs
  • Date: 2016-09-30 14:39:30 UTC
  • mfrom: (1.8.1)
  • Revision ID: nicholas.skaggs@canonical.com-20160930143930-vwwhrefh6ftckccy
import upstream

Show diffs side-by-side

added added

removed removed

Lines of Context:
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
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)
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")
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
 
                }
101
 
        }
102
 
 
103
 
        ske.Encrypted = false
104
 
        return nil
 
78
                return key, ske.CipherFunc, nil
 
79
        }
 
80
 
 
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(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