mirror of
https://github.com/emmansun/gmsm.git
synced 2025-04-26 04:06:18 +08:00
smx509: refactor p8 parse and pkix public key parse
This commit is contained in:
parent
7db8067549
commit
25ead7dc1f
@ -7,6 +7,7 @@
|
|||||||
* 《GB/T 32918.4-2016 信息安全技术 SM2椭圆曲线公钥密码算法 第4部分:公钥加密算法》
|
* 《GB/T 32918.4-2016 信息安全技术 SM2椭圆曲线公钥密码算法 第4部分:公钥加密算法》
|
||||||
* 《GB/T 32918.5-2016 信息安全技术 SM2椭圆曲线公钥密码算法 第5部分:参数定义》
|
* 《GB/T 32918.5-2016 信息安全技术 SM2椭圆曲线公钥密码算法 第5部分:参数定义》
|
||||||
* 《GB/T 35276-2017 信息安全技术 SM2密码算法使用规范》
|
* 《GB/T 35276-2017 信息安全技术 SM2密码算法使用规范》
|
||||||
|
* 《GB/T 33560-2017 信息安全技术 密码应用标识规范》
|
||||||
* 《GB/T 35275-2017 信息安全技术 SM2密码算法加密签名消息语法规范》(对应PKCS#7)
|
* 《GB/T 35275-2017 信息安全技术 SM2密码算法加密签名消息语法规范》(对应PKCS#7)
|
||||||
|
|
||||||
您可以从[国家标准全文公开系统](https://openstd.samr.gov.cn/)在线阅读这些标准。
|
您可以从[国家标准全文公开系统](https://openstd.samr.gov.cn/)在线阅读这些标准。
|
||||||
|
@ -21,6 +21,7 @@ import (
|
|||||||
"unicode/utf16"
|
"unicode/utf16"
|
||||||
"unicode/utf8"
|
"unicode/utf8"
|
||||||
|
|
||||||
|
"github.com/emmansun/gmsm/sm2"
|
||||||
"golang.org/x/crypto/cryptobyte"
|
"golang.org/x/crypto/cryptobyte"
|
||||||
cryptobyte_asn1 "golang.org/x/crypto/cryptobyte/asn1"
|
cryptobyte_asn1 "golang.org/x/crypto/cryptobyte/asn1"
|
||||||
)
|
)
|
||||||
@ -288,6 +289,27 @@ func parsePublicKey(keyData *publicKeyInfo) (any, error) {
|
|||||||
Y: y,
|
Y: y,
|
||||||
}
|
}
|
||||||
return pub, nil
|
return pub, nil
|
||||||
|
case oid.Equal(oidPublicKeySM2):
|
||||||
|
paramsDer := cryptobyte.String(params.FullBytes)
|
||||||
|
namedCurveOID := new(asn1.ObjectIdentifier)
|
||||||
|
if !paramsDer.ReadASN1ObjectIdentifier(namedCurveOID) {
|
||||||
|
return nil, errors.New("x509: invalid SM2 parameters")
|
||||||
|
}
|
||||||
|
namedCurve := namedCurveFromOID(*namedCurveOID)
|
||||||
|
if namedCurve != sm2.P256() {
|
||||||
|
return nil, errors.New("x509: unsupported SM2 curve")
|
||||||
|
}
|
||||||
|
x, y := elliptic.Unmarshal(namedCurve, der)
|
||||||
|
if x == nil {
|
||||||
|
return nil, errors.New("x509: failed to unmarshal SM2 curve point")
|
||||||
|
}
|
||||||
|
pub := &ecdsa.PublicKey{
|
||||||
|
Curve: namedCurve,
|
||||||
|
X: x,
|
||||||
|
Y: y,
|
||||||
|
}
|
||||||
|
return pub, nil
|
||||||
|
|
||||||
case oid.Equal(oidPublicKeyEd25519):
|
case oid.Equal(oidPublicKeyEd25519):
|
||||||
// RFC 8410, Section 3
|
// RFC 8410, Section 3
|
||||||
// > For all of the OIDs, the parameters MUST be absent.
|
// > For all of the OIDs, the parameters MUST be absent.
|
||||||
|
@ -2,6 +2,7 @@ package smx509
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/asn1"
|
"encoding/asn1"
|
||||||
|
"encoding/hex"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
cryptobyte_asn1 "golang.org/x/crypto/cryptobyte/asn1"
|
cryptobyte_asn1 "golang.org/x/crypto/cryptobyte/asn1"
|
||||||
@ -97,3 +98,31 @@ func TestParseASN1String(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The SM2 public key with alg = oidPublicKeySM2 and SM2 curve
|
||||||
|
var sm2PublicKeyHex = "305a301406082a811ccf5501822d06082a811ccf5501822d0342000409586fff35c1f805b5c74f7281c3ade8fe211ffa70bf0ddd1c7268f62ae664331410e3039eeb03209afdc7fa834235c7b3ef528d32bf8b401eb98d32f498b4b7"
|
||||||
|
|
||||||
|
// The SM2 public key with alg = oidPublicKeySM2 and NIST P256 curve
|
||||||
|
var sm2NistP256PubulicKeyHex = "305a301406082a811ccf5501822d06082a8648ce3d0301070342000476110a45e7e86c1e96ba3c3300da61049a529c20a7ea7f026e50a2dbed60558087346bcb04cb0f0f8dcab8cca9967b8c7cc5aa0c874f024b73208b28f408bfca"
|
||||||
|
|
||||||
|
func TestParseSM2PublicKey(t *testing.T) {
|
||||||
|
der, err := hex.DecodeString(sm2PublicKeyHex)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
_, err = ParsePKIXPublicKey(der)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestParseSM2PublicKeyWithNistP256(t *testing.T) {
|
||||||
|
der, err := hex.DecodeString(sm2NistP256PubulicKeyHex)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
_, err = ParsePKIXPublicKey(der)
|
||||||
|
if err == nil || err.Error() != "x509: unsupported SM2 curve" {
|
||||||
|
t.Fatal("should throw x509: unsupported SM2 curve")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -46,27 +46,42 @@ func ParsePKCS8PrivateKey(der []byte) (key any, err error) {
|
|||||||
}
|
}
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if privKey.Algo.Algorithm.Equal(oidSM9) || privKey.Algo.Algorithm.Equal(oidSM9Sign) || privKey.Algo.Algorithm.Equal(oidSM9Enc) {
|
switch {
|
||||||
|
case privKey.Algo.Algorithm.Equal(oidPublicKeySM2):
|
||||||
|
bytes := privKey.Algo.Parameters.FullBytes
|
||||||
|
namedCurveOID := new(asn1.ObjectIdentifier)
|
||||||
|
if _, err := asn1.Unmarshal(bytes, namedCurveOID); err != nil {
|
||||||
|
namedCurveOID = nil
|
||||||
|
}
|
||||||
|
ecKey, err := parseECPrivateKey(namedCurveOID, privKey.PrivateKey)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.New("x509: failed to parse SM2 private key embedded in PKCS#8: " + err.Error())
|
||||||
|
}
|
||||||
|
if ecKey.Curve != sm2.P256() {
|
||||||
|
return nil, errors.New("x509: unsupported SM2 curve")
|
||||||
|
}
|
||||||
|
return new(sm2.PrivateKey).FromECPrivateKey(ecKey)
|
||||||
|
case privKey.Algo.Algorithm.Equal(oidSM9), privKey.Algo.Algorithm.Equal(oidSM9Sign), privKey.Algo.Algorithm.Equal(oidSM9Enc):
|
||||||
return parseSM9PrivateKey(privKey)
|
return parseSM9PrivateKey(privKey)
|
||||||
}
|
case privKey.Algo.Algorithm.Equal(oidPublicKeyECDSA):
|
||||||
if !privKey.Algo.Algorithm.Equal(oidPublicKeyECDSA) && !privKey.Algo.Algorithm.Equal(oidNamedCurveP256SM2) {
|
bytes := privKey.Algo.Parameters.FullBytes
|
||||||
|
namedCurveOID := new(asn1.ObjectIdentifier)
|
||||||
|
if _, err := asn1.Unmarshal(bytes, namedCurveOID); err != nil {
|
||||||
|
namedCurveOID = nil
|
||||||
|
}
|
||||||
|
ecKey, err := parseECPrivateKey(namedCurveOID, privKey.PrivateKey)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.New("x509: failed to parse EC private key embedded in PKCS#8: " + err.Error())
|
||||||
|
}
|
||||||
|
// convert *ecdsa.PrivateKey to *sm2.PrivateKey
|
||||||
|
if ecKey.Curve == sm2.P256() {
|
||||||
|
return new(sm2.PrivateKey).FromECPrivateKey(ecKey)
|
||||||
|
}
|
||||||
|
return ecKey, err
|
||||||
|
default:
|
||||||
|
// fallback to golang sdk
|
||||||
return x509.ParsePKCS8PrivateKey(der)
|
return x509.ParsePKCS8PrivateKey(der)
|
||||||
}
|
}
|
||||||
bytes := privKey.Algo.Parameters.FullBytes
|
|
||||||
namedCurveOID := new(asn1.ObjectIdentifier)
|
|
||||||
if _, err := asn1.Unmarshal(bytes, namedCurveOID); err != nil {
|
|
||||||
namedCurveOID = nil
|
|
||||||
}
|
|
||||||
ecKey, err := parseECPrivateKey(namedCurveOID, privKey.PrivateKey)
|
|
||||||
if err != nil {
|
|
||||||
return nil, errors.New("x509: failed to parse EC private key embedded in PKCS#8: " + err.Error())
|
|
||||||
}
|
|
||||||
if namedCurveOID.Equal(oidNamedCurveP256SM2) {
|
|
||||||
key, err = new(sm2.PrivateKey).FromECPrivateKey(ecKey)
|
|
||||||
} else {
|
|
||||||
key = ecKey
|
|
||||||
}
|
|
||||||
return key, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseSM9PrivateKey(privKey pkcs8) (key any, err error) {
|
func parseSM9PrivateKey(privKey pkcs8) (key any, err error) {
|
||||||
|
@ -462,6 +462,9 @@ var (
|
|||||||
// id-ecPublicKey OBJECT IDENTIFIER ::= {
|
// id-ecPublicKey OBJECT IDENTIFIER ::= {
|
||||||
// iso(1) member-body(2) us(840) ansi-X9-62(10045) keyType(2) 1 }
|
// iso(1) member-body(2) us(840) ansi-X9-62(10045) keyType(2) 1 }
|
||||||
oidPublicKeyECDSA = asn1.ObjectIdentifier{1, 2, 840, 10045, 2, 1}
|
oidPublicKeyECDSA = asn1.ObjectIdentifier{1, 2, 840, 10045, 2, 1}
|
||||||
|
// GB/T 33560-2017 信息安全技术 密码应用标识规范
|
||||||
|
// 附录A(规范性附录)商用密码领域中的相关OID定义
|
||||||
|
oidPublicKeySM2 = asn1.ObjectIdentifier{1, 2, 156, 10197, 1, 301}
|
||||||
// RFC 8410, Section 3
|
// RFC 8410, Section 3
|
||||||
//
|
//
|
||||||
// id-X25519 OBJECT IDENTIFIER ::= { 1 3 101 110 }
|
// id-X25519 OBJECT IDENTIFIER ::= { 1 3 101 110 }
|
||||||
|
Loading…
x
Reference in New Issue
Block a user