refactor: 重构trustlog-sdk目录结构到trustlog/go-trustlog

- 将所有trustlog-sdk文件移动到trustlog/go-trustlog/目录
- 更新README中所有import路径从trustlog-sdk改为go-trustlog
- 更新cookiecutter配置文件中的项目名称
- 更新根目录.lefthook.yml以引用新位置的配置
- 添加go.sum文件到版本控制
- 删除过时的示例文件

这次重构与trustlog-server保持一致的目录结构,
为未来支持多语言SDK(Python、Java等)预留空间。
This commit is contained in:
ryan
2025-12-22 13:37:57 +08:00
commit d313449c5c
87 changed files with 20622 additions and 0 deletions

501
api/model/envelope.go Normal file
View File

@@ -0,0 +1,501 @@
package model
import (
"bytes"
"errors"
"fmt"
"go.yandata.net/iod/iod/trustlog-sdk/api/logger"
"go.yandata.net/iod/iod/trustlog-sdk/internal/helpers"
)
// Envelope 包装序列化后的数据,包含元信息和报文体。
// 用于 Trustlog 接口类型的序列化和反序列化。
type Envelope struct {
ProducerID string // 日志提供者ID
Signature []byte // 签名(根据客户端密钥与指定算法进行签名,二进制格式)
Body []byte // CBOR序列化的报文体
}
// EnvelopeConfig 序列化配置。
type EnvelopeConfig struct {
Signer Signer // 签名器,用于签名和验签
}
// VerifyConfig 验签配置。
type VerifyConfig struct {
Signer Signer // 签名器,用于验签
}
// NewEnvelopeConfig 创建Envelope配置。
func NewEnvelopeConfig(signer Signer) EnvelopeConfig {
log := logger.GetGlobalLogger()
log.Debug("Creating new EnvelopeConfig",
"signerType", fmt.Sprintf("%T", signer),
)
return EnvelopeConfig{
Signer: signer,
}
}
// NewSM2EnvelopeConfig 创建使用SM2签名的Envelope配置。
// 便捷方法用于快速创建SM2签名器配置。
func NewSM2EnvelopeConfig(privateKey, publicKey []byte) EnvelopeConfig {
log := logger.GetGlobalLogger()
log.Debug("Creating new SM2 EnvelopeConfig",
"privateKeyLength", len(privateKey),
"publicKeyLength", len(publicKey),
)
return EnvelopeConfig{
Signer: NewSM2Signer(privateKey, publicKey),
}
}
// NewVerifyConfig 创建验签配置。
func NewVerifyConfig(signer Signer) VerifyConfig {
log := logger.GetGlobalLogger()
log.Debug("Creating new VerifyConfig",
"signerType", fmt.Sprintf("%T", signer),
)
return VerifyConfig{
Signer: signer,
}
}
// NewSM2VerifyConfig 创建使用SM2签名的验签配置。
// 便捷方法用于快速创建SM2签名器验签配置。
// 注意验签只需要公钥但SM2Signer需要同时提供私钥和公钥私钥可以为空
func NewSM2VerifyConfig(publicKey []byte) VerifyConfig {
return VerifyConfig{
Signer: NewSM2Signer(nil, publicKey),
}
}
//
// ===== Envelope 序列化/反序列化 =====
//
// MarshalEnvelope 将 Envelope 序列化为 TLV 格式Varint长度编码
// 格式:[字段1长度][字段1值:producerID][字段2长度][字段2值:签名][字段3长度][字段3值:CBOR报文体]。
func MarshalEnvelope(env *Envelope) ([]byte, error) {
log := logger.GetGlobalLogger()
log.Debug("Marshaling envelope to TLV format")
if env == nil {
log.Error("Envelope is nil")
return nil, errors.New("envelope cannot be nil")
}
buf := new(bytes.Buffer)
writer := helpers.NewTLVWriter(buf)
log.Debug("Writing producerID to TLV",
"producerID", env.ProducerID,
)
if err := writer.WriteStringField(env.ProducerID); err != nil {
log.Error("Failed to write producerID",
"error", err,
"producerID", env.ProducerID,
)
return nil, fmt.Errorf("failed to write producerID: %w", err)
}
log.Debug("Writing signature to TLV",
"signatureLength", len(env.Signature),
)
if err := writer.WriteField(env.Signature); err != nil {
log.Error("Failed to write signature",
"error", err,
"signatureLength", len(env.Signature),
)
return nil, fmt.Errorf("failed to write signature: %w", err)
}
log.Debug("Writing body to TLV",
"bodyLength", len(env.Body),
)
if err := writer.WriteField(env.Body); err != nil {
log.Error("Failed to write body",
"error", err,
"bodyLength", len(env.Body),
)
return nil, fmt.Errorf("failed to write body: %w", err)
}
result := buf.Bytes()
log.Debug("Envelope marshaled successfully",
"producerID", env.ProducerID,
"totalLength", len(result),
)
return result, nil
}
// UnmarshalEnvelope 完整反序列化:读取所有字段。
// 解析完整的Envelope结构包括所有元数据和Body。
// 为了向后兼容如果遇到旧格式包含原hash字段会自动跳过该字段。
func UnmarshalEnvelope(data []byte) (*Envelope, error) {
log := logger.GetGlobalLogger()
log.Debug("Unmarshaling envelope from TLV format",
"dataLength", len(data),
)
if len(data) == 0 {
log.Error("Data is empty")
return nil, errors.New("data is empty")
}
r := bytes.NewReader(data)
reader := helpers.NewTLVReader(r)
log.Debug("Reading producerID from TLV")
producerID, err := reader.ReadStringField()
if err != nil {
log.Error("Failed to read producerID",
"error", err,
)
return nil, fmt.Errorf("failed to read producerID: %w", err)
}
log.Debug("ProducerID read successfully",
"producerID", producerID,
)
// 读取第一个字段可能是原hash或签名
log.Debug("Reading field 1 from TLV")
field1, err := reader.ReadField()
if err != nil {
log.Error("Failed to read field 1",
"error", err,
)
return nil, fmt.Errorf("failed to read field 1: %w", err)
}
log.Debug("Field 1 read successfully",
"field1Length", len(field1),
)
// 读取第二个字段可能是签名或body
log.Debug("Reading field 2 from TLV")
field2, err := reader.ReadField()
if err != nil {
log.Error("Failed to read field 2",
"error", err,
)
return nil, fmt.Errorf("failed to read field 2: %w", err)
}
log.Debug("Field 2 read successfully",
"field2Length", len(field2),
)
// 尝试读取第三个字段来判断格式
log.Debug("Attempting to read field 3 to determine format")
field3, err := reader.ReadField()
if err == nil {
// 有第三个字段说明是旧格式producerID, originalHash, encryptedHash, body
// field1 = originalHash, field2 = encryptedHash/signature, field3 = body
log.Debug("Detected old format (with originalHash)",
"producerID", producerID,
"signatureLength", len(field2),
"bodyLength", len(field3),
)
return &Envelope{
ProducerID: producerID,
Signature: field2,
Body: field3,
}, nil
}
// 没有第三个字段说明是新格式producerID, signature, body
// field1 = signature, field2 = body
log.Debug("Detected new format (without originalHash)",
"producerID", producerID,
"signatureLength", len(field1),
"bodyLength", len(field2),
)
return &Envelope{
ProducerID: producerID,
Signature: field1,
Body: field2,
}, nil
}
//
// ===== 部分反序列化(无需反序列化全部报文) =====
//
// UnmarshalEnvelopeProducerID 部分反序列化只读取字段1producerID
// 用于快速获取producerID而不解析整个Envelope。
func UnmarshalEnvelopeProducerID(data []byte) (string, error) {
if len(data) == 0 {
return "", errors.New("data is empty")
}
r := bytes.NewReader(data)
reader := helpers.NewTLVReader(r)
producerID, err := reader.ReadStringField()
if err != nil {
return "", fmt.Errorf("failed to read producerID: %w", err)
}
return producerID, nil
}
// UnmarshalEnvelopeSignature 部分反序列化读取字段1、2producerID, 签名)。
// 用于获取签名信息而不解析整个Body。
// 为了向后兼容如果遇到旧格式包含原hash字段会自动跳过该字段。
func UnmarshalEnvelopeSignature(data []byte) (string, []byte, error) {
if len(data) == 0 {
return "", nil, errors.New("data is empty")
}
r := bytes.NewReader(data)
reader := helpers.NewTLVReader(r)
producerID, err := reader.ReadStringField()
if err != nil {
return "", nil, fmt.Errorf("failed to read producerID: %w", err)
}
// 读取第一个字段可能是原hash或签名
field1, err := reader.ReadField()
if err != nil {
return "", nil, fmt.Errorf("failed to read field 1: %w", err)
}
// 读取第二个字段可能是签名或body
field2, err := reader.ReadField()
if err != nil {
return "", nil, fmt.Errorf("failed to read field 2: %w", err)
}
// 尝试读取第三个字段来判断格式
_, err = reader.ReadField()
if err == nil {
// 有第三个字段说明是旧格式producerID, originalHash, encryptedHash/signature, body
// field1 = originalHash, field2 = signature
return producerID, field2, nil
}
// 没有第三个字段说明是新格式producerID, signature, body
// field1 = signature
return producerID, field1, nil
}
//
// ===== Trustlog 序列化/反序列化 =====
//
// MarshalTrustlog 序列化 Trustlog 为 Envelope 格式。
// Trustlog 实现了 Trustlog 接口,自动提取 producerID 并使用 Canonical CBOR 编码。
func MarshalTrustlog(t Trustlog, config EnvelopeConfig) ([]byte, error) {
log := logger.GetGlobalLogger()
log.Debug("Marshaling Trustlog to Envelope format",
"trustlogType", fmt.Sprintf("%T", t),
)
if t == nil {
log.Error("Trustlog is nil")
return nil, errors.New("trustlog cannot be nil")
}
producerID := t.GetProducerID()
if producerID == "" {
log.Error("ProducerID is empty")
return nil, errors.New("producerID cannot be empty")
}
log.Debug("ProducerID extracted",
"producerID", producerID,
)
// 1. 序列化CBOR报文体使用 Trustlog 的 MarshalBinary确保使用 Canonical CBOR
log.Debug("Marshaling trustlog to CBOR binary")
bodyCBOR, err := t.MarshalBinary()
if err != nil {
log.Error("Failed to marshal trustlog to CBOR",
"error", err,
"producerID", producerID,
)
return nil, fmt.Errorf("failed to marshal trustlog: %w", err)
}
log.Debug("Trustlog marshaled to CBOR successfully",
"producerID", producerID,
"bodyLength", len(bodyCBOR),
)
// 2. 计算签名
if config.Signer == nil {
log.Error("Signer is nil")
return nil, errors.New("signer is required")
}
log.Debug("Signing trustlog body",
"producerID", producerID,
"bodyLength", len(bodyCBOR),
)
signature, err := config.Signer.Sign(bodyCBOR)
if err != nil {
log.Error("Failed to sign trustlog body",
"error", err,
"producerID", producerID,
)
return nil, fmt.Errorf("failed to sign data: %w", err)
}
log.Debug("Trustlog body signed successfully",
"producerID", producerID,
"signatureLength", len(signature),
)
// 3. 构建Envelope
env := &Envelope{
ProducerID: producerID,
Signature: signature,
Body: bodyCBOR,
}
// 4. 序列化为TLV格式
log.Debug("Marshaling envelope to TLV format",
"producerID", producerID,
)
return MarshalEnvelope(env)
}
// UnmarshalTrustlog 反序列化 Envelope 为 Trustlog。
// 解析Envelope数据并恢复 Trustlog 结构。
func UnmarshalTrustlog(data []byte, t Trustlog) error {
log := logger.GetGlobalLogger()
log.Debug("Unmarshaling Envelope to Trustlog",
"trustlogType", fmt.Sprintf("%T", t),
"dataLength", len(data),
)
if t == nil {
log.Error("Trustlog is nil")
return errors.New("trustlog cannot be nil")
}
env, err := UnmarshalEnvelope(data)
if err != nil {
log.Error("Failed to unmarshal envelope",
"error", err,
)
return err
}
log.Debug("Envelope unmarshaled successfully",
"producerID", env.ProducerID,
"bodyLength", len(env.Body),
)
// 使用 Trustlog 的 UnmarshalBinary 反序列化
log.Debug("Unmarshaling trustlog body from CBOR",
"producerID", env.ProducerID,
)
if errUnmarshal := t.UnmarshalBinary(env.Body); errUnmarshal != nil {
log.Error("Failed to unmarshal trustlog body",
"error", errUnmarshal,
"producerID", env.ProducerID,
)
return fmt.Errorf("failed to unmarshal trustlog body: %w", errUnmarshal)
}
log.Debug("Trustlog unmarshaled successfully",
"producerID", env.ProducerID,
)
return nil
}
//
// ===== Operation 序列化/反序列化 =====
//
// MarshalOperation 序列化 Operation 为 Envelope 格式。
func MarshalOperation(op *Operation, config EnvelopeConfig) ([]byte, error) {
return MarshalTrustlog(op, config)
}
// UnmarshalOperation 反序列化 Envelope 为 Operation。
func UnmarshalOperation(data []byte) (*Operation, error) {
var op Operation
if err := UnmarshalTrustlog(data, &op); err != nil {
return nil, err
}
return &op, nil
}
//
// ===== Record 序列化/反序列化 =====
//
// MarshalRecord 序列化 Record 为 Envelope 格式。
func MarshalRecord(record *Record, config EnvelopeConfig) ([]byte, error) {
return MarshalTrustlog(record, config)
}
// UnmarshalRecord 反序列化 Envelope 为 Record。
func UnmarshalRecord(data []byte) (*Record, error) {
var record Record
if err := UnmarshalTrustlog(data, &record); err != nil {
return nil, err
}
return &record, nil
}
//
// ===== 验证 =====
//
// VerifyEnvelope 验证Envelope的完整性使用EnvelopeConfig
// 验证签名是否匹配,确保数据未被篡改。
// 如果验证成功返回解析后的Envelope结构体指针如果验证失败返回错误。
func VerifyEnvelope(data []byte, config EnvelopeConfig) (*Envelope, error) {
if config.Signer == nil {
return nil, errors.New("signer is required for verification")
}
verifyConfig := VerifyConfig(config)
return VerifyEnvelopeWithConfig(data, verifyConfig)
}
// VerifyEnvelopeWithConfig 验证Envelope的完整性使用VerifyConfig
// 验证签名是否匹配,确保数据未被篡改。
// 如果验证成功返回解析后的Envelope结构体指针如果验证失败返回错误。
func VerifyEnvelopeWithConfig(data []byte, config VerifyConfig) (*Envelope, error) {
log := logger.GetGlobalLogger()
log.Debug("Verifying envelope",
"dataLength", len(data),
)
if config.Signer == nil {
log.Error("Signer is nil")
return nil, errors.New("signer is required for verification")
}
env, err := UnmarshalEnvelope(data)
if err != nil {
log.Error("Failed to unmarshal envelope",
"error", err,
)
return nil, fmt.Errorf("failed to unmarshal envelope: %w", err)
}
log.Debug("Envelope unmarshaled for verification",
"producerID", env.ProducerID,
"bodyLength", len(env.Body),
"signatureLength", len(env.Signature),
)
// 验证签名
log.Debug("Verifying signature",
"producerID", env.ProducerID,
)
valid, err := config.Signer.Verify(env.Body, env.Signature)
if err != nil {
log.Error("Failed to verify signature",
"error", err,
"producerID", env.ProducerID,
)
return nil, fmt.Errorf("failed to verify signature: %w", err)
}
if !valid {
log.Warn("Signature verification failed",
"producerID", env.ProducerID,
)
return nil, errors.New("signature verification failed")
}
log.Debug("Envelope verified successfully",
"producerID", env.ProducerID,
)
return env, nil
}