gitee.com/lh-her-team/common@v1.5.1/opencrypto/gmssl/sm2/sm2key.go (about) 1 package sm2 2 3 import "C" 4 import ( 5 "crypto/elliptic" 6 "crypto/x509/pkix" 7 "encoding/asn1" 8 "encoding/pem" 9 "errors" 10 "fmt" 11 12 "gitee.com/lh-her-team/common/opencrypto/utils" 13 14 "gitee.com/lh-her-team/common/opencrypto/gmssl/gmssl" 15 ) 16 17 type publicKeyInfo struct { 18 Raw asn1.RawContent 19 Algorithm pkix.AlgorithmIdentifier 20 PublicKey asn1.BitString 21 } 22 23 // MarshalPublicKey public key conversion 24 func MarshalPublicKey(key *PublicKey) ([]byte, error) { 25 if key == nil { 26 return nil, errors.New("input SM2 public key is null") 27 } 28 var pkPem string 29 var err error 30 if len(key.pkPem) != 0 { 31 pkPem = key.pkPem 32 } else { 33 pkPem, err = key.GetPEM() 34 if err != nil { 35 return nil, err 36 } 37 } 38 p, _ := pem.Decode([]byte(pkPem)) 39 if p == nil { 40 return nil, errors.New("invalid public key pem") 41 } 42 return p.Bytes, nil 43 } 44 45 func UnmarshalPublicKey(der []byte) (*PublicKey, error) { 46 if der == nil { 47 return nil, errors.New("input DER is null") 48 } 49 var pki publicKeyInfo 50 if rest, err := asn1.Unmarshal(der, &pki); err != nil { 51 return nil, err 52 } else if len(rest) != 0 { 53 return nil, errors.New("x509: trailing data after ASN.1 of public-key") 54 } 55 if !pki.Algorithm.Algorithm.Equal(utils.OidSM2) { 56 return nil, fmt.Errorf("fail to unmarshal public key: curve is not SM2P256v1") 57 } 58 asn1Data := pki.PublicKey.RightAlign() 59 x, y := elliptic.Unmarshal(utils.P256Sm2(), asn1Data) 60 if x == nil || y == nil { 61 return nil, errors.New("x509: failed to unmarshal elliptic curve point") 62 } 63 pkPem, err := PublicKeyDerToPEM(der) 64 if err != nil { 65 return nil, err 66 } 67 return PublicKeyFromPEM(pkPem) 68 } 69 70 func PublicKeyDerToPEM(der []byte) (string, error) { 71 if der == nil { 72 return "", errors.New("der is nil") 73 } 74 pemPK := pem.EncodeToMemory( 75 &pem.Block{ 76 Type: "PUBLIC KEY", 77 Bytes: der, 78 }) 79 return string(pemPK), nil 80 } 81 82 func PublicKeyFromPEM(pkPEM string) (*PublicKey, error) { 83 pk, err := gmssl.NewPublicKeyFromPEM(pkPEM) 84 if err != nil { 85 return nil, err 86 } 87 return &PublicKey{PublicKey: pk, pkPem: pkPEM}, nil 88 } 89 90 func PublicKeyToPEM(key *PublicKey) (string, error) { 91 return key.GetPEM() 92 } 93 94 // MarshalPrivateKey private key conversion 95 func MarshalPrivateKey(key *PrivateKey) ([]byte, error) { 96 if key == nil { 97 return nil, errors.New("input SM2 private key is null") 98 } 99 var skPem string 100 var err error 101 if len(key.skPem) != 0 { 102 skPem = key.skPem 103 } else { 104 skPem, err = PrivateKeyToPEM(key) 105 if err != nil { 106 return nil, err 107 } 108 } 109 p, _ := pem.Decode([]byte(skPem)) 110 if p == nil { 111 return nil, errors.New("invalid private key pem") 112 } 113 return p.Bytes, nil 114 } 115 116 func PrivateKeyDerToPEM(der []byte) (string, error) { 117 if der == nil { 118 return "", errors.New("input der is nil") 119 } 120 skPEM := pem.EncodeToMemory(&pem.Block{ 121 Type: "PRIVATE KEY", 122 Bytes: der, 123 }) 124 //check 125 if _, err := PrivateKeyFromPEM(string(skPEM), ""); err != nil { 126 return "", err 127 } 128 return string(skPEM), nil 129 } 130 131 func PrivateKeyFromPEM(skPEM string, pass string) (*PrivateKey, error) { 132 sk, err := gmssl.NewPrivateKeyFromPEM(skPEM, pass) 133 if err != nil { 134 return nil, err 135 } 136 pkPem, err := sk.GetPublicKeyPEM() 137 if err != nil { 138 return nil, err 139 } 140 pub, err := PublicKeyFromPEM(pkPem) 141 if err != nil { 142 return nil, err 143 } 144 return &PrivateKey{PrivateKey: sk, skPem: skPEM, Pub: *pub}, nil 145 } 146 147 func PrivateKeyToPEM(key *PrivateKey) (string, error) { 148 return key.PrivateKey.GetUnencryptedPEM() 149 } 150 151 func UnmarshalPrivateKey(der []byte) (*PrivateKey, error) { 152 return UnmarshalPrivateKeyWithCurve(nil, der) 153 } 154 155 func UnmarshalPrivateKeyWithCurve(namedCurveOID *asn1.ObjectIdentifier, der []byte) (*PrivateKey, error) { 156 skPem, err := PrivateKeyDerToPEM(der) 157 if err != nil { 158 return nil, err 159 } 160 return PrivateKeyFromPEM(skPem, "") 161 }