Skip to content

Commit

Permalink
smx509: improve test coverage
Browse files Browse the repository at this point in the history
  • Loading branch information
emmansun committed Jun 13, 2024
1 parent 6ba367a commit 1ef4cf9
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 6 deletions.
25 changes: 25 additions & 0 deletions docs/sm2.md
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,31 @@ func ExamplePrivateKey_Decrypt() {
### 关于点到字节串的转换
我没有找到到哪个文档写有固定64字节转换的。从国家密码管理局2010年版的《SM2椭圆曲线公钥密码算法》,到2012年的GM/T 0003-2012 SM2椭圆曲线公钥密码算法,再到GB/T 32918-2016 信息安全技术 SM2椭圆曲线公钥密码算法,都在第一部分第四章的“点到字节串的转换”有详细说明。这也符合《SEC 1: Elliptic Curve Cryptography》(May 21, 2009 Version 2.0)中2.3.3 Elliptic-Curve-Point-to-Octet-String Conversion的描述。

#### 来自AI的问答
**问: Why some crypto implementations of EC point to octet string conversion without form indicator?**
**答:** In Elliptic Curve Cryptography (ECC), the conversion of an elliptic curve point to an octet string can be done in several ways, typically either in compressed or uncompressed form. The form indicator (also known as the prefix) is used to denote whether the point is represented in its compressed or uncompressed form.

However, some implementations might choose to omit the form indicator for a few reasons:

1. **Simplicity**: Omitting the form indicator simplifies the implementation, as there's no need to handle different forms of point representation.

2. **Assumed Knowledge**: If it's known in advance that all points will be in a certain form (e.g., all points are always uncompressed), the form indicator might be deemed unnecessary.

3. **Compatibility**: Not all systems or libraries support both forms of point representation. To ensure maximum compatibility, an implementation might choose to always use one form and thus omit the form indicator.

4. **Security**: In some cases, to prevent certain types of attacks that rely on the form of the point, the form indicator might be omitted.

Please note that these are general reasons and the specific reason can vary depending on the exact context and the specific cryptographic protocol or system in use.

**问:Won't this cause interoperability issues?**
**答:** Yes, you're correct. Omitting the form indicator in the conversion of an elliptic curve point to an octet string can indeed cause interoperability issues.

When systems need to interoperate, they must agree on a common format for data exchange. If one system encodes elliptic curve points without a form indicator and another system expects the form indicator to be present, they won't be able to correctly interpret each other's data.

This is why standards like those defined by the SEC (Standards for Efficient Cryptography) specify the use of a form indicator. For example, the SEC 1 standard specifies that the form indicator should be 0x04 for uncompressed points and 0x02 or 0x03 for compressed points.

So, while omitting the form indicator might simplify the implementation or provide other benefits within a closed system, it can hinder interoperability with other systems. It's generally best to follow established standards when encoding and decoding cryptographic data to ensure maximum compatibility.

### 性能
**v0.27.0**开始,对大数据量的加解密做了优化处理,尤其是KDF并行计算。详情请参考[SM2加解密性能](https://github.com/emmansun/gmsm/wiki/SM2%E5%8A%A0%E8%A7%A3%E5%AF%86%E6%80%A7%E8%83%BD)

Expand Down
13 changes: 7 additions & 6 deletions smx509/csr_rsp.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ import (

// CSRResponse represents the response of a certificate signing request.
type CSRResponse struct {
SignCerts []*Certificate
SignCerts []*Certificate
EncryptPrivateKey *sm2.PrivateKey
EncryptCerts []*Certificate
EncryptCerts []*Certificate
}

type tbsCSRResponse struct {
Expand All @@ -31,6 +31,7 @@ type rawCertificates struct {
}

// ParseCSRResponse parses a CSRResponse from DER format.
// We do NOT verify the cert chain here, it's the caller's responsibility.
func ParseCSRResponse(signPrivateKey *sm2.PrivateKey, der []byte) (CSRResponse, error) {
result := CSRResponse{}
resp := &tbsCSRResponse{}
Expand All @@ -43,9 +44,9 @@ func ParseCSRResponse(signPrivateKey *sm2.PrivateKey, der []byte) (CSRResponse,
return result, errors.New("smx509: invalid sign certificates")
}

// further check sign public key against the private key
// check sign public key against the private key
if !signPrivateKey.PublicKey.Equal(signCerts[0].PublicKey) {
return result, errors.New("smx509: sign public key mismatch")
return result, errors.New("smx509: sign cert public key mismatch")
}

var encPrivateKey *sm2.PrivateKey
Expand All @@ -63,7 +64,7 @@ func ParseCSRResponse(signPrivateKey *sm2.PrivateKey, der []byte) (CSRResponse,
}
}

// further check the public key of the encrypt certificate
// check the public key of the encrypt certificate
if encPrivateKey != nil && len(encryptCerts) == 0 {
return result, errors.New("smx509: missing encrypt certificate")
}
Expand All @@ -88,7 +89,7 @@ func MarshalCSRResponse(signCerts []*Certificate, encryptPrivateKey *sm2.Private
return nil, errors.New("smx509: invalid sign public key")
}

// further check the public key of the encrypt certificate
// check the public key of the encrypt certificate
if encryptPrivateKey != nil && len(encryptCerts) == 0 {
return nil, errors.New("smx509: missing encrypt certificate")
}
Expand Down
15 changes: 15 additions & 0 deletions smx509/csr_rsp_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -152,4 +152,19 @@ func TestMarshalCSRResponse(t *testing.T) {
if resp.EncryptCerts != nil {
t.Errorf("Unexpected encrypt certs")
}

_, err = smx509.MarshalCSRResponse(nil, nil, nil)
if err == nil || err.Error() != "smx509: no sign certificate" {
t.Errorf("Unexpected error: %v", err)
}

_, err = smx509.MarshalCSRResponse([]*smx509.Certificate{pairs[0].Certificate, pairs[2].Certificate}, encPrivKey, nil)
if err == nil || err.Error() != "smx509: missing encrypt certificate" {
t.Errorf("Unexpected error: %v", err)
}

_, err = smx509.MarshalCSRResponse([]*smx509.Certificate{pairs[0].Certificate, pairs[2].Certificate}, encPrivKey, []*smx509.Certificate{pairs[2].Certificate})
if err == nil || err.Error() != "smx509: encrypt key pair mismatch" {
t.Errorf("Unexpected error: %v", err)
}
}

0 comments on commit 1ef4cf9

Please sign in to comment.