环境: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...")
}
}