-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathenc_kx_decryptor.go
118 lines (97 loc) · 2.15 KB
/
enc_kx_decryptor.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
package crypka
import (
"bytes"
)
type encKxDecryptor struct {
algo *EncAsymKXAlgo
secret KXSecret
ctx KeyContext
encoding intEncoding
wrappedDecryptor Decryptor
cachedError error
}
func (dec *encKxDecryptor) GetEncInfo() EncInfo {
return EncInfo{
RequiresFinalization: dec.algo.GetInfo().RequiresFinalization,
EncType: dec.algo.GetInfo().EncType,
}
}
func (dec *encKxDecryptor) Decrypt(in, appendTo []byte) (res []byte, err error) {
if dec.cachedError != nil {
err = dec.cachedError
return
}
defer func() {
if err != nil {
dec.cachedError = err
}
}()
if dec.wrappedDecryptor != nil {
return dec.wrappedDecryptor.Decrypt(in, appendTo)
}
res = appendTo
value, valueSz, err := dec.encoding.DecodeAtStart(in)
if err != nil {
return
}
in = in[valueSz:]
if dec.algo.MaxMarshaledEphemeralLength <= 0 {
if value > 1<<20 {
err = ErrEncStreamChunkTooBig
return
}
} else {
if value > uint64(dec.algo.MaxMarshaledEphemeralLength) {
err = ErrEncStreamChunkTooBig
return
}
}
if uint64(len(in)) < value {
err = ErrEncStreamCorrupted
return
}
rawEphermeralPublic := in[:int(value)]
ephPublic, err := dec.algo.KXAlgo.ParseKXPublic(dec.ctx, rawEphermeralPublic)
if err != nil {
return
}
in = in[len(rawEphermeralPublic):]
buf := make([]byte, dec.algo.KXResultLength)
err = dec.algo.KXAlgo.PerformExchange(dec.ctx, ephPublic, dec.secret, buf)
if err != nil {
return
}
var keyRNG RNG
if dec.algo.RNGAlgo == nil {
keyRNG = bytes.NewReader(buf)
} else {
keyRNG, err = dec.algo.RNGAlgo.MakeRng(dec.ctx, buf)
if err != nil {
return
}
}
sk, err := dec.algo.EncSymmAlgo.GenerateKey(dec.ctx, keyRNG)
if err != nil {
return
}
dec.wrappedDecryptor, err = sk.MakeDecryptor(dec.ctx)
if err != nil {
return
}
res, err = dec.wrappedDecryptor.Decrypt(in, res)
return
}
func (dec *encKxDecryptor) Finalize() (err error) {
if dec.cachedError != nil {
err = dec.cachedError
return
}
if dec.GetEncInfo().RequiresFinalization && dec.wrappedDecryptor == nil {
err = ErrEncAuthFiled
return
}
if dec.wrappedDecryptor != nil {
return dec.wrappedDecryptor.Finalize()
}
return
}