mirror of
https://github.com/emmansun/gmsm.git
synced 2025-04-26 12:16:20 +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.5-2016 信息安全技术 SM2椭圆曲线公钥密码算法 第5部分:参数定义》
|
||||
* 《GB/T 35276-2017 信息安全技术 SM2密码算法使用规范》
|
||||
* 《GB/T 33560-2017 信息安全技术 密码应用标识规范》
|
||||
* 《GB/T 35275-2017 信息安全技术 SM2密码算法加密签名消息语法规范》(对应PKCS#7)
|
||||
|
||||
您可以从[国家标准全文公开系统](https://openstd.samr.gov.cn/)在线阅读这些标准。
|
||||
|
@ -21,6 +21,7 @@ import (
|
||||
"unicode/utf16"
|
||||
"unicode/utf8"
|
||||
|
||||
"github.com/emmansun/gmsm/sm2"
|
||||
"golang.org/x/crypto/cryptobyte"
|
||||
cryptobyte_asn1 "golang.org/x/crypto/cryptobyte/asn1"
|
||||
)
|
||||
@ -288,6 +289,27 @@ func parsePublicKey(keyData *publicKeyInfo) (any, error) {
|
||||
Y: y,
|
||||
}
|
||||
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):
|
||||
// RFC 8410, Section 3
|
||||
// > For all of the OIDs, the parameters MUST be absent.
|
||||
|
@ -2,6 +2,7 @@ package smx509
|
||||
|
||||
import (
|
||||
"encoding/asn1"
|
||||
"encoding/hex"
|
||||
"testing"
|
||||
|
||||
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
|
||||
}
|
||||
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)
|
||||
}
|
||||
if !privKey.Algo.Algorithm.Equal(oidPublicKeyECDSA) && !privKey.Algo.Algorithm.Equal(oidNamedCurveP256SM2) {
|
||||
case privKey.Algo.Algorithm.Equal(oidPublicKeyECDSA):
|
||||
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)
|
||||
}
|
||||
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) {
|
||||
|
@ -462,6 +462,9 @@ var (
|
||||
// id-ecPublicKey OBJECT IDENTIFIER ::= {
|
||||
// iso(1) member-body(2) us(840) ansi-X9-62(10045) keyType(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
|
||||
//
|
||||
// id-X25519 OBJECT IDENTIFIER ::= { 1 3 101 110 }
|
||||
|
Loading…
x
Reference in New Issue
Block a user