Compare commits

..

6 Commits

Author SHA1 Message Date
Sun Yimin
7b75b6b26b
update disclaimer 2025-04-18 08:50:39 +08:00
Sun Yimin
5aacbc2011
Merge pull request #324 from hrimfaxi/main
sm9: Prevent PublicKey() returning nil after unmarshaling master priavate key
2025-04-15 17:31:55 +08:00
YuanHongYe
fe532e12b4 sm9: Prevent PublicKey() returning nil after unmarshaling master private key
During unmarshaling of SignMasterPrivateKey and EncryptMasterPrivateKey,
now generate the corresponding public key.
This ensures that PublicKey() does not return nil.

Test cases included to validate the changes.

Signed-off-by: YuanHongYe <yuanhongye@chinatelecom.cn>
2025-04-15 17:01:27 +08:00
Sun Yimin
1dc82305e4
Merge pull request #323 from emmansun/dependabot/go_modules/golang.org/x/crypto-0.37.0
build(deps): bump golang.org/x/crypto from 0.36.0 to 0.37.0
2025-04-08 09:28:54 +08:00
dependabot[bot]
ed256a9ea3
build(deps): bump golang.org/x/crypto from 0.36.0 to 0.37.0
Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.36.0 to 0.37.0.
- [Commits](https://github.com/golang/crypto/compare/v0.36.0...v0.37.0)

---
updated-dependencies:
- dependency-name: golang.org/x/crypto
  dependency-version: 0.37.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-08 00:52:59 +00:00
Sun Yimin
d8c6788e8f
sm2, sm2ec: remove useless codes since go 1.19 2025-04-07 13:10:09 +08:00
9 changed files with 62 additions and 62 deletions

View File

@ -1,23 +1,27 @@
# 免责
# 免责
## 声明
## 版权声明
本项目(gmsm)代码的版权归[Sun Yimin](mailto:emman.sun@foxmail.com)所有,并按照[MIT](https://github.com/emmansun/gmsm/blob/main/LICENSE)进行分发。使用本项目的代码时,必须遵守相应的许可证条款。
任何直接或间接因使用本项目(gmsm)的任何内容所导致的全部后果与本项目(gmsm)的开发者无关,若使用者无法对使用本项目(gmsm)后的任何后果负责,请不要使用本项目(gmsm)的任何内容。若该项目(gmsm)的任何内容侵犯了您的法律权益,请联系 emman.sun@foxmail.com作者会第一时间删除侵权内容。
## 免责条款
## 认证
1. **无担保声明**
本项目以“原样”提供,不提供任何形式的明示或暗示担保,包括但不限于对适销性、特定用途适用性和非侵权性的担保。
本项目(gmsm)**没有**经过相关机构资质认证。
2. **责任限制**
对于因使用或无法使用本项目代码而导致的任何直接、间接、偶然、特殊、典型或惩罚性损害(包括但不限于数据丢失、利润损失、业务中断等),项目作者或贡献者概不负责。
## 保证
3. **使用风险**
使用本项目代码的风险由使用者自行承担。使用者在使用本项目时,应自行评估代码的适用性和安全性,并根据实际需求进行测试和调整。
本项目(gmsm)不提供任何形式的保证。所有与使用本项目(gmsm)软件库及源代码相关的直接或间接风险均由用户自行承担。本项目(gmsm)提供的所有代码,并不对性能、适用性、适销性及其他方面提供任何保证。
4. **第三方依赖**
本项目可能依赖于第三方库或服务,这些库或服务的使用应遵守其各自的许可证条款。项目作者或贡献者不对第三方库或服务的稳定性、安全性或合法性负责。
本项目(gmsm)实现的内容可能包含不准确性或错误,我们不对内容的准确性进行保证。如果您发现本项目(gmsm)内容包含错误,请直接提交错误至[issue tracker](https://github.com/emmansun/gmsm/issues),或者提交代码至[pull requests](https://github.com/emmansun/gmsm/pulls)。
5. **法律合规**
使用本项目代码时,使用者应确保遵守所在国家或地区的法律法规。如因使用本项目代码而违反相关法律,使用者需自行承担法律责任。
## 您的行为
6. **产品认证**
本项目(gmsm)**没有**经过相关机构(包括但不限于**国家密码管理局商用密码检测中心**)认证,也不承诺会进行相关认证工作。
当您以任何方式使用本项目(gmsm)软件库及源代码时,说明您已经同意并接受本页面的所有信息。
## 联系方式
联系邮箱emman.sun@foxmail.com相关事务请发函至该邮箱
7. **修改与分发**
如果您修改本项目代码并重新分发,请确保保留上述版权声明和免责条款,并明确标注您的修改内容。

View File

@ -104,7 +104,8 @@ SADK 3.2之后的版本支持下列SM2密文格式(encryptedType)
* 0x02/0x03 - C1为压缩点格式具体是C1C3C2还是C1C2C3取决于解密时的选项参数默认为C1C3C2。
### 生成双密钥CSR v0.29.6+
`cfca.CreateCertificateRequest`和CFCA SADK不同调用者需要自行先生成两对密钥对一对用于签名证书一对用于加解密CFCA生成的加密用私钥文件CFCA加密申请者解密
`cfca.CreateCertificateRequest`和CFCA SADK不同调用者需要自行先生成两对密钥对一对用于签名证书一对用于加解密CFCA生成的加密用私钥文件CFCA加密申请者解密。这个方法对应CFCA的`cfca.sadk.util.P10Request.generateDoublePKCS10Request`方法。按我的理解非国密RSA应该不需要支持这种双密钥对机制不过既然**CFCA SADK**支持,本软件库从**v0.30.0**开始也支持。
使用`cfca.ParseEscrowPrivateKey`解析CFCA返回的加密用私钥。
### SM2私钥、证书的解析

4
go.mod
View File

@ -2,6 +2,6 @@ module github.com/emmansun/gmsm
go 1.23.0
require golang.org/x/crypto v0.36.0
require golang.org/x/crypto v0.37.0
require golang.org/x/sys v0.31.0 // indirect
require golang.org/x/sys v0.32.0 // indirect

8
go.sum
View File

@ -1,4 +1,4 @@
golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34=
golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc=
golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik=
golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/crypto v0.37.0 h1:kJNSjF/Xp7kU0iB2Z+9viTPMW4EqqsrywMXLJOOsXSE=
golang.org/x/crypto v0.37.0/go.mod h1:vg+k43peMZ0pUMhYmVAWysMK35e6ioLh3wB8ZCAfbVc=
golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20=
golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=

View File

@ -10,9 +10,9 @@ import (
"math/big"
"strings"
_subtle "github.com/emmansun/gmsm/internal/subtle"
"github.com/emmansun/gmsm/sm2/sm2ec"
"github.com/emmansun/gmsm/sm3"
_subtle "github.com/emmansun/gmsm/internal/subtle"
"golang.org/x/crypto/cryptobyte"
"golang.org/x/crypto/cryptobyte/asn1"
)
@ -392,7 +392,7 @@ func bytesToPoint(curve elliptic.Curve, bytes []byte) (*big.Int, *big.Int, int,
data := make([]byte, 1+byteLen*2)
data[0] = uncompressed
copy(data[1:], bytes[1:1+byteLen*2])
x, y := sm2ec.Unmarshal(curve, data)
x, y := elliptic.Unmarshal(curve, data)
if x == nil || y == nil {
return nil, nil, 0, fmt.Errorf("sm2: point is not on curve %s", curve.Params().Name)
}
@ -404,7 +404,7 @@ func bytesToPoint(curve elliptic.Curve, bytes []byte) (*big.Int, *big.Int, int,
// Make sure it's NIST curve or SM2 P-256 curve
if strings.HasPrefix(curve.Params().Name, "P-") || strings.EqualFold(curve.Params().Name, sm2ec.P256().Params().Name) {
// y² = x³ - 3x + b, prime curves
x, y := sm2ec.UnmarshalCompressed(curve, bytes[:1+byteLen])
x, y := elliptic.UnmarshalCompressed(curve, bytes[:1+byteLen])
if x == nil || y == nil {
return nil, nil, 0, fmt.Errorf("sm2: point is not on curve %s", curve.Params().Name)
}

View File

@ -2,7 +2,6 @@ package sm2ec
import (
"crypto/elliptic"
"math/big"
"sync"
)
@ -16,29 +15,3 @@ func P256() elliptic.Curve {
initonce.Do(initAll)
return sm2p256
}
// Since golang 1.19
// unmarshaler is implemented by curves with their own constant-time Unmarshal.
// There isn't an equivalent interface for Marshal/MarshalCompressed because
// that doesn't involve any mathematical operations, only FillBytes and Bit.
type unmarshaler interface {
Unmarshal([]byte) (x, y *big.Int)
UnmarshalCompressed([]byte) (x, y *big.Int)
}
func Unmarshal(curve elliptic.Curve, data []byte) (x, y *big.Int) {
if c, ok := curve.(unmarshaler); ok {
return c.Unmarshal(data)
}
return elliptic.Unmarshal(curve, data)
}
// UnmarshalCompressed converts a point, serialized by MarshalCompressed, into
// an x, y pair. It is an error if the point is not in compressed form, is not
// on the curve, or is the point at infinity. On error, x = nil.
func UnmarshalCompressed(curve elliptic.Curve, data []byte) (x, y *big.Int) {
if c, ok := curve.(unmarshaler); ok {
return c.UnmarshalCompressed(data)
}
return elliptic.UnmarshalCompressed(curve, data)
}

View File

@ -61,7 +61,7 @@ func TestOffCurve(t *testing.T) {
x.FillBytes(b[1 : 1+byteLen])
y.FillBytes(b[1+byteLen : 1+2*byteLen])
x1, y1 := Unmarshal(curve, b)
x1, y1 := elliptic.Unmarshal(curve, b)
if x1 != nil || y1 != nil {
t.Errorf("unmarshaling a point not on the curve succeeded")
}
@ -126,18 +126,18 @@ func testInfinity(t *testing.T, curve elliptic.Curve) {
t.Errorf("IsOnCurve(∞) == true")
}
if xx, yy := Unmarshal(curve, elliptic.Marshal(curve, x0, y0)); xx != nil || yy != nil {
if xx, yy := elliptic.Unmarshal(curve, elliptic.Marshal(curve, x0, y0)); xx != nil || yy != nil {
t.Errorf("Unmarshal(Marshal(∞)) did not return an error")
}
// We don't test UnmarshalCompressed(MarshalCompressed(∞)) because there are
// two valid points with x = 0.
if xx, yy := Unmarshal(curve, []byte{0x00}); xx != nil || yy != nil {
if xx, yy := elliptic.Unmarshal(curve, []byte{0x00}); xx != nil || yy != nil {
t.Errorf("Unmarshal(∞) did not return an error")
}
byteLen := (curve.Params().BitSize + 7) / 8
buf := make([]byte, byteLen*2+1)
buf[0] = 4 // Uncompressed format.
if xx, yy := Unmarshal(curve, buf); xx != nil || yy != nil {
if xx, yy := elliptic.Unmarshal(curve, buf); xx != nil || yy != nil {
t.Errorf("Unmarshal((0,0)) did not return an error")
}
}
@ -149,7 +149,7 @@ func TestMarshal(t *testing.T) {
t.Fatal(err)
}
serialized := elliptic.Marshal(curve, x, y)
xx, yy := Unmarshal(curve, serialized)
xx, yy := elliptic.Unmarshal(curve, serialized)
if xx == nil {
t.Fatal("failed to unmarshal")
}
@ -230,7 +230,7 @@ func TestMarshalCompressed(t *testing.T) {
t.Run("Invalid", func(t *testing.T) {
data, _ := hex.DecodeString("02fd4bf61763b46581fd9174d623516cf3c81edd40e29ffa2777fb6cb0ae3ce535")
X, Y := UnmarshalCompressed(P256(), data)
X, Y := elliptic.UnmarshalCompressed(P256(), data)
if X != nil || Y != nil {
t.Error("expected an error for invalid encoding")
}
@ -258,7 +258,7 @@ func testMarshalCompressed(t *testing.T, curve elliptic.Curve, x, y *big.Int, wa
t.Errorf("got unexpected MarshalCompressed result: got %x, want %x", got, want)
}
X, Y := UnmarshalCompressed(curve, got)
X, Y := elliptic.UnmarshalCompressed(curve, got)
if X == nil || Y == nil {
t.Fatalf("UnmarshalCompressed failed unexpectedly")
}
@ -328,7 +328,7 @@ func BenchmarkMarshalUnmarshal(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
buf := elliptic.Marshal(curve, x, y)
xx, yy := Unmarshal(curve, buf)
xx, yy := elliptic.Unmarshal(curve, buf)
if xx.Cmp(x) != 0 || yy.Cmp(y) != 0 {
b.Error("Unmarshal output different from Marshal input")
}
@ -338,7 +338,7 @@ func BenchmarkMarshalUnmarshal(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
buf := elliptic.MarshalCompressed(curve, x, y)
xx, yy := UnmarshalCompressed(curve, buf)
xx, yy := elliptic.UnmarshalCompressed(curve, buf)
if xx.Cmp(x) != 0 || yy.Cmp(y) != 0 {
b.Error("Unmarshal output different from Marshal input")
}

View File

@ -114,7 +114,13 @@ func UnmarshalSignMasterPrivateKeyASN1(der []byte) (*SignMasterPrivateKey, error
if err != nil {
return nil, err
}
return &SignMasterPrivateKey{privateKey: priv.Bytes(), internal: priv}, nil
master := &SignMasterPrivateKey{privateKey: priv.Bytes(), internal: priv}
master.publicKey = &SignMasterPublicKey{
publicKey: priv.PublicKey().Bytes(),
internal: priv.PublicKey(),
}
return master, nil
}
// GenerateUserKey generate a signature private key for the given user.
@ -370,7 +376,13 @@ func UnmarshalEncryptMasterPrivateKeyASN1(der []byte) (*EncryptMasterPrivateKey,
if err != nil {
return nil, err
}
return &EncryptMasterPrivateKey{privateKey: privateKey.Bytes(), internal: privateKey}, nil
master := &EncryptMasterPrivateKey{privateKey: privateKey.Bytes(), internal: privateKey}
master.publicKey = &EncryptMasterPublicKey{
publicKey: privateKey.PublicKey().Bytes(),
internal: privateKey.PublicKey(),
}
return master, nil
}
// Equal compares the receiver EncryptMasterPublicKey with another EncryptMasterPublicKey

View File

@ -27,6 +27,11 @@ func TestSignMasterPrivateKeyMarshalASN1(t *testing.T) {
if !masterKey.Equal(masterKey2) {
t.Errorf("expected %v, got %v", hex.EncodeToString(masterKey.Bytes()), hex.EncodeToString(masterKey2.Bytes()))
}
masterPubKey := masterKey2.PublicKey()
if masterPubKey == nil {
t.Fatal("cannot export public key")
}
}
func TestSignMasterPublicKeyMarshalASN1(t *testing.T) {
@ -129,6 +134,11 @@ func TestEncryptMasterPrivateKeyMarshalASN1(t *testing.T) {
if !masterKey.Equal(masterKey2) {
t.Errorf("expected %v, got %v", hex.EncodeToString(masterKey.Bytes()), hex.EncodeToString(masterKey2.Bytes()))
}
masterPubKey := masterKey2.PublicKey()
if masterPubKey == nil {
t.Fatal("cannot export public key")
}
}
func TestEncryptMasterPublicKeyMarshalASN1(t *testing.T) {