OSDN Git Service

Create ossClient.go (#574)
[bytom/vapor.git] / vendor / github.com / aliyun / aliyun-oss-go-sdk / oss / crypto / aes_ctr_cipher.go
1 package osscrypto
2
3 import (
4         "io"
5 )
6
7 const (
8         aesKeySize = 32
9         ivSize     = 16
10 )
11
12 // aesCtrCipherBuilder for building ContentCipher
13 type aesCtrCipherBuilder struct {
14         MasterCipher MasterCipher
15 }
16
17 // aesCtrCipher will use aes ctr algorithm
18 type aesCtrCipher struct {
19         CipherData CipherData
20         Cipher     Cipher
21 }
22
23 // CreateAesCtrCipher creates ContentCipherBuilder
24 func CreateAesCtrCipher(cipher MasterCipher) ContentCipherBuilder {
25         return aesCtrCipherBuilder{MasterCipher: cipher}
26 }
27
28 // createCipherData create CipherData for encrypt object data
29 func (builder aesCtrCipherBuilder) createCipherData() (CipherData, error) {
30         var cd CipherData
31         var err error
32         err = cd.RandomKeyIv(aesKeySize, ivSize)
33         if err != nil {
34                 return cd, err
35         }
36
37         cd.WrapAlgorithm = builder.MasterCipher.GetWrapAlgorithm()
38         cd.CEKAlgorithm = AesCtrAlgorithm
39         cd.MatDesc = builder.MasterCipher.GetMatDesc()
40
41         // EncryptedKey
42         cd.EncryptedKey, err = builder.MasterCipher.Encrypt(cd.Key)
43         if err != nil {
44                 return cd, err
45         }
46
47         // EncryptedIV
48         cd.EncryptedIV, err = builder.MasterCipher.Encrypt(cd.IV)
49         if err != nil {
50                 return cd, err
51         }
52
53         return cd, nil
54 }
55
56 // contentCipherCD is used to create ContentCipher with CipherData
57 func (builder aesCtrCipherBuilder) contentCipherCD(cd CipherData) (ContentCipher, error) {
58         cipher, err := newAesCtr(cd)
59         if err != nil {
60                 return nil, err
61         }
62
63         return &aesCtrCipher{
64                 CipherData: cd,
65                 Cipher:     cipher,
66         }, nil
67 }
68
69 // ContentCipher is used to create ContentCipher interface
70 func (builder aesCtrCipherBuilder) ContentCipher() (ContentCipher, error) {
71         cd, err := builder.createCipherData()
72         if err != nil {
73                 return nil, err
74         }
75         return builder.contentCipherCD(cd)
76 }
77
78 // ContentCipherEnv is used to create a decrption ContentCipher from Envelope
79 func (builder aesCtrCipherBuilder) ContentCipherEnv(envelope Envelope) (ContentCipher, error) {
80         var cd CipherData
81         cd.EncryptedKey = make([]byte, len(envelope.CipherKey))
82         copy(cd.EncryptedKey, []byte(envelope.CipherKey))
83
84         plainKey, err := builder.MasterCipher.Decrypt([]byte(envelope.CipherKey))
85         if err != nil {
86                 return nil, err
87         }
88         cd.Key = make([]byte, len(plainKey))
89         copy(cd.Key, plainKey)
90
91         cd.EncryptedIV = make([]byte, len(envelope.IV))
92         copy(cd.EncryptedIV, []byte(envelope.IV))
93
94         plainIV, err := builder.MasterCipher.Decrypt([]byte(envelope.IV))
95         if err != nil {
96                 return nil, err
97         }
98
99         cd.IV = make([]byte, len(plainIV))
100         copy(cd.IV, plainIV)
101
102         cd.MatDesc = envelope.MatDesc
103         cd.WrapAlgorithm = envelope.WrapAlg
104         cd.CEKAlgorithm = envelope.CEKAlg
105
106         return builder.contentCipherCD(cd)
107 }
108
109 // GetMatDesc is used to get MasterCipher's MatDesc
110 func (builder aesCtrCipherBuilder) GetMatDesc() string {
111         return builder.MasterCipher.GetMatDesc()
112 }
113
114 // EncryptContents will generate a random key and iv and encrypt the data using ctr
115 func (cc *aesCtrCipher) EncryptContent(src io.Reader) (io.ReadCloser, error) {
116         reader := cc.Cipher.Encrypt(src)
117         return &CryptoEncrypter{Body: src, Encrypter: reader}, nil
118 }
119
120 // DecryptContent is used to decrypt object using ctr
121 func (cc *aesCtrCipher) DecryptContent(src io.Reader) (io.ReadCloser, error) {
122         reader := cc.Cipher.Decrypt(src)
123         return &CryptoDecrypter{Body: src, Decrypter: reader}, nil
124 }
125
126 // GetCipherData is used to get cipher data information
127 func (cc *aesCtrCipher) GetCipherData() *CipherData {
128         return &(cc.CipherData)
129 }
130
131 // GetCipherData returns cipher data
132 func (cc *aesCtrCipher) GetEncryptedLen(plainTextLen int64) int64 {
133         // AES CTR encryption mode does not change content length
134         return plainTextLen
135 }
136
137 // GetAlignLen is used to get align length
138 func (cc *aesCtrCipher) GetAlignLen() int {
139         return len(cc.CipherData.IV)
140 }
141
142 // Clone is used to create a new aesCtrCipher from itself
143 func (cc *aesCtrCipher) Clone(cd CipherData) (ContentCipher, error) {
144         cipher, err := newAesCtr(cd)
145         if err != nil {
146                 return nil, err
147         }
148
149         return &aesCtrCipher{
150                 CipherData: cd,
151                 Cipher:     cipher,
152         }, nil
153 }