diff --git a/sm2/p256_asm.go b/sm2/p256_asm.go index f5bd1ab..f626e63 100644 --- a/sm2/p256_asm.go +++ b/sm2/p256_asm.go @@ -118,7 +118,7 @@ var ( } ) -// Inverse, implements invertible interface, need to test this function's correctness +// Inverse, implements invertible interface, used by Sign() // n-2 = // 1111111111111111111111111111111011111111111111111111111111111111 // 1111111111111111111111111111111111111111111111111111111111111111 diff --git a/sm2/sm2.go b/sm2/sm2.go index 069b460..4a2cd49 100644 --- a/sm2/sm2.go +++ b/sm2/sm2.go @@ -43,6 +43,10 @@ type PrivateKey struct { ecdsa.PrivateKey } +type ecdsaSignature struct { + R, S *big.Int +} + // Sign signs digest with priv, reading randomness from rand. The opts argument // is not currently used but, in keeping with the crypto.Signer interface, // should be the hash function used to digest the message. @@ -59,6 +63,16 @@ func (priv *PrivateKey) Sign(rand io.Reader, digest []byte, opts crypto.SignerOp return asn1.Marshal(ecdsaSignature{r, s}) } +// SignWithSM2 signs uid, msg with SignWithSM2 method. +func (priv *PrivateKey) SignWithSM2(rand io.Reader, uid, msg []byte) ([]byte, error) { + r, s, err := SignWithSM2(rand, &priv.PrivateKey, uid, msg) + if err != nil { + return nil, err + } + + return asn1.Marshal(ecdsaSignature{r, s}) +} + var ( one = new(big.Int).SetInt64(1) initonce sync.Once diff --git a/sm2/x509.go b/smx509/x509.go similarity index 94% rename from sm2/x509.go rename to smx509/x509.go index 3158a67..93febaf 100644 --- a/sm2/x509.go +++ b/smx509/x509.go @@ -1,4 +1,4 @@ -package sm2 +package smx509 import ( "crypto" @@ -16,7 +16,7 @@ import ( "strconv" "strings" - "github.com/emmansun/gmsm/sm3" + "github.com/emmansun/gmsm/sm2" ) // pkixPublicKey reflects a PKIX public key structure. See SubjectPublicKeyInfo @@ -38,12 +38,10 @@ type pkcs1PublicKey struct { E int } -type dsaSignature struct { +type ecdsaSignature struct { R, S *big.Int } -type ecdsaSignature dsaSignature - // http://gmssl.org/docs/oid.html var ( oidNamedCurveP224 = asn1.ObjectIdentifier{1, 3, 132, 0, 33} @@ -67,7 +65,7 @@ func oidFromNamedCurve(curve elliptic.Curve) (asn1.ObjectIdentifier, bool) { return oidNamedCurveP384, true case elliptic.P521(): return oidNamedCurveP521, true - case P256(): + case sm2.P256(): return oidNamedCurveP256SM2, true } @@ -85,7 +83,7 @@ func namedCurveFromOID(oid asn1.ObjectIdentifier) elliptic.Curve { case oid.Equal(oidNamedCurveP521): return elliptic.P521() case oid.Equal(oidNamedCurveP256SM2): - return P256() + return sm2.P256() } return nil } @@ -124,7 +122,7 @@ func ParsePKIXPublicKey(derBytes []byte) (interface{}, error) { if !namedCurveOID.Equal(oidNamedCurveP256SM2) { return x509.ParsePKIXPublicKey(derBytes) } - namedCurve := P256() + namedCurve := sm2.P256() x, y := elliptic.Unmarshal(namedCurve, asn1Data) if x == nil { return nil, errors.New("x509: failed to unmarshal elliptic curve point") @@ -145,7 +143,7 @@ func ParsePKIXPublicKey(derBytes []byte) (interface{}, error) { // This kind of key is commonly encoded in PEM blocks of type "PUBLIC KEY". func MarshalPKIXPublicKey(pub interface{}) ([]byte, error) { ecdPub, ok := pub.(*ecdsa.PublicKey) - if !ok || ecdPub.Curve != P256() { + if !ok || ecdPub.Curve != sm2.P256() { return x509.MarshalPKIXPublicKey(pub) } @@ -197,7 +195,7 @@ func CreateCertificateRequest(rand io.Reader, template *x509.CertificateRequest, if !ok { return nil, errors.New("x509: certificate private key does not implement crypto.Signer") } - privKey, ok := key.(*PrivateKey) + privKey, ok := key.(*sm2.PrivateKey) if !ok { return x509.CreateCertificateRequest(rand, template, priv) } @@ -338,17 +336,8 @@ func CreateCertificateRequest(rand io.Reader, template *x509.CertificateRequest, tbsCSR.Raw = tbsCSRContents signed := tbsCSRContents - za, err := CalculateZA(&privKey.PublicKey, defaultUID) //Emman, use template.Subject as UID? - if err != nil { - return - } - h := sm3.New() - h.Write(za) - h.Write(signed) - signed = h.Sum(nil) - var signature []byte - signature, err = privKey.Sign(rand, signed, nil) + signature, err := privKey.SignWithSM2(rand, nil, signed) if err != nil { return } @@ -739,7 +728,7 @@ func getPublicKeyAlgorithmFromOID(oid asn1.ObjectIdentifier) x509.PublicKeyAlgor func CheckSignature(c *x509.CertificateRequest) error { if c.PublicKeyAlgorithm == x509.ECDSA { pub, ok := c.PublicKey.(*ecdsa.PublicKey) - if ok && strings.EqualFold(P256().Params().Name, pub.Curve.Params().Name) { + if ok && strings.EqualFold(sm2.P256().Params().Name, pub.Curve.Params().Name) { return checkSignature(c, pub) } } @@ -759,7 +748,7 @@ func checkSignature(c *x509.CertificateRequest, publicKey *ecdsa.PublicKey) (err if ecdsaSig.R.Sign() <= 0 || ecdsaSig.S.Sign() <= 0 { return errors.New("x509: ECDSA signature contained zero or negative values") } - if !VerifyWithSM2(publicKey, nil, signed, ecdsaSig.R, ecdsaSig.S) { + if !sm2.VerifyWithSM2(publicKey, nil, signed, ecdsaSig.R, ecdsaSig.S) { return errors.New("x509: ECDSA verification failure") } return diff --git a/sm2/x509_test.go b/smx509/x509_test.go similarity index 94% rename from sm2/x509_test.go rename to smx509/x509_test.go index c32e8c1..6434333 100644 --- a/sm2/x509_test.go +++ b/smx509/x509_test.go @@ -1,4 +1,4 @@ -package sm2 +package smx509 import ( "crypto/ecdsa" @@ -13,6 +13,8 @@ import ( "fmt" "strings" "testing" + + "github.com/emmansun/gmsm/sm2" ) const publicKeyPemFromAliKms = `-----BEGIN PUBLIC KEY----- @@ -70,7 +72,7 @@ func TestParseCertificateRequest(t *testing.T) { } func TestCreateCertificateRequest(t *testing.T) { - priv, _ := GenerateKey(rand.Reader) + priv, _ := sm2.GenerateKey(rand.Reader) names := pkix.Name{CommonName: "TestName"} var template = x509.CertificateRequest{Subject: names} csrblock, err := CreateCertificateRequest(rand.Reader, &template, priv) @@ -104,7 +106,7 @@ func TestSignByAliVerifyAtLocal(t *testing.T) { pub, err := getPublicKey([]byte(publicKeyPemFromAliKmsForSign)) pub1 := pub.(*ecdsa.PublicKey) hashValue, _ := base64.StdEncoding.DecodeString(hashBase64) - result := Verify(pub1, hashValue, rs.R, rs.S) + result := sm2.Verify(pub1, hashValue, rs.R, rs.S) if !result { t.Error("Verify fail") } @@ -116,7 +118,7 @@ func TestParsePKIXPublicKey(t *testing.T) { t.Fatal(err) } pub1 := pub.(*ecdsa.PublicKey) - encrypted, err := Encrypt(rand.Reader, pub1, []byte("testfile")) + encrypted, err := sm2.Encrypt(rand.Reader, pub1, []byte("testfile")) if err != nil { t.Fatal(err) }