mirror of
https://github.com/emmansun/gmsm.git
synced 2025-04-26 12:16:20 +08:00
support sm9 key format with gmssl
This commit is contained in:
parent
ecdf5fca82
commit
404cd10210
@ -101,6 +101,7 @@ func newPRFParamFromHash(h Hash) (pkix.AlgorithmIdentifier, error) {
|
|||||||
type pbkdf2Params struct {
|
type pbkdf2Params struct {
|
||||||
Salt []byte
|
Salt []byte
|
||||||
IterationCount int
|
IterationCount int
|
||||||
|
KeyLen int `asn1:"optional"`
|
||||||
PRF pkix.AlgorithmIdentifier `asn1:"optional"`
|
PRF pkix.AlgorithmIdentifier `asn1:"optional"`
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -127,7 +128,7 @@ func (p PBKDF2Opts) DeriveKey(password, salt []byte, size int) (
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
params = pbkdf2Params{salt, p.IterationCount, prfParam}
|
params = pbkdf2Params{salt, p.IterationCount, size, prfParam}
|
||||||
return key, params, nil
|
return key, params, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -219,7 +219,7 @@ func ParsePrivateKey(der []byte, password []byte) (interface{}, KDFParameters, e
|
|||||||
|
|
||||||
key, err := smx509.ParsePKCS8PrivateKey(decryptedKey)
|
key, err := smx509.ParsePKCS8PrivateKey(decryptedKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, errors.New("pkcs8: incorrect password")
|
return nil, nil, errors.New("pkcs8: failed to parse private key while ParsePKCS8PrivateKey: " + err.Error())
|
||||||
}
|
}
|
||||||
return key, kdfParams, nil
|
return key, kdfParams, nil
|
||||||
}
|
}
|
||||||
|
@ -32,3 +32,31 @@ func TestParseFFCscryptPrivateKey(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const encryptedSM9SignPrivateKey = `-----BEGIN ENCRYPTED SM9 SIGN PRIVATE KEY-----
|
||||||
|
MIIBVjBhBgkqhkiG9w0BBQ0wVDA0BgkqhkiG9w0BBQwwJwQQxWctHikJLVP2A7fQ
|
||||||
|
nm6qwQIDAQAAAgEQMAsGCSqBHM9VAYMRAjAcBggqgRzPVQFoAgQQfuWLjhO7iJNX
|
||||||
|
2owsXE8/6gSB8Ot4oMs97o7dDd6o2U29uTjvkt7Xq/ti/2OPoOvDeGr/SWTmLUHY
|
||||||
|
6X71SpB/GAmBVE1qMXSxFHotgeq1cbwuZtwqLV2GA0etAnC2MZV/2BYcx+qOwwgX
|
||||||
|
uljiXhlvpvxHfxxdL7HzJ5oC+AuMblQZnAvaicmS9Pr+EPk4gzusiCc4cu1q+sTh
|
||||||
|
xl4HzCz08DYx8l5j1B/FCnN0/9tv2F2Q6j3xWARFC8EJPAEhALdO+hol56Tz7A2a
|
||||||
|
zSK4N8ox4ip3G8L6TVMIlc8qFIfsnaVn+dQSWDubya8Lq4AieEs8mL+kPqEnSIUX
|
||||||
|
fYuup/MCEz2zpA==
|
||||||
|
-----END ENCRYPTED SM9 SIGN PRIVATE KEY-----
|
||||||
|
`
|
||||||
|
|
||||||
|
func TestParseSM9PrivateKey(t *testing.T) {
|
||||||
|
keyList := []testPrivateKey{
|
||||||
|
{
|
||||||
|
name: "encryptedSM9SignPrivateKey",
|
||||||
|
clear: "",
|
||||||
|
encrypted: encryptedSM9SignPrivateKey,
|
||||||
|
password: "123456",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for i, key := range keyList {
|
||||||
|
t.Run(key.name, func(t *testing.T) {
|
||||||
|
testParsePKCS8PrivateKey(t, i, &key)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
161
sm9/sm9_key.go
161
sm9/sm9_key.go
@ -1,6 +1,9 @@
|
|||||||
package sm9
|
package sm9
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/asn1"
|
||||||
|
"encoding/pem"
|
||||||
|
|
||||||
"errors"
|
"errors"
|
||||||
"io"
|
"io"
|
||||||
"math/big"
|
"math/big"
|
||||||
@ -8,6 +11,7 @@ import (
|
|||||||
|
|
||||||
"github.com/emmansun/gmsm/sm9/bn256"
|
"github.com/emmansun/gmsm/sm9/bn256"
|
||||||
"golang.org/x/crypto/cryptobyte"
|
"golang.org/x/crypto/cryptobyte"
|
||||||
|
cryptobyte_asn1 "golang.org/x/crypto/cryptobyte/asn1"
|
||||||
)
|
)
|
||||||
|
|
||||||
// SignMasterPrivateKey master private key for sign, generated by KGC
|
// SignMasterPrivateKey master private key for sign, generated by KGC
|
||||||
@ -180,6 +184,16 @@ func unmarshalG2(bytes []byte) (*bn256.G2, error) {
|
|||||||
return g2, nil
|
return g2, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UnmarshalRaw unmarsal raw bytes data to sign master public key
|
||||||
|
func (pub *SignMasterPublicKey) UnmarshalRaw(bytes []byte) error {
|
||||||
|
g2, err := unmarshalG2(bytes)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
pub.MasterPublicKey = g2
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// UnmarshalASN1 unmarsal der data to sign master public key
|
// UnmarshalASN1 unmarsal der data to sign master public key
|
||||||
func (pub *SignMasterPublicKey) UnmarshalASN1(der []byte) error {
|
func (pub *SignMasterPublicKey) UnmarshalASN1(der []byte) error {
|
||||||
var bytes []byte
|
var bytes []byte
|
||||||
@ -187,12 +201,29 @@ func (pub *SignMasterPublicKey) UnmarshalASN1(der []byte) error {
|
|||||||
if !input.ReadASN1BitStringAsBytes(&bytes) || !input.Empty() {
|
if !input.ReadASN1BitStringAsBytes(&bytes) || !input.Empty() {
|
||||||
return errors.New("sm9: invalid sign master public key asn1 data")
|
return errors.New("sm9: invalid sign master public key asn1 data")
|
||||||
}
|
}
|
||||||
g2, err := unmarshalG2(bytes)
|
return pub.UnmarshalRaw(bytes)
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
pub.MasterPublicKey = g2
|
|
||||||
return nil
|
type publicKeyInfo struct {
|
||||||
|
Raw asn1.RawContent
|
||||||
|
PublicKey asn1.BitString
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParseFromPEM just for GMSSL, there are no Algorithm pkix.AlgorithmIdentifier
|
||||||
|
func (pub *SignMasterPublicKey) ParseFromPEM(data []byte) error {
|
||||||
|
block, _ := pem.Decode([]byte(data))
|
||||||
|
if block == nil {
|
||||||
|
return errors.New("failed to parse PEM block")
|
||||||
|
}
|
||||||
|
|
||||||
|
var pki publicKeyInfo
|
||||||
|
if rest, err := asn1.Unmarshal(block.Bytes, &pki); err != nil {
|
||||||
|
return err
|
||||||
|
} else if len(rest) != 0 {
|
||||||
|
return errors.New("trailing data after ASN.1 of public-key")
|
||||||
|
}
|
||||||
|
der := cryptobyte.String(pki.PublicKey.RightAlign())
|
||||||
|
return pub.UnmarshalRaw(der)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MasterPublic returns the master public key corresponding to priv.
|
// MasterPublic returns the master public key corresponding to priv.
|
||||||
@ -242,14 +273,9 @@ func unmarshalG1(bytes []byte) (*bn256.G1, error) {
|
|||||||
return g, nil
|
return g, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// UnmarshalASN1 unmarsal der data to sign user private key
|
// UnmarshalRaw unmarsal raw bytes data to sign user private key
|
||||||
// Note, priv's SignMasterPublicKey should be handled separately.
|
// Note, priv's SignMasterPublicKey should be handled separately.
|
||||||
func (priv *SignPrivateKey) UnmarshalASN1(der []byte) error {
|
func (priv *SignPrivateKey) UnmarshalRaw(bytes []byte) error {
|
||||||
var bytes []byte
|
|
||||||
input := cryptobyte.String(der)
|
|
||||||
if !input.ReadASN1BitStringAsBytes(&bytes) || !input.Empty() {
|
|
||||||
return errors.New("sm9: invalid sign user private key asn1 data")
|
|
||||||
}
|
|
||||||
g, err := unmarshalG1(bytes)
|
g, err := unmarshalG1(bytes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -258,6 +284,40 @@ func (priv *SignPrivateKey) UnmarshalASN1(der []byte) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UnmarshalASN1 unmarsal der data to sign user private key
|
||||||
|
// Note, priv's SignMasterPublicKey should be handled separately.
|
||||||
|
func (priv *SignPrivateKey) UnmarshalASN1(der []byte) error {
|
||||||
|
var bytes []byte
|
||||||
|
var pubBytes []byte
|
||||||
|
var inner cryptobyte.String
|
||||||
|
input := cryptobyte.String(der)
|
||||||
|
if der[0] == 0x30 {
|
||||||
|
if !input.ReadASN1(&inner, cryptobyte_asn1.SEQUENCE) ||
|
||||||
|
!input.Empty() ||
|
||||||
|
!inner.ReadASN1BitStringAsBytes(&bytes) {
|
||||||
|
return errors.New("sm9: invalid sign user private key asn1 data")
|
||||||
|
}
|
||||||
|
if !inner.Empty() && (!inner.ReadASN1BitStringAsBytes(&pubBytes) || !inner.Empty()) {
|
||||||
|
return errors.New("sm9: invalid sign master public key asn1 data")
|
||||||
|
}
|
||||||
|
} else if !input.ReadASN1BitStringAsBytes(&bytes) || !input.Empty() {
|
||||||
|
return errors.New("sm9: invalid sign user private key asn1 data")
|
||||||
|
}
|
||||||
|
err := priv.UnmarshalRaw(bytes)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if len(pubBytes) > 0 {
|
||||||
|
masterPK := new(SignMasterPublicKey)
|
||||||
|
err = masterPK.UnmarshalRaw(pubBytes)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
priv.SetMasterPublicKey(masterPK)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// GenerateEncryptMasterKey generates a master public and private key pair for encryption usage.
|
// GenerateEncryptMasterKey generates a master public and private key pair for encryption usage.
|
||||||
func GenerateEncryptMasterKey(rand io.Reader) (*EncryptMasterPrivateKey, error) {
|
func GenerateEncryptMasterKey(rand io.Reader) (*EncryptMasterPrivateKey, error) {
|
||||||
k, err := randFieldElement(rand)
|
k, err := randFieldElement(rand)
|
||||||
@ -367,6 +427,33 @@ func (pub *EncryptMasterPublicKey) MarshalCompressedASN1() ([]byte, error) {
|
|||||||
return b.Bytes()
|
return b.Bytes()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UnmarshalRaw unmarsal raw bytes data to encrypt master public key
|
||||||
|
func (pub *EncryptMasterPublicKey) UnmarshalRaw(bytes []byte) error {
|
||||||
|
g, err := unmarshalG1(bytes)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
pub.MasterPublicKey = g
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParseFromPEM just for GMSSL, there are no Algorithm pkix.AlgorithmIdentifier
|
||||||
|
func (pub *EncryptMasterPublicKey) ParseFromPEM(data []byte) error {
|
||||||
|
block, _ := pem.Decode([]byte(data))
|
||||||
|
if block == nil {
|
||||||
|
return errors.New("failed to parse PEM block")
|
||||||
|
}
|
||||||
|
|
||||||
|
var pki publicKeyInfo
|
||||||
|
if rest, err := asn1.Unmarshal(block.Bytes, &pki); err != nil {
|
||||||
|
return err
|
||||||
|
} else if len(rest) != 0 {
|
||||||
|
return errors.New("trailing data after ASN.1 of public-key")
|
||||||
|
}
|
||||||
|
der := cryptobyte.String(pki.PublicKey.RightAlign())
|
||||||
|
return pub.UnmarshalRaw(der)
|
||||||
|
}
|
||||||
|
|
||||||
// UnmarshalASN1 unmarsal der data to encrypt master public key
|
// UnmarshalASN1 unmarsal der data to encrypt master public key
|
||||||
func (pub *EncryptMasterPublicKey) UnmarshalASN1(der []byte) error {
|
func (pub *EncryptMasterPublicKey) UnmarshalASN1(der []byte) error {
|
||||||
var bytes []byte
|
var bytes []byte
|
||||||
@ -374,12 +461,7 @@ func (pub *EncryptMasterPublicKey) UnmarshalASN1(der []byte) error {
|
|||||||
if !input.ReadASN1BitStringAsBytes(&bytes) || !input.Empty() {
|
if !input.ReadASN1BitStringAsBytes(&bytes) || !input.Empty() {
|
||||||
return errors.New("sm9: invalid encrypt master public key asn1 data")
|
return errors.New("sm9: invalid encrypt master public key asn1 data")
|
||||||
}
|
}
|
||||||
g, err := unmarshalG1(bytes)
|
return pub.UnmarshalRaw(bytes)
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
pub.MasterPublicKey = g
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// MasterPublic returns the master public key corresponding to priv.
|
// MasterPublic returns the master public key corresponding to priv.
|
||||||
@ -410,14 +492,9 @@ func (priv *EncryptPrivateKey) MarshalCompressedASN1() ([]byte, error) {
|
|||||||
return b.Bytes()
|
return b.Bytes()
|
||||||
}
|
}
|
||||||
|
|
||||||
// UnmarshalASN1 unmarsal der data to encrypt user private key
|
// UnmarshalRaw unmarsal raw bytes data to encrypt user private key
|
||||||
// Note, priv's EncryptMasterPublicKey should be handled separately.
|
// Note, priv's EncryptMasterPublicKey should be handled separately.
|
||||||
func (priv *EncryptPrivateKey) UnmarshalASN1(der []byte) error {
|
func (priv *EncryptPrivateKey) UnmarshalRaw(bytes []byte) error {
|
||||||
var bytes []byte
|
|
||||||
input := cryptobyte.String(der)
|
|
||||||
if !input.ReadASN1BitStringAsBytes(&bytes) || !input.Empty() {
|
|
||||||
return errors.New("sm9: invalid encrypt user private key asn1 data")
|
|
||||||
}
|
|
||||||
g, err := unmarshalG2(bytes)
|
g, err := unmarshalG2(bytes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -426,6 +503,40 @@ func (priv *EncryptPrivateKey) UnmarshalASN1(der []byte) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UnmarshalASN1 unmarsal der data to encrypt user private key
|
||||||
|
// Note, priv's EncryptMasterPublicKey should be handled separately.
|
||||||
|
func (priv *EncryptPrivateKey) UnmarshalASN1(der []byte) error {
|
||||||
|
var bytes []byte
|
||||||
|
var pubBytes []byte
|
||||||
|
var inner cryptobyte.String
|
||||||
|
input := cryptobyte.String(der)
|
||||||
|
if der[0] == 0x30 {
|
||||||
|
if !input.ReadASN1(&inner, cryptobyte_asn1.SEQUENCE) ||
|
||||||
|
!input.Empty() ||
|
||||||
|
!inner.ReadASN1BitStringAsBytes(&bytes) {
|
||||||
|
return errors.New("sm9: invalid encrypt user private key asn1 data")
|
||||||
|
}
|
||||||
|
if !inner.Empty() && (!inner.ReadASN1BitStringAsBytes(&pubBytes) || !inner.Empty()) {
|
||||||
|
return errors.New("sm9: invalid encrypt master public key asn1 data")
|
||||||
|
}
|
||||||
|
} else if !input.ReadASN1BitStringAsBytes(&bytes) || !input.Empty() {
|
||||||
|
return errors.New("sm9: invalid encrypt user private key asn1 data")
|
||||||
|
}
|
||||||
|
err := priv.UnmarshalRaw(bytes)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if len(pubBytes) > 0 {
|
||||||
|
masterPK := new(EncryptMasterPublicKey)
|
||||||
|
err = masterPK.UnmarshalRaw(pubBytes)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
priv.SetMasterPublicKey(masterPK)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// fermatInverse calculates the inverse of k in GF(P) using Fermat's method
|
// fermatInverse calculates the inverse of k in GF(P) using Fermat's method
|
||||||
// (exponentiation modulo P - 2, per Euler's theorem). This has better
|
// (exponentiation modulo P - 2, per Euler's theorem). This has better
|
||||||
// constant-time properties than Euclid's method (implemented in
|
// constant-time properties than Euclid's method (implemented in
|
||||||
|
@ -253,3 +253,18 @@ func BenchmarkGenerateEncryptPrivKey(b *testing.B) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const sm9SignMasterPublicKeyFromGMSSL = `-----BEGIN SM9 SIGN MASTER PUBLIC KEY-----
|
||||||
|
MIGFA4GCAARvTUvk1ztAlmjlUK0kP3zdFEVHHr8HUL4sUbcnFoQPukP0AjurnySy
|
||||||
|
f1MY0Plzt4lZ5u0/6GC4zUjYEcjWiYV+bV9YCnOGVQAYfPr/a+4/alewf43qBJuX
|
||||||
|
Ri1gDhueE6gkoeZ4HHUu1wfhRbKRF8okwSO933f/ZSpLlYu1P7/ckw==
|
||||||
|
-----END SM9 SIGN MASTER PUBLIC KEY-----
|
||||||
|
`
|
||||||
|
|
||||||
|
func TestParseSM9SignMasterPublicKey(t *testing.T) {
|
||||||
|
key := new(SignMasterPublicKey)
|
||||||
|
err := key.ParseFromPEM([]byte(sm9SignMasterPublicKeyFromGMSSL))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -8,6 +8,13 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
"github.com/emmansun/gmsm/sm2"
|
"github.com/emmansun/gmsm/sm2"
|
||||||
|
"github.com/emmansun/gmsm/sm9"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
oidSM9 = asn1.ObjectIdentifier{1, 2, 156, 10197, 1, 302}
|
||||||
|
oidSM9Sign = asn1.ObjectIdentifier{1, 2, 156, 10197, 1, 302, 1}
|
||||||
|
oidSM9Enc = asn1.ObjectIdentifier{1, 2, 156, 10197, 1, 302, 3}
|
||||||
)
|
)
|
||||||
|
|
||||||
// pkcs8 reflects an ASN.1, PKCS #8 PrivateKey. See
|
// pkcs8 reflects an ASN.1, PKCS #8 PrivateKey. See
|
||||||
@ -37,6 +44,9 @@ func ParsePKCS8PrivateKey(der []byte) (key interface{}, err error) {
|
|||||||
}
|
}
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
if privKey.Algo.Algorithm.Equal(oidSM9) || privKey.Algo.Algorithm.Equal(oidSM9Sign) || privKey.Algo.Algorithm.Equal(oidSM9Enc) {
|
||||||
|
return parseSM9PrivateKey(privKey)
|
||||||
|
}
|
||||||
if !privKey.Algo.Algorithm.Equal(oidPublicKeyECDSA) {
|
if !privKey.Algo.Algorithm.Equal(oidPublicKeyECDSA) {
|
||||||
return x509.ParsePKCS8PrivateKey(der)
|
return x509.ParsePKCS8PrivateKey(der)
|
||||||
}
|
}
|
||||||
@ -57,6 +67,30 @@ func ParsePKCS8PrivateKey(der []byte) (key interface{}, err error) {
|
|||||||
return key, err
|
return key, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func parseSM9PrivateKey(privKey pkcs8) (key interface{}, err error) {
|
||||||
|
switch {
|
||||||
|
case privKey.Algo.Algorithm.Equal(oidSM9Sign):
|
||||||
|
sm9SignKey := new(sm9.SignPrivateKey)
|
||||||
|
err = sm9SignKey.UnmarshalASN1(privKey.PrivateKey)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
key = sm9SignKey
|
||||||
|
return
|
||||||
|
case privKey.Algo.Algorithm.Equal(oidSM9Enc):
|
||||||
|
sm9EncKey := new(sm9.EncryptPrivateKey)
|
||||||
|
err = sm9EncKey.UnmarshalASN1(privKey.PrivateKey)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
key = sm9EncKey
|
||||||
|
return
|
||||||
|
default:
|
||||||
|
return nil, errors.New("not support yet")
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// MarshalPKCS8PrivateKey converts a private key to PKCS #8, ASN.1 DER form.
|
// MarshalPKCS8PrivateKey converts a private key to PKCS #8, ASN.1 DER form.
|
||||||
//
|
//
|
||||||
// The following key types are currently supported: *rsa.PrivateKey, *ecdsa.PrivateKey
|
// The following key types are currently supported: *rsa.PrivateKey, *ecdsa.PrivateKey
|
||||||
@ -67,10 +101,72 @@ func MarshalPKCS8PrivateKey(key interface{}) ([]byte, error) {
|
|||||||
switch k := key.(type) {
|
switch k := key.(type) {
|
||||||
case *sm2.PrivateKey:
|
case *sm2.PrivateKey:
|
||||||
return marshalPKCS8ECPrivateKey(&k.PrivateKey)
|
return marshalPKCS8ECPrivateKey(&k.PrivateKey)
|
||||||
|
case *sm9.SignPrivateKey:
|
||||||
|
return marshalPKCS8SM9SignPrivateKey(k)
|
||||||
|
case *sm9.EncryptPrivateKey:
|
||||||
|
return marshalPKCS8SM9EncPrivateKey(k)
|
||||||
|
case *sm9.SignMasterPrivateKey:
|
||||||
|
return nil, errors.New("not implemented")
|
||||||
|
case *sm9.EncryptMasterPrivateKey:
|
||||||
|
return nil, errors.New("not implemented")
|
||||||
}
|
}
|
||||||
return x509.MarshalPKCS8PrivateKey(key)
|
return x509.MarshalPKCS8PrivateKey(key)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type sm9PrivateKey struct {
|
||||||
|
PrivateKey asn1.RawValue
|
||||||
|
PublicKey asn1.RawValue
|
||||||
|
}
|
||||||
|
|
||||||
|
func marshalPKCS8SM9SignPrivateKey(k *sm9.SignPrivateKey) ([]byte, error) {
|
||||||
|
var privKey pkcs8
|
||||||
|
privKey.Algo = pkix.AlgorithmIdentifier{
|
||||||
|
Algorithm: oidSM9Sign,
|
||||||
|
Parameters: asn1.NullRawValue,
|
||||||
|
}
|
||||||
|
|
||||||
|
key := sm9PrivateKey{}
|
||||||
|
privans1, err := k.MarshalASN1()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
pubasn1, err := k.MasterPublic().MarshalASN1()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
key.PrivateKey.FullBytes = privans1
|
||||||
|
key.PublicKey.FullBytes = pubasn1
|
||||||
|
|
||||||
|
if privKey.PrivateKey, err = asn1.Marshal(key); err != nil {
|
||||||
|
return nil, errors.New("x509: failed to marshal sm9 sign private key while building PKCS#8: " + err.Error())
|
||||||
|
}
|
||||||
|
return asn1.Marshal(privKey)
|
||||||
|
}
|
||||||
|
|
||||||
|
func marshalPKCS8SM9EncPrivateKey(k *sm9.EncryptPrivateKey) ([]byte, error) {
|
||||||
|
var privKey pkcs8
|
||||||
|
privKey.Algo = pkix.AlgorithmIdentifier{
|
||||||
|
Algorithm: oidSM9Enc,
|
||||||
|
Parameters: asn1.NullRawValue,
|
||||||
|
}
|
||||||
|
key := sm9PrivateKey{}
|
||||||
|
privans1, err := k.MarshalASN1()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
pubasn1, err := k.MasterPublic().MarshalASN1()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
key.PrivateKey.FullBytes = privans1
|
||||||
|
key.PublicKey.FullBytes = pubasn1
|
||||||
|
|
||||||
|
if privKey.PrivateKey, err = asn1.Marshal(key); err != nil {
|
||||||
|
return nil, errors.New("x509: failed to marshal sm9 encrypt private key while building PKCS#8: " + err.Error())
|
||||||
|
}
|
||||||
|
return asn1.Marshal(privKey)
|
||||||
|
}
|
||||||
|
|
||||||
func marshalPKCS8ECPrivateKey(k *ecdsa.PrivateKey) ([]byte, error) {
|
func marshalPKCS8ECPrivateKey(k *ecdsa.PrivateKey) ([]byte, error) {
|
||||||
var privKey pkcs8
|
var privKey pkcs8
|
||||||
oid, ok := oidFromNamedCurve(k.Curve)
|
oid, ok := oidFromNamedCurve(k.Curve)
|
||||||
|
@ -14,6 +14,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/emmansun/gmsm/sm2"
|
"github.com/emmansun/gmsm/sm2"
|
||||||
|
"github.com/emmansun/gmsm/sm9"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Generated using:
|
// Generated using:
|
||||||
@ -155,3 +156,57 @@ func TestMarshalPKCS8SM2PrivateKey(t *testing.T) {
|
|||||||
}
|
}
|
||||||
fmt.Printf("%s\n", hex.EncodeToString(res))
|
fmt.Printf("%s\n", hex.EncodeToString(res))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestMarshalPKCS8SM9SignPrivateKey(t *testing.T) {
|
||||||
|
masterKey, err := sm9.GenerateSignMasterKey(rand.Reader)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
privateKey, err := masterKey.GenerateUserKey([]byte("emmansun"), 0x01)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
res, err := MarshalPKCS8PrivateKey(privateKey)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
privateKey1, err := ParsePKCS8PrivateKey(res)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
privateKey2, ok := privateKey1.(*sm9.SignPrivateKey)
|
||||||
|
if !ok {
|
||||||
|
t.Fatalf("not expected key")
|
||||||
|
}
|
||||||
|
if !privateKey.PrivateKey.Equal(privateKey2.PrivateKey) ||
|
||||||
|
!privateKey.MasterPublicKey.Equal(privateKey2.MasterPublicKey) {
|
||||||
|
t.Fatalf("not same key")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMarshalPKCS8SM9EncPrivateKey(t *testing.T) {
|
||||||
|
masterKey, err := sm9.GenerateEncryptMasterKey(rand.Reader)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
privateKey, err := masterKey.GenerateUserKey([]byte("emmansun"), 0x01)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
res, err := MarshalPKCS8PrivateKey(privateKey)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
privateKey1, err := ParsePKCS8PrivateKey(res)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
privateKey2, ok := privateKey1.(*sm9.EncryptPrivateKey)
|
||||||
|
if !ok {
|
||||||
|
t.Fatalf("not expected key")
|
||||||
|
}
|
||||||
|
if !privateKey.PrivateKey.Equal(privateKey2.PrivateKey) ||
|
||||||
|
!privateKey.MasterPublicKey.Equal(privateKey2.MasterPublicKey) {
|
||||||
|
t.Fatalf("not same key")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user