GO:windows & linux下调用ukey的skf库示例(七侠镇莫尛貝大侠_20240911)

环境:windows 11, ubuntu24.04

开发环境:goland 2024.2

go版本:go1.23.0 amd64

Ukey型号: longmai gm3000 

skf库版本:mtoken_gm3000_tw.dll (x64)

实现功能:列出设备,导出证书,sm3hash,pkcs1签名,修改pin、认证pin、解锁ukey,监控插入拔出ukey动作,关闭程序时的扫尾工作。

package main

import (
	"bytes"
	"encoding/asn1"
	"encoding/base64"
	"encoding/hex"
	"fmt"
	_ "io/ioutil"
	"math/big"
	"os"
	"os/signal"
	"strconv"
	"sync"
	"syscall"
	"time"
	"unsafe"
)

func skf_test() {
	//1. 加载dll
	dll_name := "lib/mtoken_gm3000_tw.dll" //可以省略.dll
	//dll_name := "lib/mtoken_gm3000_x64_debug.dll" //可以省略.dll
	handle := get_dll_handle(dll_name)

	//2. SKF_EnumDev
	dev_list := get_devs(handle)
	dev_name := string(bytes.Split(dev_list, []byte{0})[0])

	//3. SKF_ConnectDev
	dev_name = "TW08220608000002"
	hdev := conn_dev(handle, dev_name)

	//4. SKF_EnumApplication
	app_list := get_apps(handle, hdev)
	//app_name := string(bytes.TrimRight(app_list,string([]byte{0})))
	app_name := string(bytes.Split(app_list, []byte{0})[0])

	//5. SKF_EnumApplication
	app_name = "GM3000RSA-TW"
	happ := open_app(handle, hdev, app_name)

	//7. SKF_EnumContainer
	bytes_cont_name := get_containers(handle, happ)
	fmt.Printf("bytes_cont_name = %s \n", bytes_cont_name)

	//8. SKF_OpenContainer
	//cont_name := string(bytes.Split(bytes_cont_name, []byte{0})[0])
	cont_name := "c08aee27-20c0-4dd3-b108-ed39828f28fa"
	phcont := open_container(handle, happ, cont_name)
	fmt.Printf("phcont = %v \n", phcont)

	//9. SKF_GetContainerType
	cont_type := get_container_type(handle, phcont)
	fmt.Printf("cont_type = %d (RSA=1,ECC=2)\n", cont_type)

	//10. SKF_ExportPublicKey
	pubkey := get_pubkey(handle, phcont)
	fmt.Printf("pubkey = %v \n", pubkey)

	//11. SKF_ExportCertificate
	cert_len, cert_bytes := get_cert(handle, phcont, 1)
	fmt.Printf("cert_len = %v cert_bytes = %v \n", cert_len, cert_bytes)

	//13. SKF_DigestInit  14. SKF_Digest
	//注意:这里传入的是hdev,不是phcont
	//rsa_or_ecc 为1表示为RSA容器,为2表示为ECC容器
	bytes_hash_32 := sm3_with_uid(handle, hdev, 2, pubkey, "123")

	//6. SKF_VerifyPIN
	var adminPin = "admin"
	var userPin = "12345678"
	var userPinNew = "12345678"
	change_pin(handle, happ, userPin, userPinNew)
	unlock_pin(handle, happ, adminPin, userPinNew)
	verify_pin(handle, happ, userPinNew)

	//15. SKF_ECCSignData
	//注意:这里传入的hcont
	bytes_sign_p1 := sign_hash(handle, phcont, bytes_hash_32)
	//fmt.Printf("bytes_sign_p1 = %v \n", bytes_sign_p1)

	bytes_hash_32_2 := sm3_with_uid(handle, hdev, 2, pubkey, "123")
	//16. SKF_ECCVerify
	//注意:这里传入hdev.
	verify_hash(handle, hdev, pubkey, bytes_hash_32_2, bytes_sign_p1)

	//17. SKF_ClearSecureState
	clear_pin(handle, happ)
	monitor_quit(handle, phcont, happ, hdev, dev_name)

}

// 1. 加载SKF库
func get_dll_handle(path_dll string) syscall.Handle {
	//"lib/mtoken_gm3000_tw"
	//1. 加载SKF库
	handle, err := syscall.LoadLibrary(path_dll)
	if err != nil {
		fmt.Printf("Error: %s\n", err)
		return 0
	}
	//TODO: 这里不能defer syscall.FreeLibrary(handle),否则后面会报错。
	//程序结束时,需要手动syscall.FreeLibrary(handle)
	/*
		defer func(handle syscall.Handle) {
			_ = syscall.FreeLibrary(handle)
		}(handle)
	*/

	fmt.Printf("1. 加载SKF库 handle = %v \n", handle)
	return handle
}

// 2. SKF_EnumDev
func get_devs(handle syscall.Handle) []byte {
	proc, err := syscall.GetProcAddress(handle, "SKF_EnumDev")
	if err != nil {
		fmt.Println(err.Error())
		return nil
	}

	var len_devname int64
	//lbr_input := &l
	//ret, _, _ := syscall.Syscall(uintptr(proc), 3, uintptr(unsafe.Pointer(&b)), 0, uintptr(unsafe.Pointer(lbr_input)))
	ret, _, _ := syscall.SyscallN(uintptr(proc),
		uintptr(1), //TODO: 已经插在机器上的设备
		uintptr(0), //TODO:  null
		uintptr(unsafe.Pointer(&len_devname)),
	)

	//lv := *(*int64)(unsafe.Pointer(lbr_input))
	//fmt.Printf("SKF_EnumDev ret: %d, len_devname: %d\n", ret, len_devname)

	var dev_list = make([]byte, len_devname)
	dev_list = append(dev_list, 0)

	//lbr_output := &dev
	//ret2, _, _ := syscall.Syscall(uintptr(proc), 3, uintptr(unsafe.Pointer(&b)), uintptr(unsafe.Pointer(&lbr_output)), uintptr(unsafe.Pointer(lbr_input)))
	ret2, _, _ := syscall.SyscallN(uintptr(proc),
		uintptr(1), //TODO: 已经插在机器上的设备
		uintptr(unsafe.Pointer(&dev_list[0])),
		uintptr(unsafe.Pointer(&len_devname)),
	)
	//dev_name := string(bytes.TrimRight(dev_list,string([]byte{0})))

	ret2_hex := strconv.FormatInt(int64(ret2), 16)
	fmt.Printf("2. SKF_EnumDev ret: %d = %s, dev_list: [%s] len = %d   \n", ret, ret2_hex, dev_list, len(dev_list))
	return dev_list
}

// 3. SKF_ConnectDev
func conn_dev(handle syscall.Handle, dev_name string) int64 {
	proc2, err2 := syscall.GetProcAddress(handle, "SKF_ConnectDev")
	if err2 != nil {
		fmt.Println(err2.Error())
		return 0
	}

	var bytes_dev_name = []byte(dev_name)
	bytes_dev_name = append(bytes_dev_name, 0)

	var hdev int64
	p_hdev := &hdev
	ret3, _, _ := syscall.SyscallN(uintptr(proc2),
		uintptr(unsafe.Pointer(&bytes_dev_name[0])),
		uintptr(unsafe.Pointer(&p_hdev)),
	)
	ret3_hex := strconv.FormatInt(int64(ret3), 16)
	ptr_hdev := unsafe.Pointer(&p_hdev)
	hdev = *(*int64)(unsafe.Pointer(ptr_hdev)) //TODO:  hdev = uintptr(dd)

	fmt.Printf("3. SKF_ConnectDev ret: %d = %v, hdev= [%v] \n", ret3, ret3_hex, hdev)
	return hdev
}

// 4. SKF_EnumApplication
func get_apps(handle syscall.Handle, hdev int64) []byte {
	//4. SKF_EnumApplication
	proc4, err4 := syscall.GetProcAddress(handle, "SKF_EnumApplication")
	if err4 != nil {
		fmt.Println(err4.Error())
		return nil
	}

	var size_app_name int64
	//ret41, _, _ := syscall.SyscallN(uintptr(proc4),
	syscall.SyscallN(uintptr(proc4),
		uintptr(hdev),
		uintptr(0),
		uintptr(unsafe.Pointer(&size_app_name)),
	)
	//ret41_hex := strconv.FormatInt(int64(ret41), 16)
	//fmt.Printf("SKF_EnumApplication ret: %d = %s, size_app_name = %d  \n", ret41,ret41_hex, size_app_name)

	var app_list = make([]byte, size_app_name)
	app_list = append(app_list, 0)

	ret4, _, _ := syscall.SyscallN(uintptr(proc4),
		uintptr(hdev),
		uintptr(unsafe.Pointer(&app_list[0])),
		uintptr(unsafe.Pointer(&size_app_name)),
	)
	//app_name := string(bytes.TrimRight(app_list,string([]byte{0})))

	ret4_hex := strconv.FormatInt(int64(ret4), 16)
	fmt.Printf("4. SKF_EnumApplication ret: %d = %s, appname: [%s] len = %d   \n", ret4, ret4_hex, app_list, len(app_list))
	return app_list
}

func open_app(handle syscall.Handle, hdev int64, app_name string) int64 {
	//5. SKF_EnumApplication
	proc5, err5 := syscall.GetProcAddress(handle, "SKF_OpenApplication")
	if err5 != nil {
		fmt.Println(err5.Error())
		return 0
	}

	//app_name = "GM3000RSA-TW"	//a00002e=应用不存在
	bytes_app_name := []byte(app_name)
	bytes_app_name = append(bytes_app_name, 0)

	var happ int64
	p_happ := &happ
	ret5, _, _ := syscall.SyscallN(uintptr(proc5), uintptr(hdev), uintptr(unsafe.Pointer(&bytes_app_name[0])), uintptr(unsafe.Pointer(&p_happ)))

	ptr_happ := unsafe.Pointer(&p_happ)              //TODO:  句柄处理
	addr_happ := *(*int64)(unsafe.Pointer(ptr_happ)) //TODO:  hdev = uintptr(dd)

	ret5_hex := strconv.FormatInt(int64(ret5), 16)
	fmt.Printf("5. SKF_OpenApplication ret: [%d = %s], appname: [%s] len = %d  %v \n", ret5, ret5_hex, app_name, len(app_name), &addr_happ)
	return addr_happ
}

