feat(db): 添加对达梦数据库的支持

- 在应用程序中新增对达梦数据库(DM)的配置和连接支持
- 实现 SetDmDB 函数以配置达梦数据库连接
- 更新数据库操作逻辑,支持达梦特有的 SQL 语法和功能
- 在相关文件中添加达梦数据库的处理逻辑,包括表创建、数据插入和查询
- 更新 go.mod 和 go.sum 文件以引入达梦数据库驱动
- 增强文档,详细说明达梦数据库的配置和使用方法
This commit is contained in:
2026-03-20 10:46:51 +08:00
parent 1546967918
commit 7f7b585ffb
194 changed files with 211502 additions and 2328 deletions
+30
View File
@@ -0,0 +1,30 @@
/*
* Copyright (c) 2000-2018, 达梦数据库有限公司.
* All rights reserved.
*/
// This is a mirror of golang.org/x/crypto/internal/subtle.
package security
import "unsafe"
// AnyOverlap reports whether x and y share memory at any (not necessarily
// corresponding) index. The memory beyond the slice length is ignored.
func AnyOverlap(x, y []byte) bool {
return len(x) > 0 && len(y) > 0 &&
uintptr(unsafe.Pointer(&x[0])) <= uintptr(unsafe.Pointer(&y[len(y)-1])) &&
uintptr(unsafe.Pointer(&y[0])) <= uintptr(unsafe.Pointer(&x[len(x)-1]))
}
// InexactOverlap reports whether x and y share memory at any non-corresponding
// index. The memory beyond the slice length is ignored. Note that x and y can
// have different lengths and still not have any inexact overlap.
//
// InexactOverlap can be used to implement the requirements of the crypto/cipher
// AEAD, Block, BlockMode and Stream interfaces.
func InexactOverlap(x, y []byte) bool {
if len(x) == 0 || len(y) == 0 || &x[0] == &y[0] {
return false
}
return AnyOverlap(x, y)
}
+11
View File
@@ -0,0 +1,11 @@
/*
* Copyright (c) 2000-2018, 达梦数据库有限公司.
* All rights reserved.
*/
package security
type Cipher interface {
Encrypt(plaintext []byte, genDigest bool) []byte
Decrypt(ciphertext []byte, checkDigest bool) ([]byte, error)
}
+87
View File
@@ -0,0 +1,87 @@
/*
* Copyright (c) 2000-2018, 达梦数据库有限公司.
* All rights reserved.
*/
package security
import (
"crypto/rand"
"errors"
"io"
"math/big"
)
type dhGroup struct {
p *big.Int
g *big.Int
}
func newDhGroup(prime, generator *big.Int) *dhGroup {
return &dhGroup{
p: prime,
g: generator,
}
}
func (dg *dhGroup) P() *big.Int {
p := new(big.Int)
p.Set(dg.p)
return p
}
func (dg *dhGroup) G() *big.Int {
g := new(big.Int)
g.Set(dg.g)
return g
}
// 生成本地公私钥
func (dg *dhGroup) GeneratePrivateKey(randReader io.Reader) (key *DhKey, err error) {
if randReader == nil {
randReader = rand.Reader
}
// 0 < x < p
x, err := rand.Int(randReader, dg.p)
if err != nil {
return
}
zero := big.NewInt(0)
for x.Cmp(zero) == 0 {
x, err = rand.Int(randReader, dg.p)
if err != nil {
return
}
}
key = new(DhKey)
key.x = x
// y = g ^ x mod p
key.y = new(big.Int).Exp(dg.g, x, dg.p)
key.group = dg
return
}
func (dg *dhGroup) ComputeKey(pubkey *DhKey, privkey *DhKey) (kye *DhKey, err error) {
if dg.p == nil {
err = errors.New("DH: invalid group")
return
}
if pubkey.y == nil {
err = errors.New("DH: invalid public key")
return
}
if pubkey.y.Sign() <= 0 || pubkey.y.Cmp(dg.p) >= 0 {
err = errors.New("DH parameter out of bounds")
return
}
if privkey.x == nil {
err = errors.New("DH: invalid private key")
return
}
k := new(big.Int).Exp(pubkey.y, privkey.x, dg.p)
key := new(DhKey)
key.y = k
key.group = dg
return
}
+64
View File
@@ -0,0 +1,64 @@
/*
* Copyright (c) 2000-2018, 达梦数据库有限公司.
* All rights reserved.
*/
package security
import "math/big"
type DhKey struct {
x *big.Int
y *big.Int
group *dhGroup
}
func newPublicKey(s []byte) *DhKey {
key := new(DhKey)
key.y = new(big.Int).SetBytes(s)
return key
}
func (dk *DhKey) GetX() *big.Int {
x := new(big.Int)
x.Set(dk.x)
return x
}
func (dk *DhKey) GetY() *big.Int {
y := new(big.Int)
y.Set(dk.y)
return y
}
func (dk *DhKey) GetYBytes() []byte {
if dk.y == nil {
return nil
}
if dk.group != nil {
blen := (dk.group.p.BitLen() + 7) / 8
ret := make([]byte, blen)
copyWithLeftPad(ret, dk.y.Bytes())
return ret
}
return dk.y.Bytes()
}
func (dk *DhKey) GetYString() string {
if dk.y == nil {
return ""
}
return dk.y.String()
}
func (dk *DhKey) IsPrivateKey() bool {
return dk.x != nil
}
func copyWithLeftPad(dest, src []byte) {
numPaddingBytes := len(dest) - len(src)
for i := 0; i < numPaddingBytes; i++ {
dest[i] = 0
}
copy(dest[:numPaddingBytes], src)
}
+69
View File
@@ -0,0 +1,69 @@
/*
* Copyright (c) 2000-2018, 达梦数据库有限公司.
* All rights reserved.
*/
// go官方没有实现ecb加密模式
package security
import (
"crypto/cipher"
)
type ecb struct {
b cipher.Block
blockSize int
}
func newECB(b cipher.Block) *ecb {
return &ecb{
b: b,
blockSize: b.BlockSize(),
}
}
type ecbEncrypter ecb
func NewECBEncrypter(b cipher.Block) cipher.BlockMode {
return (*ecbEncrypter)(newECB(b))
}
func (x *ecbEncrypter) BlockSize() int { return x.blockSize }
func (x *ecbEncrypter) CryptBlocks(dst, src []byte) {
if len(src)%x.blockSize != 0 {
panic("dm/security: input not full blocks")
}
if len(dst) < len(src) {
panic("dm/security: output smaller than input")
}
if InexactOverlap(dst[:len(src)], src) {
panic("dm/security: invalid buffer overlap")
}
for bs, be := 0, x.blockSize; bs < len(src); bs, be = bs+x.blockSize, be+x.blockSize {
x.b.Encrypt(dst[bs:be], src[bs:be])
}
}
type ecbDecrypter ecb
func NewECBDecrypter(b cipher.Block) cipher.BlockMode {
return (*ecbDecrypter)(newECB(b))
}
func (x *ecbDecrypter) BlockSize() int { return x.blockSize }
func (x *ecbDecrypter) CryptBlocks(dst, src []byte) {
if len(src)%x.blockSize != 0 {
panic("dm/security: input not full blocks")
}
if len(dst) < len(src) {
panic("dm/security: output smaller than input")
}
if InexactOverlap(dst[:len(src)], src) {
panic("dm/security: invalid buffer overlap")
}
for bs, be := 0, x.blockSize; bs < len(src); bs, be = bs+x.blockSize, be+x.blockSize {
x.b.Decrypt(dst[bs:be], src[bs:be])
}
}
+114
View File
@@ -0,0 +1,114 @@
/*
* Copyright (c) 2000-2018, 达梦数据库有限公司.
* All rights reserved.
*/
package security
import (
"math/big"
)
const (
DH_KEY_LENGTH int = 64
/* 低7位用于保存分组加密算法中的工作模式 */
WORK_MODE_MASK int = 0x007f
ECB_MODE int = 0x1
CBC_MODE int = 0x2
CFB_MODE int = 0x4
OFB_MODE int = 0x8
/* 高位保存加密算法 */
ALGO_MASK int = 0xff80
DES int = 0x0080
DES3 int = 0x0100
AES128 int = 0x0200
AES192 int = 0x0400
AES256 int = 0x0800
RC4 int = 0x1000
MD5 int = 0x1100
// 用户名密码加密算法
DES_CFB int = 132
// 消息加密摘要长度
MD5_DIGEST_SIZE int = 16
MIN_EXTERNAL_CIPHER_ID int = 5000
)
var dhParaP = "C009D877BAF5FAF416B7F778E6115DCB90D65217DCC2F08A9DFCB5A192C593EBAB02929266B8DBFC2021039FDBD4B7FDE2B996E00008F57AE6EFB4ED3F17B6D3"
var dhParaG = "5"
var defaultIV = []byte{0x20, 0x21, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a,
0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a,
0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x20}
var p *big.Int
var g *big.Int
func NewClientKeyPair() (key *DhKey, err error) {
p, _ = new(big.Int).SetString(dhParaP, 16)
g, _ = new(big.Int).SetString(dhParaG, 16)
dhGroup := newDhGroup(p, g)
key, err = dhGroup.GeneratePrivateKey(nil)
if err != nil {
return nil, err
}
return key, nil
}
func ComputeSessionKey(clientPrivKey *DhKey, serverPubKey []byte) []byte {
serverKeyX := bytes2Bn(serverPubKey)
clientPrivKeyX := clientPrivKey.GetX()
sessionKeyBN := serverKeyX.Exp(serverKeyX, clientPrivKeyX, p)
return Bn2Bytes(sessionKeyBN, 0)
}
func bytes2Bn(bnBytesSrc []byte) *big.Int {
if bnBytesSrc == nil {
return nil
}
if bnBytesSrc[0] == 0 {
return new(big.Int).SetBytes(bnBytesSrc)
}
validBytesCount := len(bnBytesSrc) + 1
bnBytesTo := make([]byte, validBytesCount)
bnBytesTo[0] = 0
copy(bnBytesTo[1:validBytesCount], bnBytesSrc)
return new(big.Int).SetBytes(bnBytesTo)
}
func Bn2Bytes(bn *big.Int, bnLen int) []byte {
var bnBytesSrc, bnBytesTemp, bnBytesTo []byte
var leading_zero_count int
validBytesCount := 0
if bn == nil {
return nil
}
bnBytesSrc = bn.Bytes()
// 去除首位0
if bnBytesSrc[0] != 0 {
bnBytesTemp = bnBytesSrc
validBytesCount = len(bnBytesTemp)
} else {
validBytesCount = len(bnBytesSrc) - 1
bnBytesTemp = make([]byte, validBytesCount)
copy(bnBytesTemp, bnBytesSrc[1:validBytesCount+1])
}
if bnLen == 0 {
leading_zero_count = 0
} else {
leading_zero_count = bnLen - validBytesCount
}
// 如果位数不足DH_KEY_LENGTH则在前面补0
if leading_zero_count > 0 {
bnBytesTo = make([]byte, DH_KEY_LENGTH)
i := 0
for i = 0; i < leading_zero_count; i++ {
bnBytesTo[i] = 0
}
copy(bnBytesTo[i:i+validBytesCount], bnBytesTemp)
} else {
bnBytesTo = bnBytesTemp
}
return bnBytesTo
}
+211
View File
@@ -0,0 +1,211 @@
/*
* Copyright (c) 2000-2018, 达梦数据库有限公司.
* All rights reserved.
*/
package security
import (
"bytes"
"crypto/aes"
"crypto/cipher"
"crypto/des"
"crypto/md5"
"crypto/rc4"
"errors"
"reflect"
)
type SymmCipher struct {
encryptCipher interface{} //cipher.BlockMode | cipher.Stream
decryptCipher interface{} //cipher.BlockMode | cipher.Stream
key []byte
block cipher.Block // 分组加密算法
algorithmType int
workMode int
needPadding bool
}
func NewSymmCipher(algorithmID int, key []byte) (SymmCipher, error) {
var sc SymmCipher
var err error
sc.key = key
sc.algorithmType = algorithmID & ALGO_MASK
sc.workMode = algorithmID & WORK_MODE_MASK
switch sc.algorithmType {
case AES128:
if sc.block, err = aes.NewCipher(key[:16]); err != nil {
return sc, err
}
case AES192:
if sc.block, err = aes.NewCipher(key[:24]); err != nil {
return sc, err
}
case AES256:
if sc.block, err = aes.NewCipher(key[:32]); err != nil {
return sc, err
}
case DES:
if sc.block, err = des.NewCipher(key[:8]); err != nil {
return sc, err
}
case DES3:
var tripleDESKey []byte
tripleDESKey = append(tripleDESKey, key[:16]...)
tripleDESKey = append(tripleDESKey, key[:8]...)
if sc.block, err = des.NewTripleDESCipher(tripleDESKey); err != nil {
return sc, err
}
case RC4:
if sc.encryptCipher, err = rc4.NewCipher(key[:16]); err != nil {
return sc, err
}
if sc.decryptCipher, err = rc4.NewCipher(key[:16]); err != nil {
return sc, err
}
return sc, nil
default:
return sc, errors.New("invalidCipher")
}
blockSize := sc.block.BlockSize()
if sc.encryptCipher, err = sc.getEncrypter(sc.workMode, sc.block, defaultIV[:blockSize]); err != nil {
return sc, err
}
if sc.decryptCipher, err = sc.getDecrypter(sc.workMode, sc.block, defaultIV[:blockSize]); err != nil {
return sc, err
}
return sc, nil
}
func (sc SymmCipher) Encrypt(plaintext []byte, genDigest bool) []byte {
// 执行过加密后,IV值变了,需要重新初始化encryptCipher对象(因为没有类似resetIV的方法)
if sc.algorithmType != RC4 {
sc.encryptCipher, _ = sc.getEncrypter(sc.workMode, sc.block, defaultIV[:sc.block.BlockSize()])
} else {
sc.encryptCipher, _ = rc4.NewCipher(sc.key[:16])
}
// 填充
var paddingtext = make([]byte, len(plaintext))
copy(paddingtext, plaintext)
if sc.needPadding {
paddingtext = pkcs5Padding(paddingtext)
}
ret := make([]byte, len(paddingtext))
if v, ok := sc.encryptCipher.(cipher.Stream); ok {
v.XORKeyStream(ret, paddingtext)
} else if v, ok := sc.encryptCipher.(cipher.BlockMode); ok {
v.CryptBlocks(ret, paddingtext)
}
// md5摘要
if genDigest {
digest := md5.Sum(plaintext)
encrypt := ret
ret = make([]byte, len(encrypt)+len(digest))
copy(ret[:len(encrypt)], encrypt)
copy(ret[len(encrypt):], digest[:])
}
return ret
}
func (sc SymmCipher) Decrypt(ciphertext []byte, checkDigest bool) ([]byte, error) {
// 执行过解密后,IV值变了,需要重新初始化decryptCipher对象(因为没有类似resetIV的方法)
if sc.algorithmType != RC4 {
sc.decryptCipher, _ = sc.getDecrypter(sc.workMode, sc.block, defaultIV[:sc.block.BlockSize()])
} else {
sc.decryptCipher, _ = rc4.NewCipher(sc.key[:16])
}
var ret []byte
if checkDigest {
var digest = ciphertext[len(ciphertext)-MD5_DIGEST_SIZE:]
ret = ciphertext[:len(ciphertext)-MD5_DIGEST_SIZE]
ret = sc.decrypt(ret)
var msgDigest = md5.Sum(ret)
if !reflect.DeepEqual(msgDigest[:], digest) {
return nil, errors.New("Decrypt failed/Digest not match\n")
}
} else {
ret = sc.decrypt(ciphertext)
}
return ret, nil
}
func (sc SymmCipher) decrypt(ciphertext []byte) []byte {
ret := make([]byte, len(ciphertext))
if v, ok := sc.decryptCipher.(cipher.Stream); ok {
v.XORKeyStream(ret, ciphertext)
} else if v, ok := sc.decryptCipher.(cipher.BlockMode); ok {
v.CryptBlocks(ret, ciphertext)
}
// 去除填充
if sc.needPadding {
ret = pkcs5UnPadding(ret)
}
return ret
}
func (sc *SymmCipher) getEncrypter(workMode int, block cipher.Block, iv []byte) (ret interface{}, err error) {
switch workMode {
case ECB_MODE:
ret = NewECBEncrypter(block)
sc.needPadding = true
case CBC_MODE:
ret = cipher.NewCBCEncrypter(block, iv)
sc.needPadding = true
case CFB_MODE:
ret = cipher.NewCFBEncrypter(block, iv)
sc.needPadding = false
case OFB_MODE:
ret = cipher.NewOFB(block, iv)
sc.needPadding = false
default:
err = errors.New("invalidCipherMode")
}
return
}
func (sc *SymmCipher) getDecrypter(workMode int, block cipher.Block, iv []byte) (ret interface{}, err error) {
switch workMode {
case ECB_MODE:
ret = NewECBDecrypter(block)
sc.needPadding = true
case CBC_MODE:
ret = cipher.NewCBCDecrypter(block, iv)
sc.needPadding = true
case CFB_MODE:
ret = cipher.NewCFBDecrypter(block, iv)
sc.needPadding = false
case OFB_MODE:
ret = cipher.NewOFB(block, iv)
sc.needPadding = false
default:
err = errors.New("invalidCipherMode")
}
return
}
// 补码
func pkcs77Padding(ciphertext []byte, blocksize int) []byte {
padding := blocksize - len(ciphertext)%blocksize
padtext := bytes.Repeat([]byte{byte(padding)}, padding)
return append(ciphertext, padtext...)
}
// 去码
func pkcs7UnPadding(origData []byte) []byte {
length := len(origData)
unpadding := int(origData[length-1])
return origData[:length-unpadding]
}
// 补码
func pkcs5Padding(ciphertext []byte) []byte {
return pkcs77Padding(ciphertext, 8)
}
// 去码
func pkcs5UnPadding(ciphertext []byte) []byte {
return pkcs7UnPadding(ciphertext)
}
+142
View File
@@ -0,0 +1,142 @@
/*
* Copyright (c) 2000-2018, 达梦数据库有限公司.
* All rights reserved.
*/
package security
import (
"crypto/md5"
"errors"
"fmt"
"reflect"
"unsafe"
)
type ThirdPartCipher struct {
encryptType int // 外部加密算法id
encryptName string // 外部加密算法名称
hashType int
key []byte
cipherCount int // 外部加密算法个数
//innerId int // 外部加密算法内部id
blockSize int // 分组块大小
khSize int // key/hash大小
}
func NewThirdPartCipher(encryptType int, key []byte, cipherPath string, hashType int) (ThirdPartCipher, error) {
var tpc = ThirdPartCipher{
encryptType: encryptType,
key: key,
hashType: hashType,
cipherCount: -1,
}
var err error
err = initThirdPartCipher(cipherPath)
if err != nil {
return tpc, err
}
tpc.getCount()
if err = tpc.getInfo(); err != nil {
return tpc, err
}
return tpc, nil
}
func (tpc *ThirdPartCipher) getCount() int {
if tpc.cipherCount == -1 {
tpc.cipherCount = cipherGetCount()
}
return tpc.cipherCount
}
func (tpc *ThirdPartCipher) getInfo() error {
var cipher_id, ty, blk_size, kh_size int
//var strptr, _ = syscall.UTF16PtrFromString(tpc.encryptName)
var strptr *uint16 = new(uint16)
for i := 1; i <= tpc.getCount(); i++ {
cipherGetInfo(uintptr(i), uintptr(unsafe.Pointer(&cipher_id)), uintptr(unsafe.Pointer(&strptr)),
uintptr(unsafe.Pointer(&ty)), uintptr(unsafe.Pointer(&blk_size)), uintptr(unsafe.Pointer(&kh_size)))
if tpc.encryptType == cipher_id {
tpc.blockSize = blk_size
tpc.khSize = kh_size
tpc.encryptName = string(uintptr2bytes(uintptr(unsafe.Pointer(strptr))))
return nil
}
}
return fmt.Errorf("ThirdPartyCipher: cipher id:%d not found", tpc.encryptType)
}
func (tpc ThirdPartCipher) Encrypt(plaintext []byte, genDigest bool) []byte {
var tmp_para uintptr
cipherEncryptInit(uintptr(tpc.encryptType), uintptr(unsafe.Pointer(&tpc.key[0])), uintptr(len(tpc.key)), tmp_para)
ciphertextLen := cipherGetCipherTextSize(uintptr(tpc.encryptType), tmp_para, uintptr(len(plaintext)))
ciphertext := make([]byte, ciphertextLen)
ret := cipherEncrypt(uintptr(tpc.encryptType), tmp_para, uintptr(unsafe.Pointer(&plaintext[0])), uintptr(len(plaintext)),
uintptr(unsafe.Pointer(&ciphertext[0])), uintptr(len(ciphertext)))
ciphertext = ciphertext[:ret]
cipherClean(uintptr(tpc.encryptType), tmp_para)
// md5摘要
if genDigest {
digest := md5.Sum(plaintext)
encrypt := ciphertext
ciphertext = make([]byte, len(encrypt)+len(digest))
copy(ciphertext[:len(encrypt)], encrypt)
copy(ciphertext[len(encrypt):], digest[:])
}
return ciphertext
}
func (tpc ThirdPartCipher) Decrypt(ciphertext []byte, checkDigest bool) ([]byte, error) {
var ret []byte
if checkDigest {
var digest = ciphertext[len(ciphertext)-MD5_DIGEST_SIZE:]
ret = ciphertext[:len(ciphertext)-MD5_DIGEST_SIZE]
ret = tpc.decrypt(ret)
var msgDigest = md5.Sum(ret)
if !reflect.DeepEqual(msgDigest[:], digest) {
return nil, errors.New("Decrypt failed/Digest not match\n")
}
} else {
ret = tpc.decrypt(ciphertext)
}
return ret, nil
}
func (tpc ThirdPartCipher) decrypt(ciphertext []byte) []byte {
var tmp_para uintptr
cipherDecryptInit(uintptr(tpc.encryptType), uintptr(unsafe.Pointer(&tpc.key[0])), uintptr(len(tpc.key)), tmp_para)
plaintext := make([]byte, len(ciphertext))
ret := cipherDecrypt(uintptr(tpc.encryptType), tmp_para, uintptr(unsafe.Pointer(&ciphertext[0])), uintptr(len(ciphertext)),
uintptr(unsafe.Pointer(&plaintext[0])), uintptr(len(plaintext)))
plaintext = plaintext[:ret]
cipherClean(uintptr(tpc.encryptType), tmp_para)
return plaintext
}
func addBufSize(buf []byte, newCap int) []byte {
newBuf := make([]byte, newCap)
copy(newBuf, buf)
return newBuf
}
func uintptr2bytes(p uintptr) []byte {
buf := make([]byte, 64)
i := 0
for b := (*byte)(unsafe.Pointer(p)); *b != 0; i++ {
if i > cap(buf) {
buf = addBufSize(buf, i*2)
}
buf[i] = *b
// byte占1字节
p++
b = (*byte)(unsafe.Pointer(p))
}
return buf[:i]
}
+96
View File
@@ -0,0 +1,96 @@
/*
* Copyright (c) 2000-2018, 达梦数据库有限公司.
* All rights reserved.
*/
package security
import "plugin"
var (
dmCipherEncryptSo *plugin.Plugin
cipherGetCountProc plugin.Symbol
cipherGetInfoProc plugin.Symbol
cipherEncryptInitProc plugin.Symbol
cipherGetCipherTextSizeProc plugin.Symbol
cipherEncryptProc plugin.Symbol
cipherCleanupProc plugin.Symbol
cipherDecryptInitProc plugin.Symbol
cipherDecryptProc plugin.Symbol
)
func initThirdPartCipher(cipherPath string) (err error) {
if dmCipherEncryptSo, err = plugin.Open(cipherPath); err != nil {
return err
}
if cipherGetCountProc, err = dmCipherEncryptSo.Lookup("cipher_get_count"); err != nil {
return err
}
if cipherGetInfoProc, err = dmCipherEncryptSo.Lookup("cipher_get_info"); err != nil {
return err
}
if cipherEncryptInitProc, err = dmCipherEncryptSo.Lookup("cipher_encrypt_init"); err != nil {
return err
}
if cipherGetCipherTextSizeProc, err = dmCipherEncryptSo.Lookup("cipher_get_cipher_text_size"); err != nil {
return err
}
if cipherEncryptProc, err = dmCipherEncryptSo.Lookup("cipher_encrypt"); err != nil {
return err
}
if cipherCleanupProc, err = dmCipherEncryptSo.Lookup("cipher_cleanup"); err != nil {
return err
}
if cipherDecryptInitProc, err = dmCipherEncryptSo.Lookup("cipher_decrypt_init"); err != nil {
return err
}
if cipherDecryptProc, err = dmCipherEncryptSo.Lookup("cipher_decrypt"); err != nil {
return err
}
return nil
}
func cipherGetCount() int {
ret := cipherGetCountProc.(func() interface{})()
return ret.(int)
}
func cipherGetInfo(seqno, cipherId, cipherName, _type, blkSize, khSIze uintptr) {
ret := cipherGetInfoProc.(func(uintptr, uintptr, uintptr, uintptr, uintptr, uintptr) interface{})(seqno, cipherId, cipherName, _type, blkSize, khSIze)
if ret.(int) == 0 {
panic("ThirdPartyCipher: call cipher_get_info failed")
}
}
func cipherEncryptInit(cipherId, key, keySize, cipherPara uintptr) {
ret := cipherEncryptInitProc.(func(uintptr, uintptr, uintptr, uintptr) interface{})(cipherId, key, keySize, cipherPara)
if ret.(int) == 0 {
panic("ThirdPartyCipher: call cipher_encrypt_init failed")
}
}
func cipherGetCipherTextSize(cipherId, cipherPara, plainTextSize uintptr) uintptr {
ciphertextLen := cipherGetCipherTextSizeProc.(func(uintptr, uintptr, uintptr) interface{})(cipherId, cipherPara, plainTextSize)
return ciphertextLen.(uintptr)
}
func cipherEncrypt(cipherId, cipherPara, plainText, plainTextSize, cipherText, cipherTextBufSize uintptr) uintptr {
ret := cipherEncryptProc.(func(uintptr, uintptr, uintptr, uintptr, uintptr, uintptr) interface{})(cipherId, cipherPara, plainText, plainTextSize, cipherText, cipherTextBufSize)
return ret.(uintptr)
}
func cipherClean(cipherId, cipherPara uintptr) {
cipherEncryptProc.(func(uintptr, uintptr))(cipherId, cipherPara)
}
func cipherDecryptInit(cipherId, key, keySize, cipherPara uintptr) {
ret := cipherDecryptInitProc.(func(uintptr, uintptr, uintptr, uintptr) interface{})(cipherId, key, keySize, cipherPara)
if ret.(int) == 0 {
panic("ThirdPartyCipher: call cipher_decrypt_init failed")
}
}
func cipherDecrypt(cipherId, cipherPara, cipherText, cipherTextSize, plainText, plainTextBufSize uintptr) uintptr {
ret := cipherDecryptProc.(func(uintptr, uintptr, uintptr, uintptr, uintptr, uintptr) interface{})(cipherId, cipherPara, cipherText, cipherTextSize, plainText, plainTextBufSize)
return ret.(uintptr)
}
+96
View File
@@ -0,0 +1,96 @@
/*
* Copyright (c) 2000-2018, 达梦数据库有限公司.
* All rights reserved.
*/
package security
import "plugin"
var (
dmCipherEncryptSo *plugin.Plugin
cipherGetCountProc plugin.Symbol
cipherGetInfoProc plugin.Symbol
cipherEncryptInitProc plugin.Symbol
cipherGetCipherTextSizeProc plugin.Symbol
cipherEncryptProc plugin.Symbol
cipherCleanupProc plugin.Symbol
cipherDecryptInitProc plugin.Symbol
cipherDecryptProc plugin.Symbol
)
func initThirdPartCipher(cipherPath string) (err error) {
if dmCipherEncryptSo, err = plugin.Open(cipherPath); err != nil {
return err
}
if cipherGetCountProc, err = dmCipherEncryptSo.Lookup("cipher_get_count"); err != nil {
return err
}
if cipherGetInfoProc, err = dmCipherEncryptSo.Lookup("cipher_get_info"); err != nil {
return err
}
if cipherEncryptInitProc, err = dmCipherEncryptSo.Lookup("cipher_encrypt_init"); err != nil {
return err
}
if cipherGetCipherTextSizeProc, err = dmCipherEncryptSo.Lookup("cipher_get_cipher_text_size"); err != nil {
return err
}
if cipherEncryptProc, err = dmCipherEncryptSo.Lookup("cipher_encrypt"); err != nil {
return err
}
if cipherCleanupProc, err = dmCipherEncryptSo.Lookup("cipher_cleanup"); err != nil {
return err
}
if cipherDecryptInitProc, err = dmCipherEncryptSo.Lookup("cipher_decrypt_init"); err != nil {
return err
}
if cipherDecryptProc, err = dmCipherEncryptSo.Lookup("cipher_decrypt"); err != nil {
return err
}
return nil
}
func cipherGetCount() int {
ret := cipherGetCountProc.(func() interface{})()
return ret.(int)
}
func cipherGetInfo(seqno, cipherId, cipherName, _type, blkSize, khSIze uintptr) {
ret := cipherGetInfoProc.(func(uintptr, uintptr, uintptr, uintptr, uintptr, uintptr) interface{})(seqno, cipherId, cipherName, _type, blkSize, khSIze)
if ret.(int) == 0 {
panic("ThirdPartyCipher: call cipher_get_info failed")
}
}
func cipherEncryptInit(cipherId, key, keySize, cipherPara uintptr) {
ret := cipherEncryptInitProc.(func(uintptr, uintptr, uintptr, uintptr) interface{})(cipherId, key, keySize, cipherPara)
if ret.(int) == 0 {
panic("ThirdPartyCipher: call cipher_encrypt_init failed")
}
}
func cipherGetCipherTextSize(cipherId, cipherPara, plainTextSize uintptr) uintptr {
ciphertextLen := cipherGetCipherTextSizeProc.(func(uintptr, uintptr, uintptr) interface{})(cipherId, cipherPara, plainTextSize)
return ciphertextLen.(uintptr)
}
func cipherEncrypt(cipherId, cipherPara, plainText, plainTextSize, cipherText, cipherTextBufSize uintptr) uintptr {
ret := cipherEncryptProc.(func(uintptr, uintptr, uintptr, uintptr, uintptr, uintptr) interface{})(cipherId, cipherPara, plainText, plainTextSize, cipherText, cipherTextBufSize)
return ret.(uintptr)
}
func cipherClean(cipherId, cipherPara uintptr) {
cipherEncryptProc.(func(uintptr, uintptr))(cipherId, cipherPara)
}
func cipherDecryptInit(cipherId, key, keySize, cipherPara uintptr) {
ret := cipherDecryptInitProc.(func(uintptr, uintptr, uintptr, uintptr) interface{})(cipherId, key, keySize, cipherPara)
if ret.(int) == 0 {
panic("ThirdPartyCipher: call cipher_decrypt_init failed")
}
}
func cipherDecrypt(cipherId, cipherPara, cipherText, cipherTextSize, plainText, plainTextBufSize uintptr) uintptr {
ret := cipherDecryptProc.(func(uintptr, uintptr, uintptr, uintptr, uintptr, uintptr) interface{})(cipherId, cipherPara, cipherText, cipherTextSize, plainText, plainTextBufSize)
return ret.(uintptr)
}
+83
View File
@@ -0,0 +1,83 @@
/*
* Copyright (c) 2000-2018, 达梦数据库有限公司.
* All rights reserved.
*/
package security
import (
"syscall"
)
var (
dmCipherEncryptDLL *syscall.LazyDLL
cipherGetCountProc *syscall.LazyProc
cipherGetInfoProc *syscall.LazyProc
cipherEncryptInitProc *syscall.LazyProc
cipherGetCipherTextSizeProc *syscall.LazyProc
cipherEncryptProc *syscall.LazyProc
cipherCleanupProc *syscall.LazyProc
cipherDecryptInitProc *syscall.LazyProc
cipherDecryptProc *syscall.LazyProc
)
func initThirdPartCipher(cipherPath string) error {
dmCipherEncryptDLL = syscall.NewLazyDLL(cipherPath)
if err := dmCipherEncryptDLL.Load(); err != nil {
return err
}
cipherGetCountProc = dmCipherEncryptDLL.NewProc("cipher_get_count")
cipherGetInfoProc = dmCipherEncryptDLL.NewProc("cipher_get_info")
cipherEncryptInitProc = dmCipherEncryptDLL.NewProc("cipher_encrypt_init")
cipherGetCipherTextSizeProc = dmCipherEncryptDLL.NewProc("cipher_get_cipher_text_size")
cipherEncryptProc = dmCipherEncryptDLL.NewProc("cipher_encrypt")
cipherCleanupProc = dmCipherEncryptDLL.NewProc("cipher_cleanup")
cipherDecryptInitProc = dmCipherEncryptDLL.NewProc("cipher_decrypt_init")
cipherDecryptProc = dmCipherEncryptDLL.NewProc("cipher_decrypt")
return nil
}
func cipherGetCount() int {
ret, _, _ := cipherGetCountProc.Call()
return int(ret)
}
func cipherGetInfo(seqno, cipherId, cipherName, _type, blkSize, khSIze uintptr) {
ret, _, _ := cipherGetInfoProc.Call(seqno, cipherId, cipherName, _type, blkSize, khSIze)
if ret == 0 {
panic("ThirdPartyCipher: call cipher_get_info failed")
}
}
func cipherEncryptInit(cipherId, key, keySize, cipherPara uintptr) {
ret, _, _ := cipherEncryptInitProc.Call(cipherId, key, keySize, cipherPara)
if ret == 0 {
panic("ThirdPartyCipher: call cipher_encrypt_init failed")
}
}
func cipherGetCipherTextSize(cipherId, cipherPara, plainTextSize uintptr) uintptr {
ciphertextLen, _, _ := cipherGetCipherTextSizeProc.Call(cipherId, cipherPara, plainTextSize)
return ciphertextLen
}
func cipherEncrypt(cipherId, cipherPara, plainText, plainTextSize, cipherText, cipherTextBufSize uintptr) uintptr {
ret, _, _ := cipherEncryptProc.Call(cipherId, cipherPara, plainText, plainTextSize, cipherText, cipherTextBufSize)
return ret
}
func cipherClean(cipherId, cipherPara uintptr) {
_, _, _ = cipherCleanupProc.Call(cipherId, cipherPara)
}
func cipherDecryptInit(cipherId, key, keySize, cipherPara uintptr) {
ret, _, _ := cipherDecryptInitProc.Call(cipherId, key, keySize, cipherPara)
if ret == 0 {
panic("ThirdPartyCipher: call cipher_decrypt_init failed")
}
}
func cipherDecrypt(cipherId, cipherPara, cipherText, cipherTextSize, plainText, plainTextBufSize uintptr) uintptr {
ret, _, _ := cipherDecryptProc.Call(cipherId, cipherPara, cipherText, cipherTextSize, plainText, plainTextBufSize)
return ret
}
+37
View File
@@ -0,0 +1,37 @@
/*
* Copyright (c) 2000-2018, 达梦数据库有限公司.
* All rights reserved.
*/
package security
import (
"crypto/tls"
"errors"
"net"
"sync"
)
//var dmHome = flag.String("DM_HOME", "", "Where DMDB installed")
var flagLock = sync.Mutex{}
func NewTLSFromTCP(conn net.Conn, sslCertPath string, sslKeyPath string, user string) (*tls.Conn, error) {
if sslCertPath == "" && sslKeyPath == "" {
// 用户必须手动指定ssl文件和签名(.cert文件)
return nil, errors.New("sslCertPath and sslKeyPath can not be empty!")
}
cer, err := tls.LoadX509KeyPair(sslCertPath, sslKeyPath)
if err != nil {
return nil, err
}
conf := &tls.Config{
InsecureSkipVerify: true,
Certificates: []tls.Certificate{cer},
}
tlsConn := tls.Client(conn, conf)
if err := tlsConn.Handshake(); err != nil {
return nil, err
}
return tlsConn, nil
}