package sm9 import ( "encoding/pem" "errors" "io" "math/big" "github.com/emmansun/gmsm/internal/sm9" "golang.org/x/crypto/cryptobyte" cryptobyte_asn1 "golang.org/x/crypto/cryptobyte/asn1" ) // SignMasterPrivateKey master private key for sign, generated by KGC type SignMasterPrivateKey struct { privateKey *sm9.SignMasterPrivateKey } // SignMasterPublicKey master public key for sign, generated by KGC type SignMasterPublicKey struct { publicKey *sm9.SignMasterPublicKey } // SignPrivateKey user private key for sign, generated by KGC type SignPrivateKey struct { privateKey *sm9.SignPrivateKey } // EncryptMasterPrivateKey master private key for encryption, generated by KGC type EncryptMasterPrivateKey struct { privateKey *sm9.EncryptMasterPrivateKey } // EncryptMasterPublicKey master private key for encryption, generated by KGC type EncryptMasterPublicKey struct { publicKey *sm9.EncryptMasterPublicKey } // EncryptPrivateKey user private key for encryption, generated by KGC type EncryptPrivateKey struct { privateKey *sm9.EncryptPrivateKey } // GenerateSignMasterKey generates a master public and private key pair for DSA usage. func GenerateSignMasterKey(rand io.Reader) (*SignMasterPrivateKey, error) { priv, err := sm9.GenerateSignMasterKey(rand) if err != nil { return nil, err } return &SignMasterPrivateKey{privateKey: priv}, nil } // Equal compares the receiver SignMasterPrivateKey with another SignMasterPrivateKey // and returns true if they are equal, otherwise it returns false. func (master *SignMasterPrivateKey) Equal(x *SignMasterPrivateKey) bool { return master.privateKey.Equal(x.privateKey) } // Bytes returns the byte representation of the SignMasterPrivateKey. // It converts the private key to a byte slice. func (master *SignMasterPrivateKey) Bytes() []byte { return master.privateKey.Bytes() } // MarshalASN1 marshal sign master private key to asn.1 format data according // SM9 cryptographic algorithm application specification func (master *SignMasterPrivateKey) MarshalASN1() ([]byte, error) { d := new(big.Int).SetBytes(master.privateKey.Bytes()) var b cryptobyte.Builder b.AddASN1BigInt(d) return b.Bytes() } // UnmarshalSignMasterPrivateKeyASN1 unmarsal der data to sign master private key func UnmarshalSignMasterPrivateKeyASN1(der []byte) (*SignMasterPrivateKey, error) { input := cryptobyte.String(der) d := &big.Int{} var inner cryptobyte.String var pubBytes []byte var err error if der[0] == 0x30 { if !input.ReadASN1(&inner, cryptobyte_asn1.SEQUENCE) || !input.Empty() || !inner.ReadASN1Integer(d) { return nil, errors.New("sm9: invalid sign master private key asn1 data") } // Just parse it, didn't validate it if !inner.Empty() && (!inner.ReadASN1BitStringAsBytes(&pubBytes) || !inner.Empty()) { return nil, errors.New("sm9: invalid sign master public key asn1 data") } } else if !input.ReadASN1Integer(d) || !input.Empty() { return nil, errors.New("sm9: invalid sign master private key asn1 data") } privateKey, err := sm9.NewSignMasterPrivateKey(d.Bytes()) if err != nil { return nil, err } return &SignMasterPrivateKey{privateKey: privateKey}, nil } // GenerateUserKey generate an user dsa key. func (master *SignMasterPrivateKey) GenerateUserKey(uid []byte, hid byte) (*SignPrivateKey, error) { priv, err := master.privateKey.GenerateUserKey(uid, hid) if err != nil { return nil, err } return &SignPrivateKey{privateKey: priv}, nil } // Public returns the public key corresponding to priv. func (master *SignMasterPrivateKey) Public() *SignMasterPublicKey { return &SignMasterPublicKey{master.privateKey.Public()} } // Equal compares the receiver SignMasterPublicKey with another SignMasterPublicKey // and returns true if they are equal, otherwise false. func (pub *SignMasterPublicKey) Equal(x *SignMasterPublicKey) bool { return pub.publicKey.Equal(x.publicKey) } // Bytes returns the byte representation of the SignMasterPublicKey. // It calls the Bytes method on the underlying publicKey field. func (pub *SignMasterPublicKey) Bytes() []byte { return pub.publicKey.Bytes() } // MarshalASN1 marshal sign master public key to asn.1 format data according // SM9 cryptographic algorithm application specification func (pub *SignMasterPublicKey) MarshalASN1() ([]byte, error) { var b cryptobyte.Builder b.AddASN1BitString(pub.publicKey.MasterPublicKey.MarshalUncompressed()) return b.Bytes() } // MarshalCompressedASN1 marshal sign master public key to asn.1 format data according // SM9 cryptographic algorithm application specification, the curve point is in compressed form. func (pub *SignMasterPublicKey) MarshalCompressedASN1() ([]byte, error) { var b cryptobyte.Builder b.AddASN1BitString(pub.publicKey.MasterPublicKey.MarshalCompressed()) return b.Bytes() } // UnmarshalSignMasterPublicKeyRaw unmarsal raw bytes data to sign master public key func UnmarshalSignMasterPublicKeyRaw(bytes []byte) (pub *SignMasterPublicKey, err error) { pub = new(SignMasterPublicKey) pub.publicKey = new(sm9.SignMasterPublicKey) err = pub.publicKey.UnmarshalRaw(bytes) return } // UnmarshalSignMasterPublicKeyASN1 unmarsal der data to sign master public key func UnmarshalSignMasterPublicKeyASN1(der []byte) (*SignMasterPublicKey, error) { var bytes []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) || !inner.Empty() { return nil, errors.New("sm9: invalid sign master public key asn1 data") } } else if !input.ReadASN1BitStringAsBytes(&bytes) || !input.Empty() { return nil, errors.New("sm9: invalid sign master public key asn1 data") } return UnmarshalSignMasterPublicKeyRaw(bytes) } // ParseSignMasterPublicKeyPEM just for GMSSL, there are no Algorithm pkix.AlgorithmIdentifier func ParseSignMasterPublicKeyPEM(data []byte) (*SignMasterPublicKey, error) { block, _ := pem.Decode([]byte(data)) if block == nil { return nil, errors.New("sm9: failed to parse PEM block") } return UnmarshalSignMasterPublicKeyASN1(block.Bytes) } func (priv *SignPrivateKey) Equal(x *SignPrivateKey) bool { return priv.privateKey.Equal(x.privateKey) } func (priv *SignPrivateKey) Bytes() []byte { return priv.privateKey.Bytes() } // MasterPublic returns the master public key corresponding to priv. func (priv *SignPrivateKey) MasterPublic() *SignMasterPublicKey { return &SignMasterPublicKey{priv.privateKey.MasterPublic()} } // setMasterPublicKey bind the sign master public key to it. func (priv *SignPrivateKey) setMasterPublicKey(pub *SignMasterPublicKey) { priv.privateKey.SetMasterPublicKey(pub.publicKey) } // MarshalASN1 marshal sign user private key to asn.1 format data according // SM9 cryptographic algorithm application specification func (priv *SignPrivateKey) MarshalASN1() ([]byte, error) { var b cryptobyte.Builder b.AddASN1BitString(priv.privateKey.PrivateKey.MarshalUncompressed()) return b.Bytes() } // MarshalCompressedASN1 marshal sign user private key to asn.1 format data according // SM9 cryptographic algorithm application specification, the curve point is in compressed form. func (priv *SignPrivateKey) MarshalCompressedASN1() ([]byte, error) { var b cryptobyte.Builder b.AddASN1BitString(priv.privateKey.PrivateKey.MarshalCompressed()) return b.Bytes() } // UnmarshalSignPrivateKeyRaw unmarsal raw bytes data to sign user private key // Note, priv's SignMasterPublicKey should be handled separately. func UnmarshalSignPrivateKeyRaw(bytes []byte) (*SignPrivateKey, error) { priv := new(SignPrivateKey) priv.privateKey = new(sm9.SignPrivateKey) err := priv.privateKey.UnmarshalRaw(bytes) if err != nil { return nil, err } return priv, nil } // UnmarshalSignPrivateKeyASN1 unmarsal der data to sign user private key // Note, priv's SignMasterPublicKey should be handled separately. func UnmarshalSignPrivateKeyASN1(der []byte) (*SignPrivateKey, 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 nil, errors.New("sm9: invalid sign user private key asn1 data") } if !inner.Empty() && (!inner.ReadASN1BitStringAsBytes(&pubBytes) || !inner.Empty()) { return nil,errors.New("sm9: invalid sign master public key asn1 data") } } else if !input.ReadASN1BitStringAsBytes(&bytes) || !input.Empty() { return nil, errors.New("sm9: invalid sign user private key asn1 data") } priv, err := UnmarshalSignPrivateKeyRaw(bytes) if err != nil { return nil, err } if len(pubBytes) > 0 { masterPK, err := UnmarshalSignMasterPublicKeyRaw(pubBytes) if err != nil { return nil, err } priv.setMasterPublicKey(masterPK) } return priv, nil } // GenerateEncryptMasterKey generates a master public and private key pair for encryption usage. func GenerateEncryptMasterKey(rand io.Reader) (*EncryptMasterPrivateKey, error) { priv, err := sm9.GenerateEncryptMasterKey(rand) if err != nil { return nil, err } return &EncryptMasterPrivateKey{privateKey: priv}, nil } // Bytes returns the byte representation of the EncryptMasterPrivateKey. // It delegates the call to the Bytes method of the underlying privateKey. func (master *EncryptMasterPrivateKey) Bytes() []byte { return master.privateKey.Bytes() } // Equal compares the receiver EncryptMasterPrivateKey with another EncryptMasterPrivateKey // and returns true if they are equal, otherwise it returns false. func (master *EncryptMasterPrivateKey) Equal(x *EncryptMasterPrivateKey) bool { return master.privateKey.Equal(x.privateKey) } // GenerateUserKey generate an user key for encryption. func (master *EncryptMasterPrivateKey) GenerateUserKey(uid []byte, hid byte) (*EncryptPrivateKey, error) { priv, err := master.privateKey.GenerateUserKey(uid, hid) if err != nil { return nil, err } return &EncryptPrivateKey{privateKey: priv}, nil } // Public returns the public key corresponding to priv. func (master *EncryptMasterPrivateKey) Public() *EncryptMasterPublicKey { return &EncryptMasterPublicKey{publicKey: master.privateKey.Public()} } // MarshalASN1 marshal encrypt master private key to asn.1 format data according // SM9 cryptographic algorithm application specification func (master *EncryptMasterPrivateKey) MarshalASN1() ([]byte, error) { d := new(big.Int).SetBytes(master.privateKey.Bytes()) var b cryptobyte.Builder b.AddASN1BigInt(d) return b.Bytes() } // UnmarshalEncryptMasterPrivateKeyASN1 unmarsal der data to encrypt master private key func UnmarshalEncryptMasterPrivateKeyASN1(der []byte) (*EncryptMasterPrivateKey, error) { input := cryptobyte.String(der) d := &big.Int{} var inner cryptobyte.String var pubBytes []byte if der[0] == 0x30 { if !input.ReadASN1(&inner, cryptobyte_asn1.SEQUENCE) || !input.Empty() || !inner.ReadASN1Integer(d) { return nil, errors.New("sm9: invalid encrypt master private key asn1 data") } // Just parse it, did't validate it if !inner.Empty() && (!inner.ReadASN1BitStringAsBytes(&pubBytes) || !inner.Empty()) { return nil, errors.New("sm9: invalid encrypt master public key asn1 data") } } else if !input.ReadASN1Integer(d) || !input.Empty() { return nil, errors.New("sm9: invalid encrypt master private key asn1 data") } privateKey, err := sm9.NewEncryptMasterPrivateKey(d.Bytes()) if err != nil { return nil, err } return &EncryptMasterPrivateKey{privateKey: privateKey}, nil } // Equal compares the receiver EncryptMasterPublicKey with another EncryptMasterPublicKey // and returns true if they are equal, otherwise it returns false. func (pub *EncryptMasterPublicKey) Equal(x *EncryptMasterPublicKey) bool { return pub.publicKey.Equal(x.publicKey) } // Bytes returns the byte representation of the EncryptMasterPublicKey. // It delegates the call to the Bytes method of the underlying publicKey. func (pub *EncryptMasterPublicKey) Bytes() []byte { return pub.publicKey.Bytes() } // MarshalASN1 marshal encrypt master public key to asn.1 format data according // SM9 cryptographic algorithm application specification func (pub *EncryptMasterPublicKey) MarshalASN1() ([]byte, error) { var b cryptobyte.Builder b.AddASN1BitString(pub.publicKey.MasterPublicKey.MarshalUncompressed()) return b.Bytes() } // MarshalCompressedASN1 marshal encrypt master public key to asn.1 format data according // SM9 cryptographic algorithm application specification, the curve point is in compressed form. func (pub *EncryptMasterPublicKey) MarshalCompressedASN1() ([]byte, error) { var b cryptobyte.Builder b.AddASN1BitString(pub.publicKey.MasterPublicKey.MarshalCompressed()) return b.Bytes() } // UnmarshalEncryptMasterPublicKeyRaw unmarsal raw bytes data to encrypt master public key func UnmarshalEncryptMasterPublicKeyRaw(bytes []byte) (*EncryptMasterPublicKey, error) { pub := new(EncryptMasterPublicKey) pub.publicKey = new(sm9.EncryptMasterPublicKey) err := pub.publicKey.UnmarshalRaw(bytes) if err != nil { return nil, err } return pub, nil } // ParseEncryptMasterPublicKeyPEM just for GMSSL, there are no Algorithm pkix.AlgorithmIdentifier func ParseEncryptMasterPublicKeyPEM(data []byte) (*EncryptMasterPublicKey, error) { block, _ := pem.Decode([]byte(data)) if block == nil { return nil, errors.New("sm9: failed to parse PEM block") } return UnmarshalEncryptMasterPublicKeyASN1(block.Bytes) } // UnmarshalEncryptMasterPublicKeyASN1 unmarsal der data to encrypt master public key func UnmarshalEncryptMasterPublicKeyASN1(der []byte) (*EncryptMasterPublicKey, error) { var bytes []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) || !inner.Empty() { return nil, errors.New("sm9: invalid encrypt master public key asn1 data") } } else if !input.ReadASN1BitStringAsBytes(&bytes) || !input.Empty() { return nil, errors.New("sm9: invalid encrypt master public key asn1 data") } return UnmarshalEncryptMasterPublicKeyRaw(bytes) } // MasterPublic returns the master public key corresponding to priv. func (priv *EncryptPrivateKey) MasterPublic() *EncryptMasterPublicKey { return &EncryptMasterPublicKey{priv.privateKey.MasterPublic()} } // setMasterPublicKey bind the encrypt master public key to it. func (priv *EncryptPrivateKey) setMasterPublicKey(pub *EncryptMasterPublicKey) { priv.privateKey.SetMasterPublicKey(pub.publicKey) } // MarshalASN1 marshal encrypt user private key to asn.1 format data according // SM9 cryptographic algorithm application specification func (priv *EncryptPrivateKey) MarshalASN1() ([]byte, error) { var b cryptobyte.Builder b.AddASN1BitString(priv.privateKey.PrivateKey.MarshalUncompressed()) return b.Bytes() } // MarshalCompressedASN1 marshal encrypt user private key to asn.1 format data according // SM9 cryptographic algorithm application specification, the curve point is in compressed form. func (priv *EncryptPrivateKey) MarshalCompressedASN1() ([]byte, error) { var b cryptobyte.Builder b.AddASN1BitString(priv.privateKey.PrivateKey.MarshalCompressed()) return b.Bytes() } // UnmarshalEncryptPrivateKeyRaw unmarsal raw bytes data to encrypt user private key // Note, priv's EncryptMasterPublicKey should be handled separately. func UnmarshalEncryptPrivateKeyRaw(bytes []byte) (*EncryptPrivateKey, error) { priv := new(EncryptPrivateKey) priv.privateKey = new(sm9.EncryptPrivateKey) err := priv.privateKey.UnmarshalRaw(bytes) if err != nil { return nil, err } return priv, nil } // UnmarshalEncryptPrivateKeyASN1 unmarsal der data to encrypt user private key // Note, priv's EncryptMasterPublicKey should be handled separately. func UnmarshalEncryptPrivateKeyASN1(der []byte) (*EncryptPrivateKey, 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 nil, errors.New("sm9: invalid encrypt user private key asn1 data") } if !inner.Empty() && (!inner.ReadASN1BitStringAsBytes(&pubBytes) || !inner.Empty()) { return nil, errors.New("sm9: invalid encrypt master public key asn1 data") } } else if !input.ReadASN1BitStringAsBytes(&bytes) || !input.Empty() { return nil, errors.New("sm9: invalid encrypt user private key asn1 data") } priv, err := UnmarshalEncryptPrivateKeyRaw(bytes) if err != nil { return nil, err } if len(pubBytes) > 0 { masterPK, err := UnmarshalEncryptMasterPublicKeyRaw(pubBytes) if err != nil { return nil, err } priv.setMasterPublicKey(masterPK) } return priv, nil } // Equal compares the receiver EncryptPrivateKey with another EncryptPrivateKey x // and returns true if they are equal, otherwise false. func (priv *EncryptPrivateKey) Equal(x *EncryptPrivateKey) bool { return priv.privateKey.Equal(x.privateKey) } // Bytes returns the byte representation of the EncryptPrivateKey. // It delegates the call to the Bytes method of the underlying privateKey. func (priv *EncryptPrivateKey) Bytes() []byte { return priv.privateKey.Bytes() }