mirror of
https://github.com/fhmq/hmq.git
synced 2026-09-01 23:34:52 +00:00
Plugins support (#46)
* modify * update * add acl * add feature * update dockerfile * add deploy * update * update * plugins * plugins * update * update * update * fixed * remove * fixed * add log * update * fixed * update * fix config * add http api * add http api * resp * add config for work chan * update * fixed * update * disable trace * fixed * change acl * fixed * fixed res * dd * dd * ddd * dd * update * fixed * update * add * fixed * update key * add log * update * format * update * update auth * update * update readme * added * update * fixed * fixed * fix * upade * update * update
This commit is contained in:
+143
@@ -0,0 +1,143 @@
|
||||
// Package common provides encryption methods common across encryption types
|
||||
package common
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/hmac"
|
||||
"encoding/binary"
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"gopkg.in/jcmturner/gokrb5.v7/crypto/etype"
|
||||
)
|
||||
|
||||
// ZeroPad pads bytes with zeros to nearest multiple of message size m.
|
||||
func ZeroPad(b []byte, m int) ([]byte, error) {
|
||||
if m <= 0 {
|
||||
return nil, errors.New("Invalid message block size when padding")
|
||||
}
|
||||
if b == nil || len(b) == 0 {
|
||||
return nil, errors.New("Data not valid to pad: Zero size")
|
||||
}
|
||||
if l := len(b) % m; l != 0 {
|
||||
n := m - l
|
||||
z := make([]byte, n)
|
||||
b = append(b, z...)
|
||||
}
|
||||
return b, nil
|
||||
}
|
||||
|
||||
// PKCS7Pad pads bytes according to RFC 2315 to nearest multiple of message size m.
|
||||
func PKCS7Pad(b []byte, m int) ([]byte, error) {
|
||||
if m <= 0 {
|
||||
return nil, errors.New("Invalid message block size when padding")
|
||||
}
|
||||
if b == nil || len(b) == 0 {
|
||||
return nil, errors.New("Data not valid to pad: Zero size")
|
||||
}
|
||||
n := m - (len(b) % m)
|
||||
pb := make([]byte, len(b)+n)
|
||||
copy(pb, b)
|
||||
copy(pb[len(b):], bytes.Repeat([]byte{byte(n)}, n))
|
||||
return pb, nil
|
||||
}
|
||||
|
||||
// PKCS7Unpad removes RFC 2315 padding from byes where message size is m.
|
||||
func PKCS7Unpad(b []byte, m int) ([]byte, error) {
|
||||
if m <= 0 {
|
||||
return nil, errors.New("invalid message block size when unpadding")
|
||||
}
|
||||
if b == nil || len(b) == 0 {
|
||||
return nil, errors.New("padded data not valid: Zero size")
|
||||
}
|
||||
if len(b)%m != 0 {
|
||||
return nil, errors.New("padded data not valid: Not multiple of message block size")
|
||||
}
|
||||
c := b[len(b)-1]
|
||||
n := int(c)
|
||||
if n == 0 || n > len(b) {
|
||||
return nil, errors.New("padded data not valid: Data may not have been padded")
|
||||
}
|
||||
for i := 0; i < n; i++ {
|
||||
if b[len(b)-n+i] != c {
|
||||
return nil, errors.New("padded data not valid")
|
||||
}
|
||||
}
|
||||
return b[:len(b)-n], nil
|
||||
}
|
||||
|
||||
// GetHash generates the keyed hash value according to the etype's hash function.
|
||||
func GetHash(pt, key []byte, usage []byte, etype etype.EType) ([]byte, error) {
|
||||
k, err := etype.DeriveKey(key, usage)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to derive key for checksum: %v", err)
|
||||
}
|
||||
mac := hmac.New(etype.GetHashFunc(), k)
|
||||
p := make([]byte, len(pt))
|
||||
copy(p, pt)
|
||||
mac.Write(p)
|
||||
return mac.Sum(nil)[:etype.GetHMACBitLength()/8], nil
|
||||
}
|
||||
|
||||
// GetChecksumHash returns a keyed checksum hash of the bytes provided.
|
||||
func GetChecksumHash(b, key []byte, usage uint32, etype etype.EType) ([]byte, error) {
|
||||
return GetHash(b, key, GetUsageKc(usage), etype)
|
||||
}
|
||||
|
||||
// GetIntegrityHash returns a keyed integrity hash of the bytes provided.
|
||||
func GetIntegrityHash(b, key []byte, usage uint32, etype etype.EType) ([]byte, error) {
|
||||
return GetHash(b, key, GetUsageKi(usage), etype)
|
||||
}
|
||||
|
||||
// VerifyChecksum compares the checksum of the msg bytes is the same as the checksum provided.
|
||||
func VerifyChecksum(key, chksum, msg []byte, usage uint32, etype etype.EType) bool {
|
||||
//The ciphertext output is the concatenation of the output of the basic
|
||||
//encryption function E and a (possibly truncated) HMAC using the
|
||||
//specified hash function H, both applied to the plaintext with a
|
||||
//random confounder prefix and sufficient padding to bring it to a
|
||||
//multiple of the message block size. When the HMAC is computed, the
|
||||
//key is used in the protocol key form.
|
||||
expectedMAC, _ := GetChecksumHash(msg, key, usage, etype)
|
||||
return hmac.Equal(chksum, expectedMAC)
|
||||
}
|
||||
|
||||
// GetUsageKc returns the checksum key usage value for the usage number un.
|
||||
//
|
||||
// RFC 3961: The "well-known constant" used for the DK function is the key usage number, expressed as four octets in big-endian order, followed by one octet indicated below.
|
||||
//
|
||||
// Kc = DK(base-key, usage | 0x99);
|
||||
func GetUsageKc(un uint32) []byte {
|
||||
return getUsage(un, 0x99)
|
||||
}
|
||||
|
||||
// GetUsageKe returns the encryption key usage value for the usage number un
|
||||
//
|
||||
// RFC 3961: The "well-known constant" used for the DK function is the key usage number, expressed as four octets in big-endian order, followed by one octet indicated below.
|
||||
//
|
||||
// Ke = DK(base-key, usage | 0xAA);
|
||||
func GetUsageKe(un uint32) []byte {
|
||||
return getUsage(un, 0xAA)
|
||||
}
|
||||
|
||||
// GetUsageKi returns the integrity key usage value for the usage number un
|
||||
//
|
||||
// RFC 3961: The "well-known constant" used for the DK function is the key usage number, expressed as four octets in big-endian order, followed by one octet indicated below.
|
||||
//
|
||||
// Ki = DK(base-key, usage | 0x55);
|
||||
func GetUsageKi(un uint32) []byte {
|
||||
return getUsage(un, 0x55)
|
||||
}
|
||||
|
||||
func getUsage(un uint32, o byte) []byte {
|
||||
var buf bytes.Buffer
|
||||
binary.Write(&buf, binary.BigEndian, un)
|
||||
return append(buf.Bytes(), o)
|
||||
}
|
||||
|
||||
// IterationsToS2Kparams converts the number of iterations as an integer to a string representation.
|
||||
func IterationsToS2Kparams(i uint32) string {
|
||||
b := make([]byte, 4, 4)
|
||||
binary.BigEndian.PutUint32(b, i)
|
||||
return hex.EncodeToString(b)
|
||||
}
|
||||
Reference in New Issue
Block a user