package com.sunyard.chsm.sdf.adapter;

import com.sunyard.chsm.sdf.context.AlgId;
import com.sunyard.chsm.sdf.model.DeviceInfo;
import com.sunyard.chsm.sdf.model.EccCipher;
import com.sunyard.chsm.sdf.model.EccKey;
import com.sunyard.chsm.sdf.model.EccPriKey;
import com.sunyard.chsm.sdf.model.EccPubKey;
import com.sunyard.chsm.sdf.model.EccSignature;

/**
 * @author liulu
 * @since 2024/11/4
 */
public interface SdfApiAdapter {

    /**
     * 打开设备
     *
     * @return 设 备 句 柄
     */
    String openDevice();

    /**
     * 关闭设备
     *
     * @param deviceHandle 已打开的设备句柄
     * @return 0 成功;   非0 失败,返回错误代码
     */
    boolean closeDevice(String deviceHandle);

    /**
     * 创建会话
     *
     * @return 与密码设备建立的新会话句柄
     */
    String openSession(String deviceHandle);

    void closeSession(String sessionHandle);

    /**
     * 获取设备信息
     *
     * @param sessionHandle 与设备建立的会话句柄
     * @return 设备能力描述信息，内容及格式见设备信息定义
     */
    DeviceInfo getDeviceInfo(String sessionHandle);

    /**
     * 产生随机数
     *
     * @param uiLength 随机数长度
     * @return pucRandom 返回随机数
     */
    byte[] generateRandom(String sessionHandle, int uiLength);

    /**
     * 导出ECC加密公钥
     *
     * @param uiKeyIndex 密码设备存储的ECC密钥对索引值
     * @return pucPublicKeyEcc 返回ECC加密公钥x+y
     */
    EccPubKey exportEncPublicKeyECC(String sessionHandle, int uiKeyIndex);

    /**
     * 产生ECC密钥对并输出 密钥模长 256
     *
     * @param alg       指定算法标识 SGD_SM2_1
     * @return pucPublicKeyEcc 返回公钥 | pucPrivateKeyEcc 返回私钥
     */
    EccKey generateKeyPairECC(String sessionHandle, AlgId alg);

    boolean getPrivateKeyAccessRight(String hSessionHandle, int uiKeyIndex, byte[] pucPassword);

    /**
     * 导入会话密钥并用内部ECC私钥解密
     *
     * @param uiIskIndex 密码设备内部存储加密私钥的索引值，对应于加密时的公钥
     * @param eccCipher  缓冲区指针，用于存放返回的密钥密文
     * @return phKeyHandle 返回密钥句柄
     */
    String importKeyWithISKECC(String sessionHandle, int uiIskIndex, EccCipher eccCipher);

    /**
     * 导入明文会话密钥
     *
     * @param sessionHandle 与设备建立的会话句柄
     * @param pucKey        缓冲区指针，用于存放输入的密钥密文
     * @return phKeyHandle 返回密钥句柄
     */
    String importKey(String sessionHandle, byte[] pucKey);

    /**
     * 销毁会话密钥
     *
     * @param hKeyHandle 密钥句柄
     * @return 0 成功;   非0 失败,返回错误代码
     */
    int destroyKey(String sessionHandle, String hKeyHandle);

    EccCipher exchangeDigitEnvelopeBaseOnECC(String sessionHandle, int uiKeyIndex, EccPubKey pubKey, EccCipher pucEncDateIn);

    /**
     * 外部密钥ECC签名
     *
     * @param privateKey ECC私钥
     * @param pucData    缓冲区指针，用于存放外部输入的数据
     * @return pucSignature 返回签名值数据
     */
    EccSignature externalSignECC(String sessionHandle, EccPriKey privateKey, byte[] pucData);

    /**
     * 外部密钥ECC验证
     *
     * @param publicKey    ECC公钥
     * @param pucData      缓冲区指针，用于存放外部输入的数据
     * @param pucSignature 缓冲区指针，用于存放输入的签名值数据
     * @return 0 成功;   非0 失败,返回错误代码
     */
    boolean externalVerifyECC(String sessionHandle, EccPubKey publicKey, byte[] pucData, EccSignature pucSignature);

    /**
     * 外部密钥ECC公钥加密
     *
     * @param pubKey  外部ECC公钥结构
     * @param pucData 缓冲区指针，用于存放外部输入的数据
     * @return pucEncData 返回数据密文
     */
    EccCipher externalEncryptECC(String sessionHandle, EccPubKey pubKey, byte[] pucData);

    /**
     * 外部密钥ECC私钥解密
     *
     * @param pucPrivateKeyEcc 外部ECC私钥结构
     * @param pucEncData       缓冲区指针，用于存放输入的数据密文
     * @return pucData 返回数据明文
     */
    byte[] externalDecryptECC(String sessionHandle, EccPriKey pucPrivateKeyEcc, EccCipher pucEncData);

    /**
     * 对称加密
     *
     * @param sessionHandle 与设备建立的会话句柄
     * @param keyHandle     指定的密钥句柄
     * @param alg           算法标识，指定对称加密算法 SGD_SMS4_ECB
     * @param pucIv         IV数据
     * @param pucData       数据明文
     * @return 数据密文
     */
    byte[] symEncrypt(String sessionHandle, String keyHandle, AlgId alg, byte[] pucIv, byte[] pucData);

    /**
     * 对称解密
     *
     * @param sessionHandle 与设备建立的会话句柄
     * @param keyHandle     指定的密钥句柄
     * @param alg           算法标识，指定对称加密算法 SGD_SMS4_ECB
     * @param pucIv         IV数据
     * @param pucEncData    数据密文
     * @return 数据明文
     */
    byte[] symDecrypt(String sessionHandle, String keyHandle, AlgId alg, byte[] pucIv, byte[] pucEncData);

    /**
     * @param sessionHandle 与设备建立的会话句柄
     * @param keyHandle     指定的密钥句柄
     * @param uiAlg         算法标识，指定MAC算法 SGD_SMS4_MAC
     * @param pucIv         IV数据
     * @param pucData       数据明文
     * @return MAC值
     */
    byte[] calculateMAC(String sessionHandle, String keyHandle, AlgId uiAlg, byte[] pucIv, byte[] pucData);

    /**
     * 杂凑运算初始化
     *
     * @param sessionHandle 与设备建立的会话句柄
     * @param alg           当前杂凑算法标识 SGD_SM3
     * @param pucPublicKey  签名者公钥，当uiAlgID为SGD_SM3时有效
     * @param pucID         签名者的ID值，当uiAlgID为SGD_SM3时有效
     * @return 0 成功;   非0 失败,返回错误代码
     */
    int hashInit(String sessionHandle, AlgId alg, EccPubKey pucPublicKey, byte[] pucID);

    /**
     * 多包杂凑运算
     *
     * @param sessionHandle sessionHandle
     * @param pucData       数据明文
     * @return 0 成功;   非0 失败,返回错误代码
     */
    int hashUpdate(String sessionHandle, byte[] pucData);

    /**
     * 杂凑运算结束
     *
     * @param sessionHandle 与设备建立的会话句柄
     * @return 杂凑数据
     */
    byte[] hashFinish(String sessionHandle);

}
