cubefs
78 строк · 1.5 Кб
1package sarama
2
3import (
4"crypto/hmac"
5"crypto/sha256"
6"crypto/sha512"
7"hash"
8)
9
10// ScramFormatter implementation
11// @see: https://github.com/apache/kafka/blob/99b9b3e84f4e98c3f07714e1de6a139a004cbc5b/clients/src/main/java/org/apache/kafka/common/security/scram/internals/ScramFormatter.java#L93
12type scramFormatter struct {
13mechanism ScramMechanismType
14}
15
16func (s scramFormatter) mac(key []byte) (hash.Hash, error) {
17var m hash.Hash
18
19switch s.mechanism {
20case SCRAM_MECHANISM_SHA_256:
21m = hmac.New(sha256.New, key)
22
23case SCRAM_MECHANISM_SHA_512:
24m = hmac.New(sha512.New, key)
25default:
26return nil, ErrUnknownScramMechanism
27}
28
29return m, nil
30}
31
32func (s scramFormatter) hmac(key []byte, extra []byte) ([]byte, error) {
33mac, err := s.mac(key)
34if err != nil {
35return nil, err
36}
37
38if _, err := mac.Write(extra); err != nil {
39return nil, err
40}
41return mac.Sum(nil), nil
42}
43
44func (s scramFormatter) xor(result []byte, second []byte) {
45for i := 0; i < len(result); i++ {
46result[i] = result[i] ^ second[i]
47}
48}
49
50func (s scramFormatter) saltedPassword(password []byte, salt []byte, iterations int) ([]byte, error) {
51mac, err := s.mac(password)
52if err != nil {
53return nil, err
54}
55
56if _, err := mac.Write(salt); err != nil {
57return nil, err
58}
59if _, err := mac.Write([]byte{0, 0, 0, 1}); err != nil {
60return nil, err
61}
62
63u1 := mac.Sum(nil)
64prev := u1
65result := u1
66
67for i := 2; i <= iterations; i++ {
68ui, err := s.hmac(password, prev)
69if err != nil {
70return nil, err
71}
72
73s.xor(result, ui)
74prev = ui
75}
76
77return result, nil
78}
79