OSDN Git Service

Create ossClient.go (#574)
[bytom/vapor.git] / vendor / github.com / aliyun / aliyun-oss-go-sdk / oss / crypto / crypto_type.go
1 package osscrypto
2
3 import (
4         "crypto/rand"
5         "encoding/binary"
6         "fmt"
7         "io"
8         math_rand "math/rand"
9         "time"
10 )
11
12 // MasterCipher encrypt or decrpt CipherData
13 // support master key: rsa && ali kms
14 type MasterCipher interface {
15         Encrypt([]byte) ([]byte, error)
16         Decrypt([]byte) ([]byte, error)
17         GetWrapAlgorithm() string
18         GetMatDesc() string
19 }
20
21 // ContentCipherBuilder is used to create ContentCipher for encryting object's data
22 type ContentCipherBuilder interface {
23         ContentCipher() (ContentCipher, error)
24         ContentCipherEnv(Envelope) (ContentCipher, error)
25         GetMatDesc() string
26 }
27
28 // ContentCipher is used to encrypt or decrypt object's data
29 type ContentCipher interface {
30         EncryptContent(io.Reader) (io.ReadCloser, error)
31         DecryptContent(io.Reader) (io.ReadCloser, error)
32         Clone(cd CipherData) (ContentCipher, error)
33         GetEncryptedLen(int64) int64
34         GetCipherData() *CipherData
35         GetAlignLen() int
36 }
37
38 // Envelope is stored in oss object's meta
39 type Envelope struct {
40         IV                    string
41         CipherKey             string
42         MatDesc               string
43         WrapAlg               string
44         CEKAlg                string
45         UnencryptedMD5        string
46         UnencryptedContentLen string
47 }
48
49 func (el Envelope) IsValid() bool {
50         return len(el.IV) > 0 &&
51                 len(el.CipherKey) > 0 &&
52                 len(el.WrapAlg) > 0 &&
53                 len(el.CEKAlg) > 0
54 }
55
56 func (el Envelope) String() string {
57         return fmt.Sprintf("IV=%s&CipherKey=%s&WrapAlg=%s&CEKAlg=%s", el.IV, el.CipherKey, el.WrapAlg, el.CEKAlg)
58 }
59
60 // CipherData is secret key information
61 type CipherData struct {
62         IV            []byte
63         Key           []byte
64         MatDesc       string
65         WrapAlgorithm string
66         CEKAlgorithm  string
67         EncryptedIV   []byte
68         EncryptedKey  []byte
69 }
70
71 func (cd *CipherData) RandomKeyIv(keyLen int, ivLen int) error {
72         math_rand.Seed(time.Now().UnixNano())
73
74         // Key
75         cd.Key = make([]byte, keyLen)
76         if _, err := io.ReadFull(rand.Reader, cd.Key); err != nil {
77                 return err
78         }
79
80         // sizeof uint64
81         if ivLen < 8 {
82                 return fmt.Errorf("ivLen:%d less than 8", ivLen)
83         }
84
85         // IV:reserve 8 bytes
86         cd.IV = make([]byte, ivLen)
87         if _, err := io.ReadFull(rand.Reader, cd.IV[0:ivLen-8]); err != nil {
88                 return err
89         }
90
91         // only use 4 byte,in order not to overflow when SeekIV()
92         randNumber := math_rand.Uint32()
93         cd.SetIV(uint64(randNumber))
94         return nil
95 }
96
97 func (cd *CipherData) SetIV(iv uint64) {
98         ivLen := len(cd.IV)
99         binary.BigEndian.PutUint64(cd.IV[ivLen-8:], iv)
100 }
101
102 func (cd *CipherData) GetIV() uint64 {
103         ivLen := len(cd.IV)
104         return binary.BigEndian.Uint64(cd.IV[ivLen-8:])
105 }
106
107 func (cd *CipherData) SeekIV(startPos uint64) {
108         cd.SetIV(cd.GetIV() + startPos/uint64(len(cd.IV)))
109 }
110
111 func (cd *CipherData) Clone() CipherData {
112         var cloneCd CipherData
113         cloneCd = *cd
114
115         cloneCd.Key = make([]byte, len(cd.Key))
116         copy(cloneCd.Key, cd.Key)
117
118         cloneCd.IV = make([]byte, len(cd.IV))
119         copy(cloneCd.IV, cd.IV)
120
121         cloneCd.EncryptedIV = make([]byte, len(cd.EncryptedIV))
122         copy(cloneCd.EncryptedIV, cd.EncryptedIV)
123
124         cloneCd.EncryptedKey = make([]byte, len(cd.EncryptedKey))
125         copy(cloneCd.EncryptedKey, cd.EncryptedKey)
126
127         return cloneCd
128 }