2022-07-15 16:42:39 +08:00
|
|
|
package sm9
|
|
|
|
|
|
|
|
import (
|
2025-03-25 11:10:53 +08:00
|
|
|
"crypto"
|
|
|
|
"crypto/subtle"
|
2022-10-22 15:49:01 +08:00
|
|
|
"encoding/pem"
|
|
|
|
|
2022-07-15 16:42:39 +08:00
|
|
|
"errors"
|
|
|
|
"io"
|
|
|
|
"math/big"
|
|
|
|
|
2025-03-13 13:46:14 +08:00
|
|
|
"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
|
|
|
)
|
|
|
|
|
2025-03-14 15:26:34 +08:00
|
|
|
// SignMasterPrivateKey is a signature master private key, generated by KGC
|
2022-07-15 16:42:39 +08:00
|
|
|
type SignMasterPrivateKey struct {
|
2025-03-25 11:10:53 +08:00
|
|
|
privateKey []byte
|
|
|
|
publicKey *SignMasterPublicKey
|
|
|
|
internal *sm9.SignMasterPrivateKey
|
2022-07-15 16:42:39 +08:00
|
|
|
}
|
|
|
|
|
2025-03-14 15:26:34 +08:00
|
|
|
// SignMasterPublicKey is a signature master public key, generated by KGC
|
2022-07-15 16:42:39 +08:00
|
|
|
type SignMasterPublicKey struct {
|
2025-03-25 11:10:53 +08:00
|
|
|
publicKey []byte
|
|
|
|
internal *sm9.SignMasterPublicKey
|
2022-07-15 16:42:39 +08:00
|
|
|
}
|
|
|
|
|
2025-03-14 15:26:34 +08:00
|
|
|
// SignPrivateKey is a signature private key, generated by KGC
|
2022-07-15 16:42:39 +08:00
|
|
|
type SignPrivateKey struct {
|
2025-03-25 11:10:53 +08:00
|
|
|
privateKey []byte
|
|
|
|
internal *sm9.SignPrivateKey
|
2022-07-15 16:42:39 +08:00
|
|
|
}
|
|
|
|
|
2025-03-14 15:26:34 +08:00
|
|
|
// EncryptMasterPrivateKey is an encryption master private key, generated by KGC
|
2022-07-15 16:42:39 +08:00
|
|
|
type EncryptMasterPrivateKey struct {
|
2025-03-25 11:10:53 +08:00
|
|
|
privateKey []byte
|
|
|
|
publicKey *EncryptMasterPublicKey
|
|
|
|
internal *sm9.EncryptMasterPrivateKey
|
2022-07-15 16:42:39 +08:00
|
|
|
}
|
|
|
|
|
2025-03-14 15:26:34 +08:00
|
|
|
// EncryptMasterPublicKey is an encryption master public key, generated by KGC
|
2022-07-15 16:42:39 +08:00
|
|
|
type EncryptMasterPublicKey struct {
|
2025-03-25 11:10:53 +08:00
|
|
|
publicKey []byte
|
|
|
|
internal *sm9.EncryptMasterPublicKey
|
2022-07-15 16:42:39 +08:00
|
|
|
}
|
|
|
|
|
2025-03-14 15:26:34 +08:00
|
|
|
// EncryptPrivateKey is an encryption private key, generated by KGC
|
2022-07-15 16:42:39 +08:00
|
|
|
type EncryptPrivateKey struct {
|
2025-03-25 11:10:53 +08:00
|
|
|
privateKey []byte
|
|
|
|
internal *sm9.EncryptPrivateKey
|
2022-07-15 16:42:39 +08:00
|
|
|
}
|
|
|
|
|
2025-03-14 15:26:34 +08:00
|
|
|
// GenerateSignMasterKey generates a signature master key pair for DSA usage.
|
2022-07-15 16:42:39 +08:00
|
|
|
func GenerateSignMasterKey(rand io.Reader) (*SignMasterPrivateKey, error) {
|
2025-03-13 13:46:14 +08:00
|
|
|
priv, err := sm9.GenerateSignMasterKey(rand)
|
2022-07-15 16:42:39 +08:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2025-03-25 11:10:53 +08:00
|
|
|
master := &SignMasterPrivateKey{privateKey: priv.Bytes(), internal: priv}
|
|
|
|
master.publicKey = &SignMasterPublicKey{publicKey: priv.PublicKey().Bytes(), internal: priv.PublicKey()}
|
|
|
|
return master, nil
|
2025-03-13 13:46:14 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// Equal compares the receiver SignMasterPrivateKey with another SignMasterPrivateKey
|
|
|
|
// and returns true if they are equal, otherwise it returns false.
|
2025-03-25 11:10:53 +08:00
|
|
|
func (master *SignMasterPrivateKey) Equal(x crypto.PrivateKey) bool {
|
|
|
|
xx, ok := x.(*SignMasterPrivateKey)
|
|
|
|
if !ok {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
return subtle.ConstantTimeCompare(master.privateKey, xx.privateKey) == 1
|
2025-03-13 13:46:14 +08:00
|
|
|
}
|
2022-07-15 16:42:39 +08:00
|
|
|
|
2025-03-13 13:46:14 +08:00
|
|
|
// Bytes returns the byte representation of the SignMasterPrivateKey.
|
|
|
|
// It converts the private key to a byte slice.
|
|
|
|
func (master *SignMasterPrivateKey) Bytes() []byte {
|
2025-03-25 11:10:53 +08:00
|
|
|
var buf [32]byte
|
|
|
|
return append(buf[:0], master.privateKey...)
|
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) {
|
2025-03-25 11:10:53 +08:00
|
|
|
d := new(big.Int).SetBytes(master.privateKey)
|
2022-07-15 16:42:39 +08:00
|
|
|
var b cryptobyte.Builder
|
2025-03-13 13:46:14 +08:00
|
|
|
b.AddASN1BigInt(d)
|
2022-07-15 16:42:39 +08:00
|
|
|
return b.Bytes()
|
|
|
|
}
|
|
|
|
|
2025-03-14 15:26:34 +08:00
|
|
|
// UnmarshalSignMasterPrivateKeyASN1 unmarsal der data to a signature master private key
|
2025-03-13 16:50:28 +08:00
|
|
|
func UnmarshalSignMasterPrivateKeyASN1(der []byte) (*SignMasterPrivateKey, error) {
|
2022-07-15 16:42:39 +08:00
|
|
|
input := cryptobyte.String(der)
|
|
|
|
d := &big.Int{}
|
2022-10-24 11:00:13 +08:00
|
|
|
var inner cryptobyte.String
|
|
|
|
var pubBytes []byte
|
2025-03-13 13:46:14 +08:00
|
|
|
var err error
|
2022-10-24 11:00:13 +08:00
|
|
|
if der[0] == 0x30 {
|
|
|
|
if !input.ReadASN1(&inner, cryptobyte_asn1.SEQUENCE) ||
|
|
|
|
!input.Empty() ||
|
|
|
|
!inner.ReadASN1Integer(d) {
|
2025-03-14 15:26:34 +08:00
|
|
|
return nil, errors.New("sm9: invalid ASN.1 data for signature master private key")
|
2022-10-24 11:00:13 +08:00
|
|
|
}
|
2024-12-17 18:06:15 +08:00
|
|
|
// Just parse it, didn't validate it
|
2022-10-24 11:00:13 +08:00
|
|
|
if !inner.Empty() && (!inner.ReadASN1BitStringAsBytes(&pubBytes) || !inner.Empty()) {
|
2025-03-14 15:26:34 +08:00
|
|
|
return nil, errors.New("sm9: invalid ASN.1 data for signature master public key")
|
2022-10-24 11:00:13 +08:00
|
|
|
}
|
|
|
|
} else if !input.ReadASN1Integer(d) || !input.Empty() {
|
2025-03-14 15:26:34 +08:00
|
|
|
return nil, errors.New("sm9: invalid ASN.1 data for signature master private key")
|
2022-07-15 16:42:39 +08:00
|
|
|
}
|
2025-03-14 15:26:34 +08:00
|
|
|
|
2025-03-25 11:10:53 +08:00
|
|
|
priv, err := sm9.NewSignMasterPrivateKey(d.Bytes())
|
2022-11-25 10:11:46 +08:00
|
|
|
if err != nil {
|
2025-03-13 16:50:28 +08:00
|
|
|
return nil, err
|
2022-11-25 10:11:46 +08:00
|
|
|
}
|
2025-04-15 15:41:20 +08:00
|
|
|
|
|
|
|
master := &SignMasterPrivateKey{privateKey: priv.Bytes(), internal: priv}
|
|
|
|
master.publicKey = &SignMasterPublicKey{
|
|
|
|
publicKey: priv.PublicKey().Bytes(),
|
|
|
|
internal: priv.PublicKey(),
|
|
|
|
}
|
|
|
|
return master, nil
|
2022-07-15 16:42:39 +08:00
|
|
|
}
|
|
|
|
|
2025-03-14 15:26:34 +08:00
|
|
|
// GenerateUserKey generate a signature private key for the given user.
|
2022-07-15 16:42:39 +08:00
|
|
|
func (master *SignMasterPrivateKey) GenerateUserKey(uid []byte, hid byte) (*SignPrivateKey, error) {
|
2025-03-25 11:10:53 +08:00
|
|
|
priv, err := master.internal.GenerateUserKey(uid, hid)
|
2022-11-25 10:11:46 +08:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2025-03-25 11:10:53 +08:00
|
|
|
return &SignPrivateKey{privateKey: priv.Bytes(), internal: priv}, nil
|
2022-07-15 16:42:39 +08:00
|
|
|
}
|
|
|
|
|
2025-03-14 15:26:34 +08:00
|
|
|
// Public returns the public key corresponding to the private key.
|
2025-03-25 11:10:53 +08:00
|
|
|
func (master *SignMasterPrivateKey) PublicKey() *SignMasterPublicKey {
|
|
|
|
return master.publicKey
|
|
|
|
}
|
|
|
|
|
|
|
|
func (master *SignMasterPrivateKey) Public() crypto.PublicKey {
|
|
|
|
return master.PublicKey()
|
2022-07-28 10:01:30 +08:00
|
|
|
}
|
|
|
|
|
2025-03-13 13:46:14 +08:00
|
|
|
// Equal compares the receiver SignMasterPublicKey with another SignMasterPublicKey
|
|
|
|
// and returns true if they are equal, otherwise false.
|
2025-03-25 11:10:53 +08:00
|
|
|
func (pub *SignMasterPublicKey) Equal(x crypto.PublicKey) bool {
|
|
|
|
xx, ok := x.(*SignMasterPublicKey)
|
|
|
|
if !ok {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
return subtle.ConstantTimeCompare(pub.publicKey, xx.publicKey) == 1
|
2022-07-28 10:01:30 +08:00
|
|
|
}
|
|
|
|
|
2025-03-13 13:46:14 +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 {
|
2025-03-25 11:10:53 +08:00
|
|
|
var buf [129]byte
|
|
|
|
return append(buf[:0], pub.publicKey...)
|
2022-07-15 16:42:39 +08:00
|
|
|
}
|
|
|
|
|
2025-03-14 15:26:34 +08:00
|
|
|
// MarshalASN1 marshal signature master public key to asn.1 format data according
|
2022-07-15 16:42:39 +08:00
|
|
|
// SM9 cryptographic algorithm application specification
|
|
|
|
func (pub *SignMasterPublicKey) MarshalASN1() ([]byte, error) {
|
|
|
|
var b cryptobyte.Builder
|
2025-03-25 11:10:53 +08:00
|
|
|
b.AddASN1BitString(pub.publicKey)
|
2022-07-15 16:42:39 +08:00
|
|
|
return b.Bytes()
|
|
|
|
}
|
|
|
|
|
2025-03-14 15:26:34 +08:00
|
|
|
// MarshalCompressedASN1 marshal signature master public key to asn.1 format data according
|
2022-08-09 10:01:34 +08:00
|
|
|
// SM9 cryptographic algorithm application specification, the curve point is in compressed form.
|
|
|
|
func (pub *SignMasterPublicKey) MarshalCompressedASN1() ([]byte, error) {
|
|
|
|
var b cryptobyte.Builder
|
2025-03-25 11:10:53 +08:00
|
|
|
b.AddASN1BitString(pub.publicKey)
|
2022-08-09 10:01:34 +08:00
|
|
|
return b.Bytes()
|
|
|
|
}
|
|
|
|
|
2025-03-14 15:26:34 +08:00
|
|
|
// UnmarshalSignMasterPublicKeyRaw unmarsal raw bytes data to signature master public key
|
2025-03-13 16:50:28 +08:00
|
|
|
func UnmarshalSignMasterPublicKeyRaw(bytes []byte) (pub *SignMasterPublicKey, err error) {
|
|
|
|
pub = new(SignMasterPublicKey)
|
2025-03-25 11:10:53 +08:00
|
|
|
pub.internal = new(sm9.SignMasterPublicKey)
|
|
|
|
err = pub.internal.UnmarshalRaw(bytes)
|
|
|
|
pub.publicKey = pub.internal.Bytes()
|
2025-03-13 16:50:28 +08:00
|
|
|
return
|
2022-10-22 15:49:01 +08:00
|
|
|
}
|
|
|
|
|
2025-03-14 15:26:34 +08:00
|
|
|
// UnmarshalSignMasterPublicKeyASN1 unmarsal der data to signature master public key
|
2025-03-13 16:50:28 +08:00
|
|
|
func UnmarshalSignMasterPublicKeyASN1(der []byte) (*SignMasterPublicKey, error) {
|
2022-07-15 16:42:39 +08:00
|
|
|
var bytes []byte
|
2022-10-24 16:09:12 +08:00
|
|
|
var inner cryptobyte.String
|
2022-07-15 16:42:39 +08:00
|
|
|
input := cryptobyte.String(der)
|
2022-10-24 16:09:12 +08:00
|
|
|
if der[0] == 0x30 {
|
|
|
|
if !input.ReadASN1(&inner, cryptobyte_asn1.SEQUENCE) ||
|
|
|
|
!input.Empty() ||
|
|
|
|
!inner.ReadASN1BitStringAsBytes(&bytes) ||
|
|
|
|
!inner.Empty() {
|
2025-03-14 15:26:34 +08:00
|
|
|
return nil, errors.New("sm9: invalid ASN.1 data for signature master public key")
|
2022-10-24 16:09:12 +08:00
|
|
|
}
|
|
|
|
} else if !input.ReadASN1BitStringAsBytes(&bytes) || !input.Empty() {
|
2025-03-14 15:26:34 +08:00
|
|
|
return nil, errors.New("sm9: invalid ASN.1 data for signature master public key")
|
2022-07-15 16:42:39 +08:00
|
|
|
}
|
2025-03-13 16:50:28 +08:00
|
|
|
return UnmarshalSignMasterPublicKeyRaw(bytes)
|
2022-10-22 15:49:01 +08:00
|
|
|
}
|
|
|
|
|
2025-03-13 16:50:28 +08:00
|
|
|
// ParseSignMasterPublicKeyPEM just for GMSSL, there are no Algorithm pkix.AlgorithmIdentifier
|
|
|
|
func ParseSignMasterPublicKeyPEM(data []byte) (*SignMasterPublicKey, error) {
|
2022-10-22 15:49:01 +08:00
|
|
|
block, _ := pem.Decode([]byte(data))
|
|
|
|
if block == nil {
|
2025-03-13 16:50:28 +08:00
|
|
|
return nil, errors.New("sm9: failed to parse PEM block")
|
2022-10-22 15:49:01 +08:00
|
|
|
}
|
2025-03-13 16:50:28 +08:00
|
|
|
return UnmarshalSignMasterPublicKeyASN1(block.Bytes)
|
2022-07-15 16:42:39 +08:00
|
|
|
}
|
|
|
|
|
2025-03-25 11:10:53 +08:00
|
|
|
func (priv *SignPrivateKey) Equal(x crypto.PrivateKey) bool {
|
|
|
|
xx, ok := x.(*SignPrivateKey)
|
|
|
|
if !ok {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
return subtle.ConstantTimeCompare(priv.privateKey, xx.privateKey) == 1
|
2025-03-13 13:46:14 +08:00
|
|
|
}
|
|
|
|
|
2025-03-25 14:58:16 +08:00
|
|
|
// Public returns the public key corresponding to the private key.
|
|
|
|
// Just to satisfy [crypto.Signer] interface.
|
|
|
|
func (priv *SignPrivateKey) Public() crypto.PublicKey {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2025-03-13 13:46:14 +08:00
|
|
|
func (priv *SignPrivateKey) Bytes() []byte {
|
2025-03-25 11:10:53 +08:00
|
|
|
var buf [65]byte
|
|
|
|
return append(buf[:0], priv.privateKey...)
|
2025-03-13 13:46:14 +08:00
|
|
|
}
|
|
|
|
|
2025-03-14 15:26:34 +08:00
|
|
|
// MasterPublic returns the signature master public key corresponding to priv.
|
2022-07-15 16:42:39 +08:00
|
|
|
func (priv *SignPrivateKey) MasterPublic() *SignMasterPublicKey {
|
2025-03-25 11:10:53 +08:00
|
|
|
masterKey := priv.internal.MasterPublic()
|
|
|
|
return &SignMasterPublicKey{internal: masterKey, publicKey: masterKey.Bytes()}
|
2022-07-15 16:42:39 +08:00
|
|
|
}
|
|
|
|
|
2025-03-14 15:26:34 +08:00
|
|
|
// MarshalASN1 marshal signature private key to asn.1 format data according
|
2022-07-15 16:42:39 +08:00
|
|
|
// SM9 cryptographic algorithm application specification
|
|
|
|
func (priv *SignPrivateKey) MarshalASN1() ([]byte, error) {
|
|
|
|
var b cryptobyte.Builder
|
2025-03-25 11:10:53 +08:00
|
|
|
b.AddASN1BitString(priv.privateKey)
|
2022-07-15 16:42:39 +08:00
|
|
|
return b.Bytes()
|
|
|
|
}
|
|
|
|
|
2025-03-14 15:26:34 +08:00
|
|
|
// MarshalCompressedASN1 marshal signature private key to asn.1 format data according
|
2022-08-09 10:01:34 +08:00
|
|
|
// SM9 cryptographic algorithm application specification, the curve point is in compressed form.
|
|
|
|
func (priv *SignPrivateKey) MarshalCompressedASN1() ([]byte, error) {
|
|
|
|
var b cryptobyte.Builder
|
2025-03-25 11:10:53 +08:00
|
|
|
b.AddASN1BitString(priv.privateKey)
|
2022-08-09 10:01:34 +08:00
|
|
|
return b.Bytes()
|
|
|
|
}
|
|
|
|
|
2025-03-14 15:26:34 +08:00
|
|
|
// UnmarshalSignPrivateKeyRaw unmarsal raw bytes data to signature private key
|
2022-10-22 15:49:01 +08:00
|
|
|
// Note, priv's SignMasterPublicKey should be handled separately.
|
2025-03-13 16:50:28 +08:00
|
|
|
func UnmarshalSignPrivateKeyRaw(bytes []byte) (*SignPrivateKey, error) {
|
|
|
|
priv := new(SignPrivateKey)
|
2025-03-25 11:10:53 +08:00
|
|
|
priv.internal = new(sm9.SignPrivateKey)
|
|
|
|
err := priv.internal.UnmarshalRaw(bytes)
|
2025-03-13 16:50:28 +08:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
2022-10-22 15:49:01 +08:00
|
|
|
}
|
2025-03-25 11:10:53 +08:00
|
|
|
priv.privateKey = priv.internal.Bytes()
|
2025-03-13 16:50:28 +08:00
|
|
|
return priv, nil
|
2022-10-22 15:49:01 +08:00
|
|
|
}
|
|
|
|
|
2025-03-14 15:26:34 +08:00
|
|
|
// UnmarshalSignPrivateKeyASN1 unmarsal der data to signature private key
|
2022-07-15 16:42:39 +08:00
|
|
|
// Note, priv's SignMasterPublicKey should be handled separately.
|
2025-03-13 16:50:28 +08:00
|
|
|
func UnmarshalSignPrivateKeyASN1(der []byte) (*SignPrivateKey, error) {
|
2022-07-15 16:42:39 +08:00
|
|
|
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) {
|
2025-03-14 15:26:34 +08:00
|
|
|
return nil, errors.New("sm9: invalid ASN.1 data for signature private key")
|
2022-10-22 15:49:01 +08:00
|
|
|
}
|
|
|
|
if !inner.Empty() && (!inner.ReadASN1BitStringAsBytes(&pubBytes) || !inner.Empty()) {
|
2025-03-14 15:26:34 +08:00
|
|
|
return nil, errors.New("sm9: invalid ASN.1 data for signature master public key")
|
2022-10-22 15:49:01 +08:00
|
|
|
}
|
|
|
|
} else if !input.ReadASN1BitStringAsBytes(&bytes) || !input.Empty() {
|
2025-03-14 15:26:34 +08:00
|
|
|
return nil, errors.New("sm9: invalid ASN.1 data for signature private key")
|
2022-07-15 16:42:39 +08:00
|
|
|
}
|
2025-03-13 16:50:28 +08:00
|
|
|
|
|
|
|
priv, err := UnmarshalSignPrivateKeyRaw(bytes)
|
2022-07-15 16:42:39 +08:00
|
|
|
if err != nil {
|
2025-03-13 16:50:28 +08:00
|
|
|
return nil, err
|
2022-07-15 16:42:39 +08:00
|
|
|
}
|
2022-10-22 15:49:01 +08:00
|
|
|
if len(pubBytes) > 0 {
|
2025-03-13 16:50:28 +08:00
|
|
|
masterPK, err := UnmarshalSignMasterPublicKeyRaw(pubBytes)
|
2022-10-22 15:49:01 +08:00
|
|
|
if err != nil {
|
2025-03-13 16:50:28 +08:00
|
|
|
return nil, err
|
2022-10-22 15:49:01 +08:00
|
|
|
}
|
2025-03-25 11:10:53 +08:00
|
|
|
priv.internal.SetMasterPublicKey(masterPK.internal)
|
2022-10-22 15:49:01 +08:00
|
|
|
}
|
2025-03-13 16:50:28 +08:00
|
|
|
return priv, nil
|
2022-07-15 16:42:39 +08:00
|
|
|
}
|
|
|
|
|
2025-03-14 15:26:34 +08:00
|
|
|
// GenerateEncryptMasterKey generates an encryption master key pair.
|
2022-07-15 16:42:39 +08:00
|
|
|
func GenerateEncryptMasterKey(rand io.Reader) (*EncryptMasterPrivateKey, error) {
|
2025-03-13 13:46:14 +08:00
|
|
|
priv, err := sm9.GenerateEncryptMasterKey(rand)
|
2022-07-15 16:42:39 +08:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2025-03-25 11:10:53 +08:00
|
|
|
master := &EncryptMasterPrivateKey{privateKey: priv.Bytes(), internal: priv}
|
|
|
|
master.publicKey = &EncryptMasterPublicKey{publicKey: priv.PublicKey().Bytes(), internal: priv.PublicKey()}
|
|
|
|
return master, nil
|
2025-03-13 13:46:14 +08:00
|
|
|
}
|
2022-07-15 16:42:39 +08:00
|
|
|
|
2025-03-13 13:46:14 +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 {
|
2025-03-25 11:10:53 +08:00
|
|
|
var buf [32]byte
|
|
|
|
return append(buf[:0], master.privateKey...)
|
2025-03-13 13:46:14 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// Equal compares the receiver EncryptMasterPrivateKey with another EncryptMasterPrivateKey
|
|
|
|
// and returns true if they are equal, otherwise it returns false.
|
2025-03-25 11:10:53 +08:00
|
|
|
func (master *EncryptMasterPrivateKey) Equal(x crypto.PrivateKey) bool {
|
|
|
|
xx, ok := x.(*EncryptMasterPrivateKey)
|
|
|
|
if !ok {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
return subtle.ConstantTimeCompare(master.privateKey, xx.privateKey) == 1
|
2022-07-15 16:42:39 +08:00
|
|
|
}
|
|
|
|
|
2025-03-14 15:26:34 +08:00
|
|
|
// GenerateUserKey generate an encryption private key for the given user.
|
2022-07-15 16:42:39 +08:00
|
|
|
func (master *EncryptMasterPrivateKey) GenerateUserKey(uid []byte, hid byte) (*EncryptPrivateKey, error) {
|
2025-03-25 11:10:53 +08:00
|
|
|
priv, err := master.internal.GenerateUserKey(uid, hid)
|
2022-11-25 10:11:46 +08:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2025-03-25 11:10:53 +08:00
|
|
|
return &EncryptPrivateKey{privateKey: priv.Bytes(), internal: priv}, nil
|
2022-07-15 16:42:39 +08:00
|
|
|
}
|
|
|
|
|
2025-03-14 15:26:34 +08:00
|
|
|
// Public returns the public key corresponding to the private key.
|
2025-03-25 11:10:53 +08:00
|
|
|
func (master *EncryptMasterPrivateKey) PublicKey() *EncryptMasterPublicKey {
|
|
|
|
return master.publicKey
|
|
|
|
}
|
|
|
|
|
|
|
|
func (master *EncryptMasterPrivateKey) Public() crypto.PublicKey {
|
|
|
|
return master.PublicKey()
|
2022-07-15 16:42:39 +08:00
|
|
|
}
|
|
|
|
|
2025-03-14 15:26:34 +08:00
|
|
|
// MarshalASN1 marshal encryption master private key to asn.1 format data according
|
2022-07-15 16:42:39 +08:00
|
|
|
// SM9 cryptographic algorithm application specification
|
|
|
|
func (master *EncryptMasterPrivateKey) MarshalASN1() ([]byte, error) {
|
2025-03-25 11:10:53 +08:00
|
|
|
d := new(big.Int).SetBytes(master.privateKey)
|
2022-07-15 16:42:39 +08:00
|
|
|
var b cryptobyte.Builder
|
2025-03-13 13:46:14 +08:00
|
|
|
b.AddASN1BigInt(d)
|
2022-07-15 16:42:39 +08:00
|
|
|
return b.Bytes()
|
|
|
|
}
|
|
|
|
|
2025-03-14 15:26:34 +08:00
|
|
|
// UnmarshalEncryptMasterPrivateKeyASN1 unmarsal der data to master encryption private key
|
2025-03-13 16:50:28 +08:00
|
|
|
func UnmarshalEncryptMasterPrivateKeyASN1(der []byte) (*EncryptMasterPrivateKey, error) {
|
2022-07-15 16:42:39 +08:00
|
|
|
input := cryptobyte.String(der)
|
|
|
|
d := &big.Int{}
|
2022-10-24 11:00:13 +08:00
|
|
|
var inner cryptobyte.String
|
|
|
|
var pubBytes []byte
|
|
|
|
if der[0] == 0x30 {
|
|
|
|
if !input.ReadASN1(&inner, cryptobyte_asn1.SEQUENCE) ||
|
|
|
|
!input.Empty() ||
|
|
|
|
!inner.ReadASN1Integer(d) {
|
2025-03-14 15:26:34 +08:00
|
|
|
return nil, errors.New("sm9: invalid ASN.1 data for encryption master private key")
|
2022-10-24 11:00:13 +08:00
|
|
|
}
|
|
|
|
// Just parse it, did't validate it
|
|
|
|
if !inner.Empty() && (!inner.ReadASN1BitStringAsBytes(&pubBytes) || !inner.Empty()) {
|
2025-03-14 15:26:34 +08:00
|
|
|
return nil, errors.New("sm9: invalid ASN.1 data for encryption master public key")
|
2022-10-24 11:00:13 +08:00
|
|
|
}
|
|
|
|
} else if !input.ReadASN1Integer(d) || !input.Empty() {
|
2025-03-14 15:26:34 +08:00
|
|
|
return nil, errors.New("sm9: invalid ASN.1 data for encryption master private key")
|
2022-07-15 16:42:39 +08:00
|
|
|
}
|
2025-03-13 16:50:28 +08:00
|
|
|
privateKey, err := sm9.NewEncryptMasterPrivateKey(d.Bytes())
|
2022-11-25 10:11:46 +08:00
|
|
|
if err != nil {
|
2025-03-13 16:50:28 +08:00
|
|
|
return nil, err
|
2022-11-25 10:11:46 +08:00
|
|
|
}
|
2025-04-15 15:41:20 +08:00
|
|
|
|
|
|
|
master := &EncryptMasterPrivateKey{privateKey: privateKey.Bytes(), internal: privateKey}
|
|
|
|
master.publicKey = &EncryptMasterPublicKey{
|
|
|
|
publicKey: privateKey.PublicKey().Bytes(),
|
|
|
|
internal: privateKey.PublicKey(),
|
|
|
|
}
|
|
|
|
return master, nil
|
2022-07-15 16:42:39 +08:00
|
|
|
}
|
|
|
|
|
2025-03-13 13:46:14 +08:00
|
|
|
// Equal compares the receiver EncryptMasterPublicKey with another EncryptMasterPublicKey
|
|
|
|
// and returns true if they are equal, otherwise it returns false.
|
2025-03-25 11:10:53 +08:00
|
|
|
func (pub *EncryptMasterPublicKey) Equal(x crypto.PublicKey) bool {
|
|
|
|
xx, ok := x.(*EncryptMasterPublicKey)
|
|
|
|
if !ok {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
return subtle.ConstantTimeCompare(pub.publicKey, xx.publicKey) == 1
|
2022-07-28 10:01:30 +08:00
|
|
|
}
|
|
|
|
|
2025-03-13 13:46:14 +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 {
|
2025-03-25 11:10:53 +08:00
|
|
|
var buf [65]byte
|
|
|
|
return append(buf[:0], pub.publicKey...)
|
2022-07-15 16:42:39 +08:00
|
|
|
}
|
|
|
|
|
2025-03-14 15:26:34 +08:00
|
|
|
// MarshalASN1 marshal encryption master public key to asn.1 format data according
|
2022-07-15 16:42:39 +08:00
|
|
|
// SM9 cryptographic algorithm application specification
|
|
|
|
func (pub *EncryptMasterPublicKey) MarshalASN1() ([]byte, error) {
|
|
|
|
var b cryptobyte.Builder
|
2025-03-25 11:10:53 +08:00
|
|
|
b.AddASN1BitString(pub.publicKey)
|
2022-07-15 16:42:39 +08:00
|
|
|
return b.Bytes()
|
|
|
|
}
|
|
|
|
|
2025-03-14 15:26:34 +08:00
|
|
|
// MarshalCompressedASN1 marshal encryption master public key to asn.1 format data according
|
2022-08-09 10:01:34 +08:00
|
|
|
// SM9 cryptographic algorithm application specification, the curve point is in compressed form.
|
|
|
|
func (pub *EncryptMasterPublicKey) MarshalCompressedASN1() ([]byte, error) {
|
|
|
|
var b cryptobyte.Builder
|
2025-03-25 11:10:53 +08:00
|
|
|
b.AddASN1BitString(pub.publicKey)
|
2022-08-09 10:01:34 +08:00
|
|
|
return b.Bytes()
|
|
|
|
}
|
|
|
|
|
2025-03-14 15:26:34 +08:00
|
|
|
// UnmarshalEncryptMasterPublicKeyRaw unmarsal raw bytes data to encryption master public key
|
2025-03-13 16:50:28 +08:00
|
|
|
func UnmarshalEncryptMasterPublicKeyRaw(bytes []byte) (*EncryptMasterPublicKey, error) {
|
|
|
|
pub := new(EncryptMasterPublicKey)
|
2025-03-25 11:10:53 +08:00
|
|
|
pub.internal = new(sm9.EncryptMasterPublicKey)
|
|
|
|
err := pub.internal.UnmarshalRaw(bytes)
|
2025-03-13 16:50:28 +08:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
2022-10-22 15:49:01 +08:00
|
|
|
}
|
2025-03-25 11:10:53 +08:00
|
|
|
pub.publicKey = pub.internal.Bytes()
|
2025-03-13 16:50:28 +08:00
|
|
|
return pub, nil
|
2022-10-22 15:49:01 +08:00
|
|
|
}
|
|
|
|
|
2025-03-13 16:50:28 +08:00
|
|
|
// ParseEncryptMasterPublicKeyPEM just for GMSSL, there are no Algorithm pkix.AlgorithmIdentifier
|
|
|
|
func ParseEncryptMasterPublicKeyPEM(data []byte) (*EncryptMasterPublicKey, error) {
|
2022-10-22 15:49:01 +08:00
|
|
|
block, _ := pem.Decode([]byte(data))
|
|
|
|
if block == nil {
|
2025-03-13 16:50:28 +08:00
|
|
|
return nil, errors.New("sm9: failed to parse PEM block")
|
2022-10-22 15:49:01 +08:00
|
|
|
}
|
2025-03-13 16:50:28 +08:00
|
|
|
return UnmarshalEncryptMasterPublicKeyASN1(block.Bytes)
|
2022-10-22 15:49:01 +08:00
|
|
|
}
|
|
|
|
|
2025-03-14 15:26:34 +08:00
|
|
|
// UnmarshalEncryptMasterPublicKeyASN1 unmarsal der data to encryption master public key
|
2025-03-13 16:50:28 +08:00
|
|
|
func UnmarshalEncryptMasterPublicKeyASN1(der []byte) (*EncryptMasterPublicKey, error) {
|
2022-07-15 16:42:39 +08:00
|
|
|
var bytes []byte
|
2022-10-24 16:09:12 +08:00
|
|
|
var inner cryptobyte.String
|
2022-07-15 16:42:39 +08:00
|
|
|
input := cryptobyte.String(der)
|
2022-10-24 16:09:12 +08:00
|
|
|
if der[0] == 0x30 {
|
|
|
|
if !input.ReadASN1(&inner, cryptobyte_asn1.SEQUENCE) ||
|
|
|
|
!input.Empty() ||
|
|
|
|
!inner.ReadASN1BitStringAsBytes(&bytes) ||
|
|
|
|
!inner.Empty() {
|
2025-03-14 15:26:34 +08:00
|
|
|
return nil, errors.New("sm9: invalid ASN.1 data for encryption master public key")
|
2022-10-24 16:09:12 +08:00
|
|
|
}
|
|
|
|
} else if !input.ReadASN1BitStringAsBytes(&bytes) || !input.Empty() {
|
2025-03-14 15:26:34 +08:00
|
|
|
return nil, errors.New("sm9: invalid ASN.1 data for encryption master public key")
|
2022-07-15 16:42:39 +08:00
|
|
|
}
|
2025-03-13 16:50:28 +08:00
|
|
|
return UnmarshalEncryptMasterPublicKeyRaw(bytes)
|
2022-07-15 16:42:39 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// MasterPublic returns the master public key corresponding to priv.
|
|
|
|
func (priv *EncryptPrivateKey) MasterPublic() *EncryptMasterPublicKey {
|
2025-03-25 11:10:53 +08:00
|
|
|
master := priv.internal.MasterPublic()
|
|
|
|
return &EncryptMasterPublicKey{publicKey: master.Bytes(), internal: master}
|
2022-07-15 16:42:39 +08:00
|
|
|
}
|
|
|
|
|
2025-03-14 15:26:34 +08:00
|
|
|
// MarshalASN1 marshal encryption private key to asn.1 format data according
|
2022-07-15 16:42:39 +08:00
|
|
|
// SM9 cryptographic algorithm application specification
|
|
|
|
func (priv *EncryptPrivateKey) MarshalASN1() ([]byte, error) {
|
|
|
|
var b cryptobyte.Builder
|
2025-03-25 11:10:53 +08:00
|
|
|
b.AddASN1BitString(priv.privateKey)
|
2022-07-15 16:42:39 +08:00
|
|
|
return b.Bytes()
|
|
|
|
}
|
|
|
|
|
2025-03-14 15:26:34 +08:00
|
|
|
// MarshalCompressedASN1 marshal encryption private key to asn.1 format data according
|
2022-08-09 10:01:34 +08:00
|
|
|
// SM9 cryptographic algorithm application specification, the curve point is in compressed form.
|
|
|
|
func (priv *EncryptPrivateKey) MarshalCompressedASN1() ([]byte, error) {
|
|
|
|
var b cryptobyte.Builder
|
2025-03-25 11:10:53 +08:00
|
|
|
b.AddASN1BitString(priv.privateKey)
|
2022-08-09 10:01:34 +08:00
|
|
|
return b.Bytes()
|
|
|
|
}
|
|
|
|
|
2025-03-14 15:26:34 +08:00
|
|
|
// UnmarshalEncryptPrivateKeyRaw unmarsal raw bytes data to encryption private key
|
2022-10-22 15:49:01 +08:00
|
|
|
// Note, priv's EncryptMasterPublicKey should be handled separately.
|
2025-03-13 16:50:28 +08:00
|
|
|
func UnmarshalEncryptPrivateKeyRaw(bytes []byte) (*EncryptPrivateKey, error) {
|
|
|
|
priv := new(EncryptPrivateKey)
|
2025-03-25 11:10:53 +08:00
|
|
|
priv.internal = new(sm9.EncryptPrivateKey)
|
|
|
|
err := priv.internal.UnmarshalRaw(bytes)
|
2025-03-13 16:50:28 +08:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
2022-10-22 15:49:01 +08:00
|
|
|
}
|
2025-03-25 11:10:53 +08:00
|
|
|
priv.privateKey = priv.internal.Bytes()
|
2025-03-13 16:50:28 +08:00
|
|
|
return priv, nil
|
2022-10-22 15:49:01 +08:00
|
|
|
}
|
|
|
|
|
2025-03-14 15:26:34 +08:00
|
|
|
// UnmarshalEncryptPrivateKeyASN1 unmarsal der data to encryption private key
|
2022-07-15 16:42:39 +08:00
|
|
|
// Note, priv's EncryptMasterPublicKey should be handled separately.
|
2025-03-13 16:50:28 +08:00
|
|
|
func UnmarshalEncryptPrivateKeyASN1(der []byte) (*EncryptPrivateKey, error) {
|
2022-07-15 16:42:39 +08:00
|
|
|
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) {
|
2025-03-14 15:26:34 +08:00
|
|
|
return nil, errors.New("sm9: invalid ASN.1 data for encryption private key")
|
2022-10-22 15:49:01 +08:00
|
|
|
}
|
|
|
|
if !inner.Empty() && (!inner.ReadASN1BitStringAsBytes(&pubBytes) || !inner.Empty()) {
|
2025-03-14 15:26:34 +08:00
|
|
|
return nil, errors.New("sm9: invalid ASN.1 data for encryption master public key")
|
2022-10-22 15:49:01 +08:00
|
|
|
}
|
|
|
|
} else if !input.ReadASN1BitStringAsBytes(&bytes) || !input.Empty() {
|
2025-03-14 15:26:34 +08:00
|
|
|
return nil, errors.New("sm9: invalid ASN.1 data for encryption private key")
|
2022-07-15 16:42:39 +08:00
|
|
|
}
|
2025-03-13 16:50:28 +08:00
|
|
|
priv, err := UnmarshalEncryptPrivateKeyRaw(bytes)
|
2022-07-15 16:42:39 +08:00
|
|
|
if err != nil {
|
2025-03-13 16:50:28 +08:00
|
|
|
return nil, err
|
2022-07-15 16:42:39 +08:00
|
|
|
}
|
2022-10-22 15:49:01 +08:00
|
|
|
if len(pubBytes) > 0 {
|
2025-03-13 16:50:28 +08:00
|
|
|
masterPK, err := UnmarshalEncryptMasterPublicKeyRaw(pubBytes)
|
2022-10-22 15:49:01 +08:00
|
|
|
if err != nil {
|
2025-03-13 16:50:28 +08:00
|
|
|
return nil, err
|
2022-10-22 15:49:01 +08:00
|
|
|
}
|
2025-03-25 11:10:53 +08:00
|
|
|
priv.internal.SetMasterPublicKey(masterPK.internal)
|
2022-10-22 15:49:01 +08:00
|
|
|
}
|
2025-03-13 16:50:28 +08:00
|
|
|
return priv, nil
|
2022-07-15 16:42:39 +08:00
|
|
|
}
|
2025-03-13 13:46:14 +08:00
|
|
|
|
|
|
|
// Equal compares the receiver EncryptPrivateKey with another EncryptPrivateKey x
|
|
|
|
// and returns true if they are equal, otherwise false.
|
2025-03-25 11:10:53 +08:00
|
|
|
func (priv *EncryptPrivateKey) Equal(x crypto.PrivateKey) bool {
|
|
|
|
xx, ok := x.(*EncryptPrivateKey)
|
|
|
|
if !ok {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
return subtle.ConstantTimeCompare(priv.privateKey, xx.privateKey) == 1
|
2025-03-13 13:46:14 +08:00
|
|
|
}
|
|
|
|
|
2025-03-25 14:58:16 +08:00
|
|
|
// Public returns the public key corresponding to the private key.
|
|
|
|
// Just to satisfy [crypto.Decrypter] interface.
|
|
|
|
func (priv *EncryptPrivateKey) Public() crypto.PublicKey {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2025-03-13 13:46:14 +08:00
|
|
|
// 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 {
|
2025-03-25 11:10:53 +08:00
|
|
|
var buf [129]byte
|
|
|
|
return append(buf[:0], priv.privateKey...)
|
2025-03-13 13:46:14 +08:00
|
|
|
}
|