// 6. SKF_ChangePIN
func change_pin(handle syscall.Handle, addr_happ int64, user_pin string, user_pin_new string) {
	proc6, err6 := syscall.GetProcAddress(handle, "SKF_ChangePIN")
	if err6 != nil {
		fmt.Println(err6.Error())
		return
	}

	var pin_type = 1 //TODO:  USER_PIN=1, ADMIN_PIN=0

	//var user_pin = "12345678"
	var bytes_user_pin = []byte(user_pin)
	bytes_user_pin = append(bytes_user_pin, 0)
	var bytes_user_pin_new = []byte(user_pin_new)
	bytes_user_pin_new = append(bytes_user_pin_new, 0)

	var retry_count int64
	//var p_retry_count = &retry_count

	ret6, _, _ := syscall.SyscallN(uintptr(proc6),
		uintptr(addr_happ),
		uintptr(pin_type), //TODO:   long型参数入参
		uintptr(unsafe.Pointer(&bytes_user_pin[0])),
		uintptr(unsafe.Pointer(&bytes_user_pin_new[0])),
		uintptr(unsafe.Pointer(&retry_count)),
	)

	//v_retry_count := *(*int64)(unsafe.Pointer(p_retry_count))	//TODO:  出参long取值有问题
	ret6_hex := strconv.FormatInt(int64(ret6), 16)
	fmt.Printf("6. SKF_ChangePIN ret: [%d = %s], user_pin: [%v] len = %d retry_count = %d \n", ret6, ret6_hex, user_pin, len(user_pin), retry_count)

}

// SKF_UnblockPIN
func unlock_pin(handle syscall.Handle, addr_happ int64, admin_pin string, user_pin string) {
	var fn_name = "SKF_UnblockPIN"
	proc6, err6 := syscall.GetProcAddress(handle, fn_name)
	if err6 != nil {
		fmt.Println(err6.Error())
		return
	}

	var bytes_admin_pin = []byte(admin_pin)
	bytes_admin_pin = append(bytes_admin_pin, 0)
	var bytes_user_pin = []byte(user_pin)
	bytes_user_pin = append(bytes_user_pin, 0)

	var retry_count int64

	ret, _, _ := syscall.SyscallN(uintptr(proc6),
		uintptr(addr_happ),
		uintptr(unsafe.Pointer(&bytes_admin_pin[0])),
		uintptr(unsafe.Pointer(&bytes_user_pin[0])),
		uintptr(unsafe.Pointer(&retry_count)),
	)

	ret_hex := strconv.FormatInt(int64(ret), 16)
	if ret == 0 {
		fmt.Printf("6. %s ret: [%d = %s], user_pin: [%v] len = %d retry_count = %d \n", fn_name, ret, ret_hex, user_pin, len(user_pin), retry_count)
	} else {
		fmt.Printf("\033[31m6. %s ret: [%d = %s], user_pin: [%v] len = %d retry_count = %d \033[0m \n", fn_name, ret, ret_hex, user_pin, len(user_pin), retry_count)
	}
}

// 6. SKF_VerifyPIN
func verify_pin(handle syscall.Handle, addr_happ int64, user_pin string) {
	proc6, err6 := syscall.GetProcAddress(handle, "SKF_VerifyPIN")
	if err6 != nil {
		fmt.Println(err6.Error())
		return
	}

	var pin_type = 1 //TODO:  USER_PIN=1, ADMIN_PIN=0

	//var user_pin = "12345678"
	var bytes_user_pin = []byte(user_pin)
	bytes_user_pin = append(bytes_user_pin, 0)

	var retry_count int64
	//var p_retry_count = &retry_count

	ret6, _, _ := syscall.SyscallN(uintptr(proc6),
		uintptr(addr_happ),
		uintptr(pin_type),
		uintptr(unsafe.Pointer(&bytes_user_pin[0])),
		uintptr(unsafe.Pointer(&retry_count)),
	)

	ret6_hex := strconv.FormatInt(int64(ret6), 16)
	fmt.Printf("6. SKF_VerifyPIN ret: [%d = %s], user_pin: [%v] len = %d retry_count = %d \n", ret6, ret6_hex, user_pin, len(user_pin), retry_count)

}

func get_containers(handle syscall.Handle, addr_happ int64) []byte {
	//7. SKF_EnumContainer
	proc7, err7 := syscall.GetProcAddress(handle, "SKF_EnumContainer")
	if err7 != nil {
		fmt.Println(err7.Error())
		return nil
	}

	var size_cont int64
	ret71, _, _ := syscall.SyscallN(uintptr(proc7),
		uintptr(addr_happ),
		uintptr(0),
		uintptr(unsafe.Pointer(&size_cont)), //TODO: int64 出参
	)
	ret71_hex := strconv.FormatInt(int64(ret71), 16)
	fmt.Printf("71. SKF_EnumContainer ret: [%d = %s], size_cont = %d \n", ret71, ret71_hex, size_cont)

	var cont_list = make([]byte, size_cont)
	cont_list = append(cont_list, 0)

	ret7, _, _ := syscall.SyscallN(uintptr(proc7),
		uintptr(addr_happ),
		uintptr(unsafe.Pointer(&cont_list[0])),
		uintptr(unsafe.Pointer(&size_cont)), //TODO: int64 出参
	)

	bytes_cont_name := bytes.TrimRight(cont_list, string([]byte{0}))

	ret7_hex := strconv.FormatInt(int64(ret7), 16)
	fmt.Printf("7. SKF_EnumContainer ret: [%d = %s], v_size_cont = %d cont_name=[%s] size_cont = %d \n", ret7, ret7_hex, len(bytes_cont_name), bytes_cont_name, size_cont)
	return bytes_cont_name
}

// 8. SKF_OpenContainer
func open_container(handle syscall.Handle, addr_happ int64, cont_name string) int64 {
	proc, err := syscall.GetProcAddress(handle, "SKF_OpenContainer")
	if err != nil {
		fmt.Println(err.Error())
		return 0
	}

	//var cont_name = "c08aee27-20c0-4dd3-b108-ed39828f28fa"
	var bytes_cont_name = []byte(cont_name)
	bytes_cont_name = append(bytes_cont_name, 0)

	var phcont int64

	ret, _, _ := syscall.SyscallN(uintptr(proc),
		uintptr(addr_happ),
		uintptr(unsafe.Pointer(&bytes_cont_name[0])),
		uintptr(unsafe.Pointer(&phcont)),
	)

	ret_hex := strconv.FormatInt(int64(ret), 16)
	fmt.Printf("8. SKF_OpenContainer ret: [%d = %s], v_size_cont = %d cont_name=[%s] %v \n", ret, ret_hex, len(cont_name), cont_name, &phcont)
	return phcont
}

// 9. SKF_GetContainerType
func get_container_type(handle syscall.Handle, addr_phcont int64) int64 {
	proc, err := syscall.GetProcAddress(handle, "SKF_GetContainerType")
	if err != nil {
		fmt.Println(err.Error())
		return 0
	}

	var cont_type int64
	//p_cont_type := &cont_type

	ret, _, _ := syscall.SyscallN(uintptr(proc),
		uintptr(addr_phcont),
		uintptr(unsafe.Pointer(&cont_type)),
	)

	ret_hex := strconv.FormatInt(int64(ret), 16)
	fmt.Printf("9. SKF_GetContainerType ret: [%d = %s], cont_type= %d (RSA=1,ECC=2) \n", ret, ret_hex, cont_type)
	return cont_type
}

// 10. SKF_ExportPublicKey
func get_pubkey(handle syscall.Handle, addr_phcont int64) []byte {
	proc, err := syscall.GetProcAddress(handle, "SKF_ExportPublicKey")
	if err != nil {
		fmt.Println(err.Error())
	}

	pubkey_len := 132
	p_pubkey_len := &pubkey_len

	var p_pubkey = make([]byte, 132)
	p_pubkey = append(p_pubkey, 0)

	ret, _, _ := syscall.SyscallN(uintptr(proc),
		uintptr(addr_phcont),
		1,
		uintptr(unsafe.Pointer(&p_pubkey[0])),
		uintptr(unsafe.Pointer(&p_pubkey_len)),
	)

	pubkey_str := hex.EncodeToString(p_pubkey)
	BitLen := hex.EncodeToString(p_pubkey[0:4])
	xh := hex.EncodeToString(p_pubkey[4:36])
	x := hex.EncodeToString(p_pubkey[36:68])
	yh := hex.EncodeToString(p_pubkey[68:100])
	y := hex.EncodeToString(p_pubkey[100:132])

	fmt.Printf("BitLen hex = %v \n", BitLen)
	value, err := strconv.ParseInt(BitLen, 16, 64)
	fmt.Printf("value = %d \n", value)

	fmt.Printf("xh = %v \n", xh)
	fmt.Printf("xh = %v \n", x)
	fmt.Printf("xh = %v \n", yh)
	fmt.Printf("xh = %v \n", y)

	ret_hex := strconv.FormatInt(int64(ret), 16)
	fmt.Printf("10. SKF_ExportPublicKey ret: [%d = %s], p_pubkey_len= %d pubkey_hex=[%s] \n", ret, ret_hex, len(p_pubkey), pubkey_str)
	return p_pubkey
}

// sign_or_enc [IN] TRUE表示签名证书,FALSE表示加密证书
func get_cert(handle syscall.Handle, addr_phcont int64, sign_or_enc int64) (int64, []byte) {
	//11. SKF_ExportCertificate
	proc, err := syscall.GetProcAddress(handle, "SKF_ExportCertificate")
	if err != nil {
		fmt.Println(err.Error())
	}

	var cert_len int64

	syscall.SyscallN(uintptr(proc),
		uintptr(addr_phcont),
		uintptr(sign_or_enc), //[IN] TRUE表示签名证书,FALSE表示加密证书
		uintptr(0),
		uintptr(unsafe.Pointer(&cert_len)),
	)
	fmt.Printf("v_cert_len = %d \n", cert_len)

	//p_cert_len := &cert_len
	var p_cert = make([]byte, cert_len)
	p_cert = append(p_cert, 0)

	ret, _, _ := syscall.SyscallN(uintptr(proc),
		uintptr(addr_phcont),
		uintptr(sign_or_enc), //[IN] TRUE表示签名证书,FALSE表示加密证书
		uintptr(unsafe.Pointer(&p_cert[0])),
		uintptr(unsafe.Pointer(&cert_len)),
	)

	//cert_hex := hex.EncodeToString(p_cert)
	cert_b64 := base64.StdEncoding.EncodeToString(p_cert)
	fmt.Printf("cert_b64 = %s \n", cert_b64)

	ret_hex := strconv.FormatInt(int64(ret), 16)
	fmt.Printf("11. SKF_ExportCertificate ret: [%d = %s], v_cert_len= %d  \n", ret, ret_hex, cert_len)
	return cert_len, p_cert
}

// rsa_or_ecc 为1表示为RSA容器,为2表示为ECC容器
func sm3_with_uid(handle syscall.Handle, hdev int64, rsa_or_ecc int64, pubkey []byte, plain string) []byte {
	//12. SKF_DigestInit SKF_Digest
	proc, err := syscall.GetProcAddress(handle, "SKF_DigestInit")
	if err != nil {
		fmt.Println(err.Error())
	}

	var userid = "1234567812345678"
	var bytes_userid = []byte(userid)
	bytes_userid = append(bytes_userid, 0)

	var userid_len int64 = int64(len(bytes_userid))
	var h_hash int64
	ph_hash := &h_hash

	ret, _, _ := syscall.SyscallN(uintptr(proc),
		uintptr(hdev),
		uintptr(rsa_or_ecc), //为1表示为RSA容器,为2表示为ECC容器
		uintptr(unsafe.Pointer(&pubkey[0])),
		uintptr(unsafe.Pointer(&bytes_userid[0])),
		uintptr(userid_len),
		uintptr(unsafe.Pointer(&ph_hash)),
	)
	ptr_ph_hash := unsafe.Pointer(&ph_hash)
	addrptr_ph_hash := *(*int64)(unsafe.Pointer(ptr_ph_hash))

	ret_hex := strconv.FormatInt(int64(ret), 16)
	fmt.Printf("13. SKF_DigestInit ret: [%d = %s], addrptr_ph_hash= %v  \n", ret, ret_hex, addrptr_ph_hash)

	//
	//var plain_test = "test123"
	var plain_test = plain
	var bytes_plain_test = []byte(plain_test)
	var len_bytes_plain_test = len(bytes_plain_test)
	var len_hash_sm3 int64 = 32 //TODO:  sm3 hash 长度是固定的32 ?
	var bytes_sm3_hash = make([]byte, 32)
	//var p_bytes_sm3_hash = &bytes_sm3_hash

	proc2, err2 := syscall.GetProcAddress(handle, "SKF_Digest")
	if err2 != nil {
		fmt.Println(err2.Error())
	}
	ret2, _, _ := syscall.SyscallN(uintptr(proc2),
		uintptr(addrptr_ph_hash),
		uintptr(unsafe.Pointer(&bytes_plain_test[0])),
		uintptr(len_bytes_plain_test),
		uintptr(unsafe.Pointer(&bytes_sm3_hash[0])),
		uintptr(unsafe.Pointer(&len_hash_sm3)),
	)
	hash_sm3_b64 := base64.StdEncoding.EncodeToString(bytes_sm3_hash)
	fmt.Printf("hash_sm3_b64 = %s \n", hash_sm3_b64)
	ret2_hex := strconv.FormatInt(int64(ret2), 16)
	fmt.Printf("14. SKF_Digest ret: [%d = %s], len_hash_sm3= %v  sm3 = %v \n", ret2, ret2_hex, len_hash_sm3, bytes_sm3_hash)

	close_handle(handle, addrptr_ph_hash)
	return bytes_sm3_hash
}

func sm3_no_uid(handle syscall.Handle, hdev int64, rsa_or_ecc int64, pubkey []byte, plain string) []byte {
	//12. SKF_DigestInit SKF_Digest
	proc, err := syscall.GetProcAddress(handle, "SKF_DigestInit")
	if err != nil {
		fmt.Println(err.Error())
	}

	var userid = "1234567812345678"
	var bytes_userid = []byte(userid)
	bytes_userid = append(bytes_userid, 0)

	var userid_len int64 = int64(len(bytes_userid))
	var h_hash int64
	ph_hash := &h_hash

	ret, _, _ := syscall.SyscallN(uintptr(proc),
		uintptr(hdev),
		uintptr(rsa_or_ecc), //为1表示为RSA容器,为2表示为ECC容器
		uintptr(unsafe.Pointer(&pubkey[0])),
		uintptr(unsafe.Pointer(&bytes_userid[0])),
		uintptr(userid_len),
		uintptr(unsafe.Pointer(&ph_hash)),
	)
	ptr_ph_hash := unsafe.Pointer(&ph_hash)
	addrptr_ph_hash := *(*int64)(unsafe.Pointer(ptr_ph_hash))

	ret_hex := strconv.FormatInt(int64(ret), 16)
	fmt.Printf("13. SKF_DigestInit ret: [%d = %s], addrptr_ph_hash= %v  \n", ret, ret_hex, addrptr_ph_hash)

	//
	//var plain_test = "test123"
	var plain_test = plain
	var bytes_plain_test = []byte(plain_test)
	var len_bytes_plain_test = len(bytes_plain_test)
	var len_hash_sm3 int64 = 32 //TODO:  sm3 hash 长度是固定的32 ?
	var bytes_sm3_hash = make([]byte, 32)
	//var p_bytes_sm3_hash = &bytes_sm3_hash

	proc2, err2 := syscall.GetProcAddress(handle, "SKF_Digest")
	if err2 != nil {
		fmt.Println(err2.Error())
	}
	ret2, _, _ := syscall.SyscallN(uintptr(proc2),
		uintptr(addrptr_ph_hash),
		uintptr(unsafe.Pointer(&bytes_plain_test[0])),
		uintptr(len_bytes_plain_test),
		uintptr(unsafe.Pointer(&bytes_sm3_hash[0])),
		uintptr(unsafe.Pointer(&len_hash_sm3)),
	)
	hash_sm3_b64 := base64.StdEncoding.EncodeToString(bytes_sm3_hash)
	fmt.Printf("hash_sm3_b64 = %s \n", hash_sm3_b64)
	ret2_hex := strconv.FormatInt(int64(ret2), 16)
	fmt.Printf("14. SKF_Digest ret: [%d = %s], len_hash_sm3= %v  sm3 = %v \n", ret2, ret2_hex, len_hash_sm3, bytes_sm3_hash)

	close_handle(handle, addrptr_ph_hash)
	return bytes_sm3_hash
}

type sm2Signature struct {
	R, S *big.Int
}

func sign_hash(handle syscall.Handle, hcont int64, hash_32 []byte) []byte {
	//15. SKF_ECCSignData
	proc, err := syscall.GetProcAddress(handle, "SKF_ECCSignData")
	if err != nil {
		fmt.Println(err.Error())
	}

	var hash_len int64 = int64(len(hash_32))
	var bytes_sign_p1 = make([]byte, 128)
	bytes_sign_p1 = append(bytes_sign_p1, 0)

	ret, _, _ := syscall.SyscallN(uintptr(proc),
		uintptr(hcont),
		uintptr(unsafe.Pointer(&hash_32[0])),
		uintptr(hash_len),
		uintptr(unsafe.Pointer(&bytes_sign_p1[0])),
	)
	//sign_p1_b64 := base64.StdEncoding.EncodeToString(bytes_sign_p1)
	//fmt.Printf("sign_p1_b64 = %s \n",sign_p1_b64)

	//TODO:  将r和s转asn1 pkcs1格式
	// 将签名拆分为r和s
	rBytes := bytes_sign_p1[32:64]
	sBytes := bytes_sign_p1[96:128]
	r_bigint := new(big.Int).SetBytes(rBytes)
	s_bigint := new(big.Int).SetBytes(sBytes)
	sign_p1_asn1, _ := asn1.Marshal(sm2Signature{r_bigint, s_bigint})
	sign_p1_asn1_b64 := base64.StdEncoding.EncodeToString(sign_p1_asn1)
	fmt.Printf("sign_p1_asn1_b64 = %s \n", sign_p1_asn1_b64)

	retHex := strconv.FormatInt(int64(ret), 16)
	fmt.Printf("15. SKF_ECCSignData ret: [%d = %s], sign_p1 = %v \n", ret, retHex, bytes_sign_p1)

	return bytes_sign_p1
}

func verify_hash(handle syscall.Handle, hdev int64, pubkey []byte, hash_32 []byte, bytes_sign_p1 []byte) int64 {
	//16. SKF_ECCVerify
	proc, err := syscall.GetProcAddress(handle, "SKF_ECCVerify")
	if err != nil {
		fmt.Println(err.Error())
	}

	var hash_len int64 = int64(len(hash_32))

	ret, _, _ := syscall.SyscallN(uintptr(proc),
		uintptr(hdev),
		uintptr(unsafe.Pointer(&pubkey[0])),
		uintptr(unsafe.Pointer(&hash_32[0])),
		uintptr(hash_len),
		uintptr(unsafe.Pointer(&bytes_sign_p1[0])),
	)

	retHex := strconv.FormatInt(int64(ret), 16)
	fmt.Printf("16. SKF_ECCVerify ret: [%d = %s] \n", ret, retHex)

	return int64(ret)
}

// 17. SKF_ClearSecureState
func clear_pin(handle syscall.Handle, addr_happ int64) int64 {
	proc, err := syscall.GetProcAddress(handle, "SKF_ClearSecureState")
	if err != nil {
		fmt.Println(err.Error())
		return 0
	}

	ret, _, _ := syscall.SyscallN(uintptr(proc),
		uintptr(addr_happ),
	)

	retHex := strconv.FormatInt(int64(ret), 16)
	fmt.Printf("17. SKF_ClearSecureState ret: [%d = %s] \n", ret, retHex)
	return int64(ret)
}

// SKF_CloseHandle 关闭会话密钥、杂凑、消息认证码句柄。
func close_handle(handle syscall.Handle, handle_hash int64) {
	var fn_name = "SKF_CloseHandle"
	proc, err := syscall.GetProcAddress(handle, fn_name)
	if err != nil {
		fmt.Println(err.Error())
		return
	}

	ret, _, _ := syscall.SyscallN(uintptr(proc),
		uintptr(handle_hash),
	)

	ret_hex := strconv.FormatInt(int64(ret), 16)
	if ret == 0 {
		fmt.Printf("13. %s ret: [%d = %s]  \n", fn_name, ret, ret_hex)
	} else {
		fmt.Printf("\033[31m13. %s ret: [%d = %s] \033[0m \n", fn_name, ret, ret_hex)
	}
}

func close_container(handle syscall.Handle, hcont int64) {
	var fn_name = "SKF_CloseContainer"
	proc, err := syscall.GetProcAddress(handle, fn_name)
	if err != nil {
		fmt.Println(err.Error())
		return
	}

	ret, _, _ := syscall.SyscallN(uintptr(proc),
		uintptr(hcont),
	)

	ret_hex := strconv.FormatInt(int64(ret), 16)
	if ret == 0 {
		fmt.Printf("13. %s ret: [%d = %s]  \n", fn_name, ret, ret_hex)
	} else {
		fmt.Printf("\033[31m13. %s ret: [%d = %s] \033[0m \n", fn_name, ret, ret_hex)
	}
}

func close_application(handle syscall.Handle, happ int64) {
	var fn_name = "SKF_CloseApplication"
	proc, err := syscall.GetProcAddress(handle, fn_name)
	if err != nil {
		fmt.Println(err.Error())
		return
	}

	ret, _, _ := syscall.SyscallN(uintptr(proc),
		uintptr(happ),
	)

	ret_hex := strconv.FormatInt(int64(ret), 16)
	if ret == 0 {
		fmt.Printf("13. %s ret: [%d = %s]  \n", fn_name, ret, ret_hex)
	} else {
		fmt.Printf("\033[31m13. %s ret: [%d = %s] \033[0m \n", fn_name, ret, ret_hex)
	}
}

func close_dev(handle syscall.Handle, hdev int64) {
	var fn_name = "SKF_DisConnectDev"
	proc, err := syscall.GetProcAddress(handle, fn_name)
	if err != nil {
		fmt.Println(err.Error())
		return
	}

	ret, _, _ := syscall.SyscallN(uintptr(proc),
		uintptr(hdev),
	)
	ret_hex := strconv.FormatInt(int64(ret), 16)
	if ret == 0 {
		fmt.Printf("13. %s ret: [%d = %s]  \n", fn_name, ret, ret_hex)
	} else {
		fmt.Printf("\033[31m13. %s ret: [%d = %s] \033[0m \n", fn_name, ret, ret_hex)
	}
}

// SKF_WaitForDevEvent 等待设备的插拔事件
func monitor_dev(handle syscall.Handle, dev_name string) int64 {
	var fn_name = "SKF_WaitForDevEvent"
	proc, err := syscall.GetProcAddress(handle, fn_name)
	if err != nil {
		fmt.Println(err.Error())
		return 0
	}
	var bytes_dev_name = []byte(dev_name)
	bytes_dev_name = append(bytes_dev_name, 0) //TODO: UserPIN要做特殊处理?最后增加0表示字符串结束

	var len_dev int64 = int64(len(dev_name))
	var ret_event int64

	ret, _, _ := syscall.SyscallN(uintptr(proc),
		uintptr(unsafe.Pointer(&bytes_dev_name[0])),
		uintptr(unsafe.Pointer(&len_dev)),
		uintptr(unsafe.Pointer(&ret_event)),
	)
	ret_hex := strconv.FormatInt(int64(ret), 16)

	if ret == 0 {
		fmt.Printf("3. %s ret: [%d = %s], ret_event = [%d]: 1表示插入,2表示拔出 \n", fn_name, ret, ret_hex, ret_event)
	} else {
		fmt.Printf("\033[31m3. %s ret: [%d = %s], ret_event= [%d]: 1表示插入,2表示拔出 \033[0m \n", fn_name, ret, ret_hex, ret_event)
	}
	return ret_event
}

// 检测插拔key动作,并在程序退出前释放资源
func monitor_quit(handle syscall.Handle, phcont int64, happ int64, hdev int64, dev_name string) {
	var wg sync.WaitGroup

	// 创建一个channel来接收操作系统信号
	sigs := make(chan os.Signal, 1)
	// 创建一个带有中断信号的channel
	interrupt := make(chan struct{})

	signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)

	// 启动一个goroutine来监听信号
	wg.Add(1)
	go func() {
		defer wg.Done()

		sig := <-sigs
		fmt.Println()
		fmt.Println(sig, "received")
		// 在退出程序之前执行一些操作
		fmt.Println("cleaning up...")
		//interrupt <- struct{}{}

		close_container(handle, phcont)
		close_application(handle, happ)
		close_dev(handle, hdev)
		//Final.
		syscall.FreeLibrary(handle)

		// 执行完操作后退出程序
		os.Exit(0)
	}()

	// 主函数可以继续执行其他操作
	fmt.Println("doing some work...")
	wg.Add(1)
	go func() {
		defer wg.Done()
		for {
			select {
			case <-interrupt:
				fmt.Printf(" 接收到中断信号,退出循环\n")
			default:
				code_event := monitor_dev(handle, dev_name)
				fmt.Printf("检测到ukey插拔事件:%d \n", code_event)
				time.Sleep(time.Second)

			}
		}

	}()
	// 等待信号
	//<-sigs

	wg.Wait()
}

func main() {
	/**
	0 SKF_EnumDev 设备编号长度= [34]
	0 SKF_EnumDev 设备编号= [TW08220608000002]
	0 SKF_ConnectDev 设备hdev= [native@0x1000]
	0 SKF_EnumApplication app name= [GM3000RSA-TW]
	a000005 = 无效的句柄
	a000006 = 无效的参数
	a00001a = Hash值不相等 (验证签名失败)
	a00002e = 应用不存在
	a000024 = PIN不正确
	a000027 = PIN长度错误
	a00002d = 用户没有登录
	*/

	skf_test()

}

运行结果:


1. 加载SKF库 handle = 140705037090816 
2. SKF_EnumDev ret: 0 = 0, dev_list: [TW08220608000002                   ] len = 35   
3. SKF_ConnectDev ret: 0 = 0, hdev= [2289157607120] 
4. SKF_EnumApplication ret: 0 = 0, appname: [GM3000RSA-TW   ] len = 15   
5. SKF_OpenApplication ret: [0 = 0], appname: [GM3000RSA-TW] len = 12  0xc00000a190 
71. SKF_EnumContainer ret: [0 = 0], size_cont = 112 
7. SKF_EnumContainer ret: [0 = 0], v_size_cont = 110 cont_name=[c08aee27-20c0-4dd3-b108-ed39828f28fa 83e45d70-3bbc-455e-ad21-49e0981b2263 9c1b03cc-0493-4309-8240-a818456d407b] size_cont = 112 
bytes_cont_name = c08aee27-20c0-4dd3-b108-ed39828f28fa 83e45d70-3bbc-455e-ad21-49e0981b2263 9c1b03cc-0493-4309-8240-a818456d407b 
8. SKF_OpenContainer ret: [0 = 0], v_size_cont = 36 cont_name=[c08aee27-20c0-4dd3-b108-ed39828f28fa] 0xc000106000 
phcont = 2289157607584 
9. SKF_GetContainerType ret: [0 = 0], cont_type= 2 (RSA=1,ECC=2) 
cont_type = 2 (RSA=1,ECC=2)
BitLen hex = 00010000 
value = 65536 
xh = 0000000000000000000000000000000000000000000000000000000000000000 
xh = b005c7a6dee9f5e5c0e***********61a2269d977d99733ac4f291b388078 
xh = 0000000000000000000000000000000000000000000000000000000000000000 
xh = c290ab63fa4919b33e6************0c6a3f0afdaf36689d41d75a78aaa1827c2 
10. SKF_ExportPublicKey ret: [0 = 0], p_pubkey_len= 133 pubkey_hex=[000100000000000000000000000000000000000000000000000000000000000000000000b005c7a6dee9f5e5c0ebc1bc24405251***********d99733ac4f291b3880780000000000000000000000000000000000000000000000000000000000000000c290ab63fa4919b33e667f6***********afdaf36689d41d75a78aaa1827c200] 
pubkey = [0 1 0 0 0 0 0 *********** 243 102 137 212 29 117 167 138 170 24 39 194 0] 
v_cert_len = 624 
cert_b64 = MIICbDCCAhGg********KfAA== 
11. SKF_ExportCertificate ret: [0 = 0], v_cert_len= 624  
cert_len = 624 cert_bytes = [48 130 2 108 48 ****114 1 209 204 170 95 176 9 175 162 159 0] 
13. SKF_DigestInit ret: [0 = 0], addrptr_ph_hash= 2289157628592  
hash_sm3_b64 = QL0AFWMIX8NRZTKeof9cXsvbvu8AAAAAAAAAAAAAAAA= 
14. SKF_Digest ret: [0 = 0], len_hash_sm3= 20  sm3 = [64 189 0 21 99 8 95 195 81 101 50 158 161 255 92 94 203 219 190 239 0 0 0 0 0 0 0 0 0 0 0 0] 
13. SKF_CloseHandle ret: [0 = 0]  
6. SKF_ChangePIN ret: [0 = 0], user_pin: [12345678] len = 8 retry_count = 0 
6. SKF_UnblockPIN ret: [0 = 0], user_pin: [12345678] len = 8 retry_count = 0 
6. SKF_VerifyPIN ret: [0 = 0], user_pin: [12345678] len = 8 retry_count = 0 
sign_p1_asn1_b64 = MEQCIFf6irIONJURxKNrRgs33ej/m8m1onjwBGGBW2ggd1vtAiBu0RIlEuHQUBnKu8c4skoH1P/HxDKJAS/O2zvkO01ZNg== 
15. SKF_ECCSignData ret: [0 = 0], sign_p1 = [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 87 250 138 178 14 52 149 17 196 163 107 70 11 55 221 232 255 155 201 181 162 120 240 4 97 129 91 104 32 119 91 237 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 110 209 18 37 18 225 208 80 25 202 187 199 56 178 74 7 212 255 199 196 50 137 1 47 206 219 59 228 59 77 89 54 0] 
13. SKF_DigestInit ret: [0 = 0], addrptr_ph_hash= 2289157628304  
hash_sm3_b64 = QL0AFWMIX8NRZTKeof9cXsvbvu8AAAAAAAAAAAAAAAA= 
14. SKF_Digest ret: [0 = 0], len_hash_sm3= 20  sm3 = [64 189 0 21 99 8 95 195 81 101 50 158 161 255 92 94 203 219 190 239 0 0 0 0 0 0 0 0 0 0 0 0] 
13. SKF_CloseHandle ret: [0 = 0]  
16. SKF_ECCVerify ret: [0 = 0] 
17. SKF_ClearSecureState ret: [0 = 0] 
doing some work...
3. SKF_WaitForDevEvent ret: [0 = 0], ret_event = [2]: 1表示插入,2表示拔出 
检测到ukey插拔事件:2 
3. SKF_WaitForDevEvent ret: [0 = 0], ret_event = [1]: 1表示插入,2表示拔出 
检测到ukey插拔事件:1 
3. SKF_WaitForDevEvent ret: [0 = 0], ret_event = [2]: 1表示插入,2表示拔出 
检测到ukey插拔事件:2 
3. SKF_WaitForDevEvent ret: [0 = 0], ret_event = [2]: 1表示插入,2表示拔出 
检测到ukey插拔事件:2 
3. SKF_WaitForDevEvent ret: [0 = 0], ret_event = [1]: 1表示插入,2表示拔出 
检测到ukey插拔事件:1 

interrupt received
cleaning up...
13. SKF_CloseContainer ret: [0 = 0]  
13. SKF_CloseApplication ret: [0 = 0]  
13. SKF_DisConnectDev ret: [0 = 0]  

Process finished with the exit code 0

感觉go调用dll比java更方便一些。

20240911: linux下调用skf so库方法与windows不同。这里使用purego,不需要cgo很方便。

package main

import (
	"bytes"
	"encoding/asn1"
	"encoding/base64"
	"encoding/hex"
	"fmt"
	"github.com/ebitengine/purego"
	_ "io/ioutil"
	"math/big"
	"os"
	"os/signal"
	"strconv"
	"syscall"
	"time"
	"unsafe"
)

func skf_test() {
	//1. 加载dll
	//CGO_ENABLED=0;GOARCH=amd64;GOOS=linux
	dll_name := "./libgm3000.1.0_static_debug.so" //不能省略.so. 使用debug版so,可以在/var/tmp/mk_log.log里查看接口调用日志
	//dll_name := "./lib/mtoken_gm3000_tw.dll" //qurego不支持windows?
	handle := get_dll_handle(dll_name)

	//2. SKF_EnumDev
	dev_list := get_devs(handle)
	if len(dev_list) == 0 {
		fmt.Printf("未找到ukey设备。\n")
		return
	}
	dev_name := string(bytes.Split(dev_list, []byte{0})[0])

	//3. SKF_ConnectDev
	dev_name = "TW08220608000002"
	hdev := conn_dev(handle, dev_name)

	//4. SKF_EnumApplication
	app_list := get_apps(handle, hdev)
	//app_name := string(bytes.TrimRight(app_list,string([]byte{0})))
	app_name := string(bytes.Split(app_list, []byte{0})[0])

	//5. SKF_EnumApplication
	app_name = "GM3000RSA-TW"
	happ := open_app(handle, hdev, app_name)

	//7. SKF_EnumContainer
	bytes_cont_name := get_containers(handle, happ)

	//8. SKF_OpenContainer
	//cont_name := "c08aee27-20c0-4dd3-b108-ed39828f28fa"
	//cont_name := strings.Split(string(bytes_cont_name), " ")[0]	//TODO: 选择第一个cont
	cont_name := string(bytes.Split(bytes_cont_name, []byte{0})[0])
	fmt.Printf("cont_name = %s \n", cont_name)

	//8. SKF_OpenContainer
	cont_name = "c08aee27-20c0-4dd3-b108-ed39828f28fa"
	phcont := open_container(handle, happ, cont_name)
	fmt.Printf("phcont = %v \n", phcont)

	//9. SKF_GetContainerType
	cont_type := get_container_type(handle, phcont)
	fmt.Printf("cont_type = %d (RSA=1,ECC=2)\n", cont_type)

	//10. SKF_ExportPublicKey
	pubkey := get_pubkey(handle, phcont)
	fmt.Printf("pubkey = %v \n", pubkey)

	//11. SKF_ExportCertificate
	cert_len, cert_bytes := get_cert(handle, phcont, 1)
	fmt.Printf("cert_len = %v cert_bytes = %v \n", cert_len, cert_bytes)

	//13. SKF_DigestInit  14. SKF_Digest
	//注意:这里传入的是hdev,不是phcont
	//rsa_or_ecc 为1表示为RSA容器,为2表示为ECC容器
	bytes_hash_32 := sm3_with_uid(handle, hdev, 2, pubkey, "123")

	//6. SKF_VerifyPIN
	var adminPin = "admin"
	var userPin = "12345678"
	var userPinNew = "12345678"
	change_pin(handle, happ, userPin, userPinNew)
	unlock_pin(handle, happ, adminPin, userPin)
	verify_pin(handle, happ, userPin)

	//15. SKF_ECCSignData
	//注意:这里传入的hcont
	bytes_sign_p1 := sign_hash(handle, phcont, bytes_hash_32)
	//fmt.Printf("bytes_sign_p1 = %v \n", bytes_sign_p1)

	verify_hash(handle, hdev, pubkey, bytes_hash_32, bytes_sign_p1)

	bytes_hash_32_2 := sm3_with_uid(handle, hdev, 2, pubkey, "1234")
	//16. SKF_ECCVerify
	//注意:这里传入hdev.
	verify_hash(handle, hdev, pubkey, bytes_hash_32_2, bytes_sign_p1)

	//17. SKF_ClearSecureState
	clear_pin(handle, happ)

	//Final.
	//syscall.FreeLibrary(handle)

	//阻塞检查插拔key,和ctl+c组合键退出程序
	monitor_quit(handle, phcont, happ, hdev, dev_name)
}

// 1. 加载SKF库
func get_dll_handle(path_dll string) uintptr {
	//"lib/mtoken_gm3000_tw"
	//1. 加载SKF库
	libc, err := purego.Dlopen(path_dll, purego.RTLD_NOW|purego.RTLD_GLOBAL)
	if err != nil {
		panic(err)
	}

	var SKF_EnumDev func(uintptr, uintptr, uintptr) int64
	purego.RegisterLibFunc(&SKF_EnumDev, libc, "SKF_EnumDev")

	//TODO: 这里不能defer syscall.FreeLibrary(handle),否则后面会报错。
	//程序结束时,需要手动syscall.FreeLibrary(handle)
	/*
		defer func(handle syscall.Handle) {
			_ = syscall.FreeLibrary(handle)
		}(handle)
	*/

	fmt.Printf("1. 加载SKF库 libc = %v \n", libc)
	return libc
}

// 2. SKF_EnumDev
func get_devs(libc uintptr) []byte {
	var fn_name = "SKF_EnumDev"
	var fn func(uintptr, uintptr, uintptr) int64
	purego.RegisterLibFunc(&fn, libc, fn_name)

	var len_devName int64
	ret := fn(
		uintptr(1),
		uintptr(0),
		uintptr(unsafe.Pointer(&len_devName)),
	)
	ret_hex := strconv.FormatInt(int64(ret), 16)
	if ret == 0 {
		fmt.Printf("ret = [%d = %s],len_devName = %d \n", ret, ret_hex, len_devName)
	} else {
		fmt.Printf("\033[31mret = [%d = %s] ,len_devName = %d \033[0m \n", ret, ret_hex, len_devName)
		return nil
	}

	var byte_dev_list = make([]byte, len_devName)
	ret2 := fn(
		uintptr(1),
		uintptr(unsafe.Pointer(&byte_dev_list[0])),
		uintptr(unsafe.Pointer(&len_devName)),
	)

	ret2_hex := strconv.FormatInt(int64(ret2), 16)
	if ret2 == 0 {
		fmt.Printf("2. %s ret: [%d = %s], dev_list: [%s] len = %d   \n", fn_name, ret, ret2_hex, byte_dev_list, len(byte_dev_list))
	} else {
		fmt.Printf("\033[31m2. %s ret: [%d = %s], dev_list: [%s] len = %d \033[0m  \n", fn_name, ret, ret2_hex, byte_dev_list, len(byte_dev_list))
	}
	return byte_dev_list
}

// 3. SKF_ConnectDev
func conn_dev(libc uintptr, dev_name string) int64 {
	var fn_name = "SKF_ConnectDev"
	var fn func(uintptr, uintptr) int64
	purego.RegisterLibFunc(&fn, libc, fn_name)

	var bytes_dev_name = []byte(dev_name)      //TODO:  注意字符串型参数,要转为[]byte,并指定[0]:uintptr(unsafe.Pointer(&dev_name[0]))
	bytes_dev_name = append(bytes_dev_name, 0) //TODO: UserPIN要做特殊处理?最后增加0表示字符串结束

	var hdev int64
	p_hdev := &hdev
	ret := fn(
		uintptr(unsafe.Pointer(&bytes_dev_name[0])),
		uintptr(unsafe.Pointer(&p_hdev)),
	)

	ret_hex := strconv.FormatInt(int64(ret), 16)
	ptr_hdev := unsafe.Pointer(&p_hdev)
	hdev = *(*int64)(unsafe.Pointer(ptr_hdev)) //TODO:  hdev = uintptr(dd)

	if ret == 0 {
		fmt.Printf("3. %s ret: [%d = %s], hdev= [%v] \n", fn_name, ret, ret_hex, hdev)
	} else {
		fmt.Printf("\033[31m3. %s ret: [%d = %s], hdev= [%v] \033[0m \n", fn_name, ret, ret_hex, hdev)
	}
	return hdev
}

// SKF_WaitForDevEvent 等待设备的插拔事件
func monitor_dev(libc uintptr, dev_name string) int64 {
	var fn_name = "SKF_WaitForDevEvent"
	var fn func(uintptr, uintptr, uintptr) int64
	purego.RegisterLibFunc(&fn, libc, fn_name)

	var bytes_dev_name = []byte(dev_name)      //TODO:  注意字符串型参数,要转为[]byte,并指定[0]:uintptr(unsafe.Pointer(&dev_name[0]))
	bytes_dev_name = append(bytes_dev_name, 0) //TODO: UserPIN要做特殊处理?最后增加0表示字符串结束

	var len_dev int64 = int64(len(dev_name))
	var ret_event int64

	ret := fn(
		uintptr(unsafe.Pointer(&bytes_dev_name[0])),
		uintptr(unsafe.Pointer(&len_dev)),
		uintptr(unsafe.Pointer(&ret_event)),
	)
	ret_hex := strconv.FormatInt(int64(ret), 16)

	if ret == 0 {
		fmt.Printf("3. %s ret: [%d = %s], ret_event = [%d]: 1表示插入,2表示拔出 \n", fn_name, ret, ret_hex, ret_event)
	} else {
		fmt.Printf("\033[31m3. %s ret: [%d = %s], ret_event= [%d]: 1表示插入,2表示拔出 \033[0m \n", fn_name, ret, ret_hex, ret_event)
	}
	return ret_event
}

// 4. SKF_EnumApplication
func get_apps(libc uintptr, hdev int64) []byte {
	var fn_name = "SKF_EnumApplication"
	var fn func(uintptr, uintptr, uintptr) int64
	purego.RegisterLibFunc(&fn, libc, fn_name)

	var size_app_name int64
	fn(
		uintptr(hdev),
		uintptr(0),
		uintptr(unsafe.Pointer(&size_app_name)),
	)
	//ret41_hex := strconv.FormatInt(int64(ret41), 16)
	//fmt.Printf("SKF_EnumApplication ret: %d = %s, size_app_name = %d  \n", ret41,ret41_hex, size_app_name)

	var app_list = make([]byte, size_app_name)
	ret := fn(
		uintptr(hdev),
		uintptr(unsafe.Pointer(&app_list[0])),
		uintptr(unsafe.Pointer(&size_app_name)),
	)
	//app_name := string(bytes.TrimRight(app_list,string([]byte{0})))

	ret_hex := strconv.FormatInt(int64(ret), 16)
	if ret == 0 {
		fmt.Printf("4. %s ret: [%d = %s], appname: [%s] len = %d   \n", fn_name, ret, ret_hex, app_list, len(app_list))
	} else {
		fmt.Printf("\033[31m4. %s ret: [%d = %s], appname: [%s] len = %d \033[0m  \n", fn_name, ret, ret_hex, app_list, len(app_list))
	}
	return app_list
}

// 5. SKF_OpenApplication
func open_app(libc uintptr, hdev int64, app_name string) int64 {
	var fn_name = "SKF_OpenApplication"
	var fn func(uintptr, uintptr, uintptr) int64
	purego.RegisterLibFunc(&fn, libc, fn_name)

	//app_name = "GM3000RSA-TW"	//a00002e=应用不存在
	bytes_app_name := []byte(app_name)         //TODO:  字符串型入参,转为[]byte,uintptr(unsafe.Pointer(&bytes_app_name[0]))
	bytes_app_name = append(bytes_app_name, 0) //TODO: UserPIN要做特殊处理?最后增加0表示字符串结束

	var happ int64
	p_happ := &happ
	ret := fn(
		uintptr(hdev),
		uintptr(unsafe.Pointer(&bytes_app_name[0])),
		uintptr(unsafe.Pointer(&p_happ)),
	)
	ptr_happ := unsafe.Pointer(&p_happ)              //TODO:  句柄处理
	addr_happ := *(*int64)(unsafe.Pointer(ptr_happ)) //TODO:  hdev = uintptr(dd)

	ret_hex := strconv.FormatInt(int64(ret), 16)
	if ret == 0 {
		fmt.Printf("5. %s ret: [%d = %s], appname: [%s] len = %d  %v \n", fn_name, ret, ret_hex, app_name, len(app_name), &addr_happ)
	} else {
		fmt.Printf("\033[31m5. %s ret: [%d = %s], appname: [%s] len = %d  %v \033[0m \n", fn_name, ret, ret_hex, app_name, len(app_name), &addr_happ)
	}
	return addr_happ
}

// 6. SKF_VerifyPIN
func change_pin(libc uintptr, addr_happ int64, user_pin string, user_pin_new string) {
	var fn_name = "SKF_ChangePIN"
	var fn func(uintptr, uintptr, uintptr, uintptr, uintptr) int64
	purego.RegisterLibFunc(&fn, libc, fn_name)

	var pin_type int64 = 1 //TODO:  USER_PIN=1, ADMIN_PIN=0

	//var bytes_user_pin = []byte(user_pin) //TODO:  字符串型入参,转为[]byte,uintptr(unsafe.Pointer(&bytes_app_name[0]))
	var bytes_user_pin = []byte(user_pin)
	bytes_user_pin = append(bytes_user_pin, 0)

	var bytes_user_pin_new = []byte(user_pin_new)
	bytes_user_pin_new = append(bytes_user_pin_new, 0)

	//bytes_user_pin := C.CString(user_pin)
	var retry_count int64
	//var p_retry_count = &retry_count
	ret := fn(
		uintptr(addr_happ),
		uintptr(pin_type),
		uintptr(unsafe.Pointer(&bytes_user_pin[0])),
		uintptr(unsafe.Pointer(&bytes_user_pin_new[0])),
		uintptr(unsafe.Pointer(&retry_count)),
	)

	//v_retry_count := *(*int64)(unsafe.Pointer(p_retry_count))	//TODO:  出参long取值有问题
	ret_hex := strconv.FormatInt(int64(ret), 16)
	if ret == 0 {
		fmt.Printf("6. %s ret: [%d = %s], user_pin: [%v] len = %d retry_count = %d \n", fn_name, ret, ret_hex, user_pin, len(user_pin), retry_count)
	} else {
		fmt.Printf("\033[31m6. %s ret: [%d = %s], user_pin: [%v] len = %d retry_count = %d \033[0m \n", fn_name, ret, ret_hex, user_pin, len(user_pin), retry_count)
	}
}

func verify_pin(libc uintptr, addr_happ int64, user_pin string) {
	var fn_name = "SKF_VerifyPIN"
	var fn func(uintptr, uintptr, uintptr, uintptr) int64
	purego.RegisterLibFunc(&fn, libc, fn_name)

	var pin_type int64 = 1 //TODO:  USER_PIN=1, ADMIN_PIN=0

	var bytes_user_pin = []byte(user_pin)      //TODO:  字符串型入参,转为[]byte,uintptr(unsafe.Pointer(&bytes_app_name[0]))
	bytes_user_pin = append(bytes_user_pin, 0) //TODO: UserPIN要做特殊处理?最后增加0表示字符串结束

	var retry_count int64
	ret := fn(
		uintptr(addr_happ),
		uintptr(pin_type),
		uintptr(unsafe.Pointer(&bytes_user_pin[0])),
		uintptr(unsafe.Pointer(&retry_count)),
	)

	ret_hex := strconv.FormatInt(int64(ret), 16)
	if ret == 0 {
		fmt.Printf("6. %s ret: [%d = %s], user_pin: [%v] len = %d retry_count = %d \n", fn_name, ret, ret_hex, user_pin, len(user_pin), retry_count)
	} else {
		fmt.Printf("\033[31m6. %s ret: [%d = %s], user_pin: [%v] len = %d retry_count = %d \033[0m \n", fn_name, ret, ret_hex, user_pin, len(user_pin), retry_count)
	}
}

// SKF_UnblockPIN
func unlock_pin(libc uintptr, addr_happ int64, admin_pin string, user_pin string) {
	var fn_name = "SKF_UnblockPIN"
	var fn func(uintptr, uintptr, uintptr, uintptr) int64
	purego.RegisterLibFunc(&fn, libc, fn_name)

	var bytes_admin_pin = []byte(admin_pin)
	bytes_admin_pin = append(bytes_admin_pin, 0)
	var bytes_user_pin = []byte(user_pin)
	bytes_user_pin = append(bytes_user_pin, 0)

	var retry_count int64
	ret := fn(
		uintptr(addr_happ),
		uintptr(unsafe.Pointer(&bytes_admin_pin[0])),
		uintptr(unsafe.Pointer(&bytes_user_pin[0])),
		uintptr(unsafe.Pointer(&retry_count)),
	)

	ret_hex := strconv.FormatInt(int64(ret), 16)
	if ret == 0 {
		fmt.Printf("6. %s ret: [%d = %s], user_pin: [%v] len = %d retry_count = %d \n", fn_name, ret, ret_hex, user_pin, len(user_pin), retry_count)
	} else {
		fmt.Printf("\033[31m6. %s ret: [%d = %s], user_pin: [%v] len = %d retry_count = %d \033[0m \n", fn_name, ret, ret_hex, user_pin, len(user_pin), retry_count)
	}
}

// 7. SKF_EnumContainer
func get_containers(libc uintptr, addr_happ int64) []byte {
	var fn_name = "SKF_EnumContainer"
	var fn func(uintptr, uintptr, uintptr) int64
	purego.RegisterLibFunc(&fn, libc, fn_name)

	var size_cont int64

	ret := fn(
		uintptr(addr_happ),
		uintptr(0),
		uintptr(unsafe.Pointer(&size_cont)), //TODO: int64 出参
	)
	ret_hex := strconv.FormatInt(int64(ret), 16)
	if ret == 0 {
		fmt.Printf("71. %s ret: [%d = %s], size_cont = %d \n", fn_name, ret, ret_hex, size_cont)
	} else {
		fmt.Printf("\033[31m71. %s ret: [%d = %s], size_cont = %d \033[0m \n", fn_name, ret, ret_hex, size_cont)
	}

	var cont_list = make([]byte, size_cont)

	ret7 := fn(
		uintptr(addr_happ),
		uintptr(unsafe.Pointer(&cont_list[0])),
		uintptr(unsafe.Pointer(&size_cont)), //TODO: int64 出参
	)

	bytes_cont_name := bytes.TrimRight(cont_list, string([]byte{0}))

	ret7_hex := strconv.FormatInt(int64(ret7), 16)
	if ret7 == 0 {
		fmt.Printf("7. %s ret: [%d = %s], v_size_cont = %d cont_name=[%s] size_cont = %d \n", fn_name, ret7, ret7_hex, len(bytes_cont_name), bytes_cont_name, size_cont)
	} else {
		fmt.Printf("\033[31m7. %s ret: [%d = %s], v_size_cont = %d cont_name=[%s] size_cont = %d \033[0m \n", fn_name, ret7, ret7_hex, len(bytes_cont_name), bytes_cont_name, size_cont)
	}
	return bytes_cont_name
}

// 8. SKF_OpenContainer
func open_container(libc uintptr, addr_happ int64, cont_name string) int64 {
	var fn_name = "SKF_OpenContainer"
	var fn func(uintptr, uintptr, uintptr) int64
	purego.RegisterLibFunc(&fn, libc, fn_name)

	//var cont_name = "c08aee27-20c0-4dd3-b108-ed39828f28fa"
	var bytes_cont_name = []byte(cont_name)
	bytes_cont_name = append(bytes_cont_name, 0) //TODO: UserPIN要做特殊处理?最后增加0表示字符串结束

	var phcont int64

	ret := fn(
		uintptr(addr_happ),
		uintptr(unsafe.Pointer(&bytes_cont_name[0])),
		uintptr(unsafe.Pointer(&phcont)),
	)

	ret_hex := strconv.FormatInt(int64(ret), 16)
	if ret == 0 {
		fmt.Printf("8. %s ret: [%d = %s], v_size_cont = %d cont_name=[%s] %v \n", fn_name, ret, ret_hex, len(cont_name), cont_name, &phcont)
	} else {
		fmt.Printf("\033[31m8. %s ret: [%d = %s], v_size_cont = %d cont_name=[%s] %v \033[0m \n", fn_name, ret, ret_hex, len(cont_name), cont_name, &phcont)
	}
	return phcont
}

// 9. SKF_GetContainerType
func get_container_type(libc uintptr, addr_phcont int64) int64 {
	var fn_name = "SKF_GetContainerType"
	var fn func(uintptr, uintptr) int64
	purego.RegisterLibFunc(&fn, libc, fn_name)

	var cont_type int64
	//p_cont_type := &cont_type

	ret := fn(
		uintptr(addr_phcont),
		uintptr(unsafe.Pointer(&cont_type)),
	)
	//v_cont_type := *(*int64)(unsafe.Pointer(p_cont_type))	//TODO:  出参long取值有问题

	ret_hex := strconv.FormatInt(int64(ret), 16)
	if ret == 0 {
		fmt.Printf("9. %s ret: [%d = %s], cont_type= %d (RSA=1,ECC=2) \n", fn_name, ret, ret_hex, cont_type)
	} else {
		fmt.Printf("\033[31m9. %s ret: [%d = %s], cont_type= %d (RSA=1,ECC=2) \033[0m \n", fn_name, ret, ret_hex, cont_type)
	}
	return cont_type
}

// 10. SKF_ExportPublicKey
func get_pubkey(libc uintptr, addr_phcont int64) []byte {
	var fn_name = "SKF_ExportPublicKey"
	var fn func(uintptr, uintptr, uintptr, uintptr) int64
	purego.RegisterLibFunc(&fn, libc, fn_name)

	pubkey_len := 132
	p_pubkey_len := &pubkey_len

	var p_pubkey = make([]byte, 132)

	ret := fn(
		uintptr(addr_phcont),
		1,
		uintptr(unsafe.Pointer(&p_pubkey[0])),
		uintptr(unsafe.Pointer(&p_pubkey_len)),
	)

	pubkey_str := hex.EncodeToString(p_pubkey)
	BitLen := hex.EncodeToString(p_pubkey[0:4])
	xh := hex.EncodeToString(p_pubkey[4:36])
	x := hex.EncodeToString(p_pubkey[36:68])
	yh := hex.EncodeToString(p_pubkey[68:100])
	y := hex.EncodeToString(p_pubkey[100:132])

	value, _ := strconv.ParseUint(BitLen, 16, 32)
	fmt.Printf("BitLen = %d \n", value)
	fmt.Printf("BitLen = %v \n", BitLen)
	fmt.Printf("xh = %v \n", xh)
	fmt.Printf("xh = %v \n", x)
	fmt.Printf("xh = %v \n", yh)
	fmt.Printf("xh = %v \n", y)

	ret_hex := strconv.FormatInt(int64(ret), 16)
	if ret == 0 {
		fmt.Printf("10. %s ret: [%d = %s], p_pubkey_len= %d pubkey_hex=[%s] \n", fn_name, ret, ret_hex, len(p_pubkey), pubkey_str)
	} else {
		fmt.Printf("\033[31m10. %s ret: [%d = %s], p_pubkey_len= %d pubkey_hex=[%s] \033[0m \n", fn_name, ret, ret_hex, len(p_pubkey), pubkey_str)
	}
	return p_pubkey
}

// 11. SKF_ExportCertificate
// sign_or_enc [IN] TRUE表示签名证书,FALSE表示加密证书
func get_cert(libc uintptr, addr_phcont int64, sign_or_enc int64) (int64, []byte) {
	var fn_name = "SKF_ExportCertificate"
	var fn func(uintptr, uintptr, uintptr, uintptr) int64
	purego.RegisterLibFunc(&fn, libc, fn_name)

	var cert_len int64 //TODO: int64出参,无需&?

	fn(
		uintptr(addr_phcont),
		uintptr(sign_or_enc), //[IN] TRUE表示签名证书,FALSE表示加密证书
		uintptr(0),
		uintptr(unsafe.Pointer(&cert_len)),
	)
	//v_cert_len := *(*int64)(unsafe.Pointer(p_cert_len))	//TODO:  出参long取值有问题
	fmt.Printf("v_cert_len = %d \n", cert_len)

	//p_cert_len := &cert_len
	var p_cert = make([]byte, cert_len)

	ret := fn(
		uintptr(addr_phcont),
		uintptr(sign_or_enc), //[IN] TRUE表示签名证书,FALSE表示加密证书
		uintptr(unsafe.Pointer(&p_cert[0])),
		uintptr(unsafe.Pointer(&cert_len)),
	)
	//cert_hex := hex.EncodeToString(p_cert)
	cert_b64 := base64.StdEncoding.EncodeToString(p_cert)
	fmt.Printf("cert_b64 = %s \n", cert_b64)

	ret_hex := strconv.FormatInt(int64(ret), 16)
	if ret == 0 {
		fmt.Printf("11. %s ret: [%d = %s], v_cert_len= %d  \n", fn_name, ret, ret_hex, cert_len)
	} else {
		fmt.Printf("\033[31m11. %s ret: [%d = %s], v_cert_len= %d \033[0m \n", fn_name, ret, ret_hex, cert_len)
	}
	return cert_len, p_cert
}

// 12. SKF_DigestInit SKF_Digest
// rsa_or_ecc 为1表示为RSA容器,为2表示为ECC容器
func sm3_with_uid(libc uintptr, hdev int64, rsa_or_ecc int64, pubkey []byte, plain string) []byte {
	var fn_name = "SKF_DigestInit"
	var fn func(uintptr, uintptr, uintptr, uintptr, uintptr, uintptr) int64
	purego.RegisterLibFunc(&fn, libc, fn_name)

	var userid = "1234567812345678"
	var bytes_userid = []byte(userid)      //TODO:  字符串型入参,转为[]byte,uintptr(unsafe.Pointer(&bytes_app_name[0]))
	bytes_userid = append(bytes_userid, 0) //TODO: UserPIN要做特殊处理?最后增加0表示字符串结束

	var userid_len int64 = int64(len(bytes_userid))
	var h_hash int64
	ph_hash := &h_hash

	ret := fn(
		uintptr(hdev),
		uintptr(rsa_or_ecc), //为1表示为RSA容器,为2表示为ECC容器
		uintptr(unsafe.Pointer(&pubkey[0])),
		uintptr(unsafe.Pointer(&bytes_userid[0])),
		uintptr(userid_len),
		uintptr(unsafe.Pointer(&ph_hash)),
	)
	ptr_ph_hash := unsafe.Pointer(&ph_hash) //TODO:  句柄处理
	addrptr_ph_hash := *(*int64)(unsafe.Pointer(ptr_ph_hash))

	ret_hex := strconv.FormatInt(int64(ret), 16)
	if ret == 0 {
		fmt.Printf("13. %s ret: [%d = %s], addrptr_ph_hash= %v  \n", fn_name, ret, ret_hex, addrptr_ph_hash)
	} else {
		fmt.Printf("\033[31m13. %s ret: [%d = %s], addrptr_ph_hash= %v \033[0m \n", fn_name, ret, ret_hex, addrptr_ph_hash)
	}

	//
	//var plain_test = "test123"
	var plain_test = plain
	var bytes_plain_test = []byte(plain_test)
	bytes_plain_test = append(bytes_plain_test, 0) //TODO: UserPIN要做特殊处理?最后增加0表示字符串结束

	var len_bytes_plain_test = len(bytes_plain_test)
	var len_hash_sm3 int64 = 32 //TODO:  sm3 hash 长度是固定的20/32 ?
	var bytes_sm3_hash = make([]byte, 32)
	//var p_bytes_sm3_hash = &bytes_sm3_hash

	fn_name = "SKF_Digest"
	var fn2 func(uintptr, uintptr, uintptr, uintptr, uintptr) int64
	purego.RegisterLibFunc(&fn2, libc, fn_name)
	ret2 := fn2(
		uintptr(addrptr_ph_hash),
		uintptr(unsafe.Pointer(&bytes_plain_test[0])),
		uintptr(len_bytes_plain_test),
		uintptr(unsafe.Pointer(&bytes_sm3_hash[0])),
		uintptr(unsafe.Pointer(&len_hash_sm3)),
	)
	defer close_handle(libc, addrptr_ph_hash)

	hash_sm3_b64 := base64.StdEncoding.EncodeToString(bytes_sm3_hash)
	fmt.Printf("hash_sm3_b64 = %s \n", hash_sm3_b64)
	ret2_hex := strconv.FormatInt(int64(ret2), 16)
	//fmt.Printf("14. %s ret: [%d = %s], len_hash_sm3= %v  sm3 = %v \n", fn_name, ret2, ret2_hex, len_hash_sm3, bytes_sm3_hash)
	if ret2 == 0 {
		fmt.Printf("14. %s ret: [%d = %s], len_hash_sm3= %v  \n", fn_name, ret2, ret2_hex, len_hash_sm3)
	} else {
		fmt.Printf("\033[31m14. %s ret: [%d = %s], len_hash_sm3= %v \033[0m \n", fn_name, ret2, ret2_hex, len_hash_sm3)
	}

	return bytes_sm3_hash
}

// 12. SKF_DigestInit SKF_Digest
func sm3_no_uid(libc uintptr, hdev int64, rsa_or_ecc int64, pubkey []byte, plain string) []byte {
	var fn_name = "SKF_DigestInit"
	var fn func(uintptr, uintptr, uintptr, uintptr, uintptr, uintptr) int64
	purego.RegisterLibFunc(&fn, libc, fn_name)

	var userid = "1234567812345678"
	var bytes_userid = []byte(userid)      //TODO:  字符串型入参,转为[]byte,uintptr(unsafe.Pointer(&bytes_app_name[0]))
	bytes_userid = append(bytes_userid, 0) //TODO: UserPIN要做特殊处理?最后增加0表示字符串结束

	var userid_len int64 = int64(len(bytes_userid))
	var h_hash int64
	ph_hash := &h_hash

	ret := fn(
		uintptr(hdev),
		uintptr(rsa_or_ecc), //为1表示为RSA容器,为2表示为ECC容器
		uintptr(unsafe.Pointer(&pubkey[0])),
		uintptr(unsafe.Pointer(&bytes_userid[0])),
		uintptr(userid_len),
		uintptr(unsafe.Pointer(&ph_hash)),
	)

	ptr_ph_hash := unsafe.Pointer(&ph_hash) //TODO:  句柄处理
	addrptr_ph_hash := *(*int64)(unsafe.Pointer(ptr_ph_hash))

	ret_hex := strconv.FormatInt(int64(ret), 16)
	if ret == 0 {
		fmt.Printf("13. %s ret: [%d = %s], addrptr_ph_hash= %v  \n", fn_name, ret, ret_hex, addrptr_ph_hash)
	} else {
		fmt.Printf("\033[31m13. %s ret: [%d = %s], addrptr_ph_hash= %v \033[0m \n", fn_name, ret, ret_hex, addrptr_ph_hash)
	}

	//
	//var plain_test = "test123"
	var plain_test = plain
	var bytes_plain_test = []byte(plain_test)
	bytes_plain_test = append(bytes_plain_test, 0) //TODO: UserPIN要做特殊处理?最后增加0表示字符串结束

	var len_bytes_plain_test = len(bytes_plain_test)
	var len_hash_sm3 int64 = 32 //TODO:  sm3 hash 长度是固定的32 ?
	var bytes_sm3_hash = make([]byte, 32)
	//var p_bytes_sm3_hash = &bytes_sm3_hash

	fn_name = "SKF_Digest"
	var fn2 func(uintptr, uintptr, uintptr, uintptr, uintptr) int64
	purego.RegisterLibFunc(&fn, libc, fn_name)

	ret2 := fn2(
		uintptr(addrptr_ph_hash),
		uintptr(unsafe.Pointer(&bytes_plain_test[0])),
		uintptr(len_bytes_plain_test),
		uintptr(unsafe.Pointer(&bytes_sm3_hash[0])),
		uintptr(unsafe.Pointer(&len_hash_sm3)),
	)

	hash_sm3_b64 := base64.StdEncoding.EncodeToString(bytes_sm3_hash)
	fmt.Printf("hash_sm3_b64 = %s \n", hash_sm3_b64)
	ret2_hex := strconv.FormatInt(int64(ret2), 16)
	if ret2 == 0 {
		fmt.Printf("14. %s ret: [%d = %s], len_hash_sm3= %v  sm3 = %v \n", fn_name, ret2, ret2_hex, len_hash_sm3, bytes_sm3_hash)
	} else {
		fmt.Printf("\033[31m14. %s ret: [%d = %s], len_hash_sm3= %v  sm3 = %v \033[0m \n", fn_name, ret2, ret2_hex, len_hash_sm3, bytes_sm3_hash)
	}

	return bytes_sm3_hash
}

type sm2Signature struct {
	R, S *big.Int
}

// 15. SKF_ECCSignData
func sign_hash(libc uintptr, hcont int64, hash_32 []byte) []byte {
	var fn_name = "SKF_ECCSignData"
	var fn func(uintptr, uintptr, uintptr, uintptr) int64
	purego.RegisterLibFunc(&fn, libc, fn_name)

	var hash_len int64 = int64(len(hash_32))
	var bytes_sign_p1 = make([]byte, 128)

	ret := fn(
		uintptr(hcont),
		uintptr(unsafe.Pointer(&hash_32[0])),
		uintptr(hash_len),
		uintptr(unsafe.Pointer(&bytes_sign_p1[0])),
	)

	//sign_p1_b64 := base64.StdEncoding.EncodeToString(bytes_sign_p1)
	//fmt.Printf("sign_p1_b64 = %s \n",sign_p1_b64)

	//TODO:  将r和s转asn1 pkcs1格式
	// 将签名拆分为r和s
	rBytes := bytes_sign_p1[32:64]
	sBytes := bytes_sign_p1[96:128]
	r_bigint := new(big.Int).SetBytes(rBytes)
	s_bigint := new(big.Int).SetBytes(sBytes)
	sign_p1_asn1, _ := asn1.Marshal(sm2Signature{r_bigint, s_bigint})
	sign_p1_asn1_b64 := base64.StdEncoding.EncodeToString(sign_p1_asn1)
	fmt.Printf("sign_p1_asn1_b64 = %s \n", sign_p1_asn1_b64)

	retHex := strconv.FormatInt(int64(ret), 16)
	if ret == 0 {
		fmt.Printf("15. %s ret: [%d = %s], sign_p1 = %v \n", fn_name, ret, retHex, bytes_sign_p1)
	} else {
		fmt.Printf("\033[31m15. %s ret: [%d = %s], sign_p1 = %v \033[0m \n", fn_name, ret, retHex, bytes_sign_p1)
	}

	return bytes_sign_p1
}

// 16. SKF_ECCVerify
func verify_hash(libc uintptr, hdev int64, pubkey []byte, hash_32 []byte, bytes_sign_p1 []byte) int64 {
	var fn_name = "SKF_ECCVerify"
	var fn func(uintptr, uintptr, uintptr, uintptr, uintptr) int64
	purego.RegisterLibFunc(&fn, libc, fn_name)

	var hash_len int64 = int64(len(hash_32))

	ret := fn(
		uintptr(hdev),
		uintptr(unsafe.Pointer(&pubkey[0])),
		uintptr(unsafe.Pointer(&hash_32[0])),
		uintptr(hash_len),
		uintptr(unsafe.Pointer(&bytes_sign_p1[0])),
	)

	retHex := strconv.FormatInt(int64(ret), 16)
	if ret == 0 {
		fmt.Printf("16. %s ret: [%d = %s] \n", fn_name, ret, retHex)
	} else {
		fmt.Printf("\033[31m16. %s ret: [%d = %s] \033[0m \n", fn_name, ret, retHex)
	}

	return int64(ret)
}

// 17. SKF_ClearSecureState
func clear_pin(libc uintptr, addr_happ int64) int64 {
	var fn_name = "SKF_ClearSecureState"
	var fn func(uintptr) int64
	purego.RegisterLibFunc(&fn, libc, fn_name)

	ret := fn(
		uintptr(addr_happ),
	)

	retHex := strconv.FormatInt(int64(ret), 16)
	if ret == 0 {
		fmt.Printf("17. %s ret: [%d = %s] \n", fn_name, ret, retHex)
	} else {
		fmt.Printf("\033[31m17. %s ret: [%d = %s] \033[0m \n", fn_name, ret, retHex)
	}
	return int64(ret)
}

// SKF_CloseHandle 关闭会话密钥、杂凑、消息认证码句柄。
func close_handle(libc uintptr, handle int64) int64 {
	var fn_name = "SKF_CloseHandle"
	var fn func(uintptr) int64
	purego.RegisterLibFunc(&fn, libc, fn_name)

	ret := fn(
		uintptr(handle),
	)

	ret_hex := strconv.FormatInt(int64(ret), 16)
	if ret == 0 {
		fmt.Printf("13. %s ret: [%d = %s]  \n", fn_name, ret, ret_hex)
	} else {
		fmt.Printf("\033[31m13. %s ret: [%d = %s] \033[0m \n", fn_name, ret, ret_hex)
	}
	return ret
}

func close_container(libc uintptr, hcont int64) int64 {
	var fn_name = "SKF_CloseContainer"
	var fn func(uintptr) int64
	purego.RegisterLibFunc(&fn, libc, fn_name)

	ret := fn(
		uintptr(hcont),
	)

	ret_hex := strconv.FormatInt(int64(ret), 16)
	if ret == 0 {
		fmt.Printf("13. %s ret: [%d = %s]  \n", fn_name, ret, ret_hex)
	} else {
		fmt.Printf("\033[31m13. %s ret: [%d = %s] \033[0m \n", fn_name, ret, ret_hex)
	}
	return ret
}

func close_application(libc uintptr, happ int64) int64 {
	var fn_name = "SKF_CloseApplication"
	var fn func(uintptr) int64
	purego.RegisterLibFunc(&fn, libc, fn_name)

	ret := fn(
		uintptr(happ),
	)

	ret_hex := strconv.FormatInt(int64(ret), 16)
	if ret == 0 {
		fmt.Printf("13. %s ret: [%d = %s]  \n", fn_name, ret, ret_hex)
	} else {
		fmt.Printf("\033[31m13. %s ret: [%d = %s] \033[0m \n", fn_name, ret, ret_hex)
	}
	return ret
}

func close_dev(libc uintptr, hdev int64) int64 {
	var fn_name = "SKF_DisConnectDev"
	var fn func(uintptr) int64
	purego.RegisterLibFunc(&fn, libc, fn_name)

	ret := fn(
		uintptr(hdev),
	)

	ret_hex := strconv.FormatInt(int64(ret), 16)
	if ret == 0 {
		fmt.Printf("13. %s ret: [%d = %s]  \n", fn_name, ret, ret_hex)
	} else {
		fmt.Printf("\033[31m13. %s ret: [%d = %s] \033[0m \n", fn_name, ret, ret_hex)
	}
	return ret
}

func monitor_quit(libc uintptr, phcont int64, happ int64, hdev int64, dev_name string) {
	// 创建一个channel来接收操作系统信号
	sigs := make(chan os.Signal, 1)
	signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)

	// 启动一个goroutine来监听信号
	go func() {
		sig := <-sigs
		fmt.Println()
		fmt.Println(sig, "received")
		// 在退出程序之前执行一些操作
		fmt.Println("cleaning up...")
		close_container(libc, phcont)
		close_application(libc, happ)
		close_dev(libc, hdev)

		// 执行完操作后退出程序
		os.Exit(0)
	}()

	// 主函数可以继续执行其他操作
	fmt.Println("doing some work...")
	// 创建一个带有中断信号的channel
	interrupt := make(chan struct{})
	for {
		select {
		case <-interrupt:
			fmt.Printf(" 接收到中断信号,退出循环\n")
		default:
			code_event := monitor_dev(libc, dev_name)
			fmt.Printf("检测到ukey插拔事件:%d \n", code_event)
			time.Sleep(time.Second)
		}
	}

	// 等待信号
	<-sigs
}

func main() {
	/**
	0 SKF_EnumDev 设备编号长度= [34]
	0 SKF_EnumDev 设备编号= [TW08220608000002]
	0 SKF_ConnectDev 设备hdev= [native@0x1000]
	0 SKF_EnumApplication app name= [GM3000RSA-TW]
	a000005 = 无效的句柄
	a000006 = 无效的参数
	a00001a = Hash值不相等 (验证签名失败)
	a00002e = 应用不存在
	a000023 = 设备已移除 (没插key)
	a000024 = PIN不正确
	a000025 = PIN被锁死
	a000027 = PIN长度错误
	a00002d = 用户没有登录
	*/

	skf_test()
	//skf_verify_pin_test()

	//ret_hex := strconv.FormatInt(int64(167772162), 16)
	//fmt.Printf("ret_hex = %s \n", ret_hex)

	if false {
		var input string
		fmt.Println("Press any key to continue...")
		_, _ = fmt.Scanln(&input)
		fmt.Println("Continuing...")
	}

}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值