gmsm/sm9/sm9_key.go

470 lines
16 KiB
Go
Raw Normal View History

2022-07-15 16:42:39 +08:00
package sm9
import (
2022-10-22 15:49:01 +08:00
"encoding/pem"
2022-07-15 16:42:39 +08:00
"errors"
"io"
"math/big"
"github.com/emmansun/gmsm/internal/sm9"
2022-07-15 16:42:39 +08:00
"golang.org/x/crypto/cryptobyte"
2022-10-22 15:49:01 +08:00
cryptobyte_asn1 "golang.org/x/crypto/cryptobyte/asn1"
2022-07-15 16:42:39 +08:00
)
// SignMasterPrivateKey master private key for sign, generated by KGC
type SignMasterPrivateKey struct {
privateKey *sm9.SignMasterPrivateKey
2022-07-15 16:42:39 +08:00
}
// SignMasterPublicKey master public key for sign, generated by KGC
type SignMasterPublicKey struct {
publicKey *sm9.SignMasterPublicKey
2022-07-15 16:42:39 +08:00
}
// SignPrivateKey user private key for sign, generated by KGC
type SignPrivateKey struct {
privateKey *sm9.SignPrivateKey
2022-07-15 16:42:39 +08:00
}
// EncryptMasterPrivateKey master private key for encryption, generated by KGC
type EncryptMasterPrivateKey struct {
privateKey *sm9.EncryptMasterPrivateKey
2022-07-15 16:42:39 +08:00
}
// EncryptMasterPublicKey master private key for encryption, generated by KGC
type EncryptMasterPublicKey struct {
publicKey *sm9.EncryptMasterPublicKey
2022-07-15 16:42:39 +08:00
}
// EncryptPrivateKey user private key for encryption, generated by KGC
type EncryptPrivateKey struct {
privateKey *sm9.EncryptPrivateKey
2022-07-15 16:42:39 +08:00
}
// GenerateSignMasterKey generates a master public and private key pair for DSA usage.
func GenerateSignMasterKey(rand io.Reader) (*SignMasterPrivateKey, error) {
priv, err := sm9.GenerateSignMasterKey(rand)
2022-07-15 16:42:39 +08:00
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)
}
2022-07-15 16:42:39 +08:00
// 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()
2022-07-15 16:42:39 +08:00
}
// 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())
2022-07-15 16:42:39 +08:00
var b cryptobyte.Builder
b.AddASN1BigInt(d)
2022-07-15 16:42:39 +08:00
return b.Bytes()
}
// UnmarshalASN1 unmarsal der data to sign master private key
func (master *SignMasterPrivateKey) UnmarshalASN1(der []byte) 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 errors.New("sm9: invalid sign master private key asn1 data")
}
2024-12-17 18:06:15 +08:00
// Just parse it, didn't validate it
if !inner.Empty() && (!inner.ReadASN1BitStringAsBytes(&pubBytes) || !inner.Empty()) {
return errors.New("sm9: invalid sign master public key asn1 data")
}
} else if !input.ReadASN1Integer(d) || !input.Empty() {
return errors.New("sm9: invalid sign master private key asn1 data")
2022-07-15 16:42:39 +08:00
}
master.privateKey, err = sm9.NewSignMasterPrivateKey(d.Bytes())
2022-11-25 10:11:46 +08:00
if err != nil {
return err
}
2022-07-15 16:42:39 +08:00
return nil
}
// GenerateUserKey generate an user dsa key.
func (master *SignMasterPrivateKey) GenerateUserKey(uid []byte, hid byte) (*SignPrivateKey, error) {
priv, err := master.privateKey.GenerateUserKey(uid, hid)
2022-11-25 10:11:46 +08:00
if err != nil {
return nil, err
}
return &SignPrivateKey{privateKey: priv}, nil
2022-07-15 16:42:39 +08:00
}
// Public returns the public key corresponding to priv.
func (master *SignMasterPrivateKey) Public() *SignMasterPublicKey {
return &SignMasterPublicKey{master.privateKey.Public()}
2022-07-28 10:01:30 +08:00
}
// 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)
2022-07-28 10:01:30 +08:00
}
// 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()
2022-07-15 16:42:39 +08:00
}
// 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())
2022-07-15 16:42:39 +08:00
return b.Bytes()
}
2022-08-09 10:01:34 +08:00
// 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())
2022-08-09 10:01:34 +08:00
return b.Bytes()
}
2022-10-22 15:49:01 +08:00
// UnmarshalRaw unmarsal raw bytes data to sign master public key
func (pub *SignMasterPublicKey) UnmarshalRaw(bytes []byte) error {
if pub.publicKey == nil {
pub.publicKey = new(sm9.SignMasterPublicKey)
2022-10-22 15:49:01 +08:00
}
return pub.publicKey.UnmarshalRaw(bytes)
2022-10-22 15:49:01 +08:00
}
2022-07-15 16:42:39 +08:00
// UnmarshalASN1 unmarsal der data to sign master public key
func (pub *SignMasterPublicKey) UnmarshalASN1(der []byte) error {
var bytes []byte
var inner cryptobyte.String
2022-07-15 16:42:39 +08:00
input := cryptobyte.String(der)
if der[0] == 0x30 {
if !input.ReadASN1(&inner, cryptobyte_asn1.SEQUENCE) ||
!input.Empty() ||
!inner.ReadASN1BitStringAsBytes(&bytes) ||
!inner.Empty() {
return errors.New("sm9: invalid sign master public key asn1 data")
}
} else if !input.ReadASN1BitStringAsBytes(&bytes) || !input.Empty() {
2022-07-15 16:42:39 +08:00
return errors.New("sm9: invalid sign master public key asn1 data")
}
2022-10-22 15:49:01 +08:00
return pub.UnmarshalRaw(bytes)
}
// 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 {
2022-10-24 17:32:56 +08:00
return errors.New("sm9: failed to parse PEM block")
2022-10-22 15:49:01 +08:00
}
return pub.UnmarshalASN1(block.Bytes)
2022-07-15 16:42:39 +08:00
}
func (priv *SignPrivateKey) Equal(x *SignPrivateKey) bool {
return priv.privateKey.Equal(x.privateKey)
}
func (priv *SignPrivateKey) Bytes() []byte {
return priv.privateKey.Bytes()
}
2022-07-15 16:42:39 +08:00
// MasterPublic returns the master public key corresponding to priv.
func (priv *SignPrivateKey) MasterPublic() *SignMasterPublicKey {
return &SignMasterPublicKey{priv.privateKey.MasterPublic()}
2022-07-15 16:42:39 +08:00
}
// SetMasterPublicKey bind the sign master public key to it.
func (priv *SignPrivateKey) SetMasterPublicKey(pub *SignMasterPublicKey) {
priv.privateKey.SetMasterPublicKey(pub.publicKey)
2022-07-15 16:42:39 +08:00
}
// 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())
2022-07-15 16:42:39 +08:00
return b.Bytes()
}
2022-08-09 10:01:34 +08:00
// 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())
2022-08-09 10:01:34 +08:00
return b.Bytes()
}
2022-10-22 15:49:01 +08:00
// UnmarshalRaw unmarsal raw bytes data to sign user private key
// Note, priv's SignMasterPublicKey should be handled separately.
func (priv *SignPrivateKey) UnmarshalRaw(bytes []byte) error {
if priv.privateKey == nil {
priv.privateKey = new(sm9.SignPrivateKey)
2022-10-22 15:49:01 +08:00
}
return priv.privateKey.UnmarshalRaw(bytes)
2022-10-22 15:49:01 +08:00
}
2022-07-15 16:42:39 +08:00
// 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
2022-10-22 15:49:01 +08:00
var pubBytes []byte
var inner cryptobyte.String
2022-07-15 16:42:39 +08:00
input := cryptobyte.String(der)
2022-10-22 15:49:01 +08:00
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() {
2022-07-15 16:42:39 +08:00
return errors.New("sm9: invalid sign user private key asn1 data")
}
2022-10-22 15:49:01 +08:00
err := priv.UnmarshalRaw(bytes)
2022-07-15 16:42:39 +08:00
if err != nil {
return err
}
2022-10-22 15:49:01 +08:00
if len(pubBytes) > 0 {
masterPK := new(SignMasterPublicKey)
err = masterPK.UnmarshalRaw(pubBytes)
if err != nil {
return err
}
priv.SetMasterPublicKey(masterPK)
}
2022-07-15 16:42:39 +08:00
return 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)
2022-07-15 16:42:39 +08:00
if err != nil {
return nil, err
}
return &EncryptMasterPrivateKey{privateKey: priv}, nil
}
2022-07-15 16:42:39 +08:00
// 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)
2022-07-15 16:42:39 +08:00
}
// GenerateUserKey generate an user key for encryption.
func (master *EncryptMasterPrivateKey) GenerateUserKey(uid []byte, hid byte) (*EncryptPrivateKey, error) {
priv, err := master.privateKey.GenerateUserKey(uid, hid)
2022-11-25 10:11:46 +08:00
if err != nil {
return nil, err
}
return &EncryptPrivateKey{privateKey: priv}, nil
2022-07-15 16:42:39 +08:00
}
// Public returns the public key corresponding to priv.
func (master *EncryptMasterPrivateKey) Public() *EncryptMasterPublicKey {
return &EncryptMasterPublicKey{publicKey: master.privateKey.Public()}
2022-07-15 16:42:39 +08:00
}
// 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())
2022-07-15 16:42:39 +08:00
var b cryptobyte.Builder
b.AddASN1BigInt(d)
2022-07-15 16:42:39 +08:00
return b.Bytes()
}
// UnmarshalASN1 unmarsal der data to encrypt master private key
2022-07-15 16:42:39 +08:00
func (master *EncryptMasterPrivateKey) UnmarshalASN1(der []byte) 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 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 errors.New("sm9: invalid encrypt master public key asn1 data")
}
} else if !input.ReadASN1Integer(d) || !input.Empty() {
2022-10-24 17:32:56 +08:00
return errors.New("sm9: invalid encrypt master private key asn1 data")
2022-07-15 16:42:39 +08:00
}
var err error
master.privateKey, err = sm9.NewEncryptMasterPrivateKey(d.Bytes())
2022-11-25 10:11:46 +08:00
if err != nil {
return err
}
2022-07-15 16:42:39 +08:00
return 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)
2022-07-28 10:01:30 +08:00
}
// 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()
2022-07-15 16:42:39 +08:00
}
// 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())
2022-07-15 16:42:39 +08:00
return b.Bytes()
}
2022-08-09 10:01:34 +08:00
// 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())
2022-08-09 10:01:34 +08:00
return b.Bytes()
}
2022-10-22 15:49:01 +08:00
// UnmarshalRaw unmarsal raw bytes data to encrypt master public key
func (pub *EncryptMasterPublicKey) UnmarshalRaw(bytes []byte) error {
if pub.publicKey == nil {
pub.publicKey = new(sm9.EncryptMasterPublicKey)
2022-10-22 15:49:01 +08:00
}
return pub.publicKey.UnmarshalRaw(bytes)
2022-10-22 15:49:01 +08:00
}
// 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 {
2022-10-24 17:32:56 +08:00
return errors.New("sm9: failed to parse PEM block")
2022-10-22 15:49:01 +08:00
}
return pub.UnmarshalASN1(block.Bytes)
2022-10-22 15:49:01 +08:00
}
2022-07-15 16:42:39 +08:00
// UnmarshalASN1 unmarsal der data to encrypt master public key
func (pub *EncryptMasterPublicKey) UnmarshalASN1(der []byte) error {
var bytes []byte
var inner cryptobyte.String
2022-07-15 16:42:39 +08:00
input := cryptobyte.String(der)
if der[0] == 0x30 {
if !input.ReadASN1(&inner, cryptobyte_asn1.SEQUENCE) ||
!input.Empty() ||
!inner.ReadASN1BitStringAsBytes(&bytes) ||
!inner.Empty() {
return errors.New("sm9: invalid encrypt master public key asn1 data")
}
} else if !input.ReadASN1BitStringAsBytes(&bytes) || !input.Empty() {
2022-07-15 16:42:39 +08:00
return errors.New("sm9: invalid encrypt master public key asn1 data")
}
2022-10-22 15:49:01 +08:00
return pub.UnmarshalRaw(bytes)
2022-07-15 16:42:39 +08:00
}
// MasterPublic returns the master public key corresponding to priv.
func (priv *EncryptPrivateKey) MasterPublic() *EncryptMasterPublicKey {
return &EncryptMasterPublicKey{priv.privateKey.MasterPublic()}
2022-07-15 16:42:39 +08:00
}
// SetMasterPublicKey bind the encrypt master public key to it.
func (priv *EncryptPrivateKey) SetMasterPublicKey(pub *EncryptMasterPublicKey) {
priv.privateKey.SetMasterPublicKey(pub.publicKey)
2022-07-15 16:42:39 +08:00
}
// 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())
2022-07-15 16:42:39 +08:00
return b.Bytes()
}
2022-08-09 10:01:34 +08:00
// 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())
2022-08-09 10:01:34 +08:00
return b.Bytes()
}
2022-10-22 15:49:01 +08:00
// UnmarshalRaw unmarsal raw bytes data to encrypt user private key
// Note, priv's EncryptMasterPublicKey should be handled separately.
func (priv *EncryptPrivateKey) UnmarshalRaw(bytes []byte) error {
if priv.privateKey == nil {
priv.privateKey = new(sm9.EncryptPrivateKey)
2022-10-22 15:49:01 +08:00
}
return priv.privateKey.UnmarshalRaw(bytes)
2022-10-22 15:49:01 +08:00
}
2022-07-15 16:42:39 +08:00
// 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
2022-10-22 15:49:01 +08:00
var pubBytes []byte
var inner cryptobyte.String
2022-07-15 16:42:39 +08:00
input := cryptobyte.String(der)
2022-10-22 15:49:01 +08:00
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() {
2022-07-15 16:42:39 +08:00
return errors.New("sm9: invalid encrypt user private key asn1 data")
}
2022-10-22 15:49:01 +08:00
err := priv.UnmarshalRaw(bytes)
2022-07-15 16:42:39 +08:00
if err != nil {
return err
}
2022-10-22 15:49:01 +08:00
if len(pubBytes) > 0 {
masterPK := new(EncryptMasterPublicKey)
err = masterPK.UnmarshalRaw(pubBytes)
if err != nil {
return err
}
priv.SetMasterPublicKey(masterPK)
}
2022-07-15 16:42:39 +08:00
return 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()
}