44 "crypto/ecdsa"
55 "crypto/rand"
66 "crypto/rsa"
7+ "crypto/sha256"
78 "crypto/x509/pkix"
89 "encoding/asn1"
910 "fmt"
@@ -14,6 +15,8 @@ import (
1415
1516 "github.com/pedroalbanese/gogost/gost3410"
1617 "github.com/pedroalbanese/gogost/gost34112012256"
18+ "github.com/tjfoc/gmsm/sm2"
19+ "github.com/tjfoc/gmsm/sm3"
1720)
1821
1922// SignatureAlgorithm represents the algorithm used to sign the certificate
@@ -188,6 +191,12 @@ func CreateCertificate(rand io.Reader, template, parent *Certificate, pub interf
188191 case * rsa.PrivateKey :
189192 sigAlg = SHA256WithRSA
190193 fmt .Printf ("DEBUG: Using RSA signature algorithm\n " )
194+ case * ecdsa.PrivateKey :
195+ sigAlg = ECDSAWithSHA256
196+ fmt .Printf ("DEBUG: Using ECDSA signature algorithm\n " )
197+ case * sm2.PrivateKey :
198+ sigAlg = ECDSAWithSHA256
199+ fmt .Printf ("DEBUG: Using SM2 signature algorithm\n " )
191200 case * gost3410.PrivateKey :
192201 // Determine GOST algorithm based on curve
193202 gostPriv := priv .(* gost3410.PrivateKey )
@@ -266,6 +275,10 @@ func MarshalPKCS8PrivateKey(key interface{}) ([]byte, error) {
266275 switch k := key .(type ) {
267276 case * rsa.PrivateKey :
268277 return marshalPKCS8PrivateKey (k )
278+ case * ecdsa.PrivateKey :
279+ return marshalECDSAPKCS8PrivateKey (k )
280+ case * sm2.PrivateKey :
281+ return marshalSM2PKCS8PrivateKey (k )
269282 case * gost3410.PrivateKey :
270283 return marshalGOSTPKCS8PrivateKey (k )
271284 default :
@@ -383,6 +396,10 @@ func signCertificate(tbsCert []byte, priv interface{}, sigAlg SignatureAlgorithm
383396 switch k := priv .(type ) {
384397 case * rsa.PrivateKey :
385398 return signWithRSA (tbsCert , k , sigAlg )
399+ case * ecdsa.PrivateKey :
400+ return signWithECDSA (tbsCert , k , sigAlg )
401+ case * sm2.PrivateKey :
402+ return signWithSM2 (tbsCert , k , sigAlg )
386403 case * gost3410.PrivateKey :
387404 return signWithGOST (tbsCert , k , sigAlg )
388405 case * gost3410.PrivateKeyReverseDigest :
@@ -397,6 +414,32 @@ func signWithRSA(data []byte, priv *rsa.PrivateKey, sigAlg SignatureAlgorithm) (
397414 return nil , fmt .Errorf ("RSA signing not implemented" )
398415}
399416
417+ func signWithECDSA (data []byte , priv * ecdsa.PrivateKey , sigAlg SignatureAlgorithm ) ([]byte , error ) {
418+ // Hash the data with SHA256 for ECDSA signing
419+ hash := sha256 .Sum256 (data )
420+
421+ // Sign the hash
422+ signature , err := ecdsa .SignASN1 (rand .Reader , priv , hash [:])
423+ if err != nil {
424+ return nil , fmt .Errorf ("failed to sign with ECDSA: %w" , err )
425+ }
426+
427+ return signature , nil
428+ }
429+
430+ func signWithSM2 (data []byte , priv * sm2.PrivateKey , sigAlg SignatureAlgorithm ) ([]byte , error ) {
431+ // Hash the data with SM3 for SM2 signing
432+ hash := sm3 .Sm3Sum (data )
433+
434+ // Sign the hash
435+ signature , err := priv .Sign (rand .Reader , hash , nil )
436+ if err != nil {
437+ return nil , fmt .Errorf ("failed to sign with SM2: %w" , err )
438+ }
439+
440+ return signature , nil
441+ }
442+
400443func signWithGOST (data []byte , priv * gost3410.PrivateKey , sigAlg SignatureAlgorithm ) ([]byte , error ) {
401444 // Use GOST signing with reverse digest
402445 signer := & gost3410.PrivateKeyReverseDigest {Prv : priv }
@@ -423,6 +466,10 @@ func getPublicKeyAlgorithm(pub interface{}) PublicKeyAlgorithm {
423466 switch pub .(type ) {
424467 case * rsa.PublicKey :
425468 return RSA
469+ case * ecdsa.PublicKey :
470+ return ECDSA
471+ case * sm2.PublicKey :
472+ return ECDSA
426473 case * gost3410.PublicKey :
427474 return GOST
428475 default :
@@ -435,6 +482,52 @@ func marshalPKCS8PrivateKey(key *rsa.PrivateKey) ([]byte, error) {
435482 return nil , fmt .Errorf ("RSA PKCS8 marshaling not implemented" )
436483}
437484
485+ func marshalECDSAPKCS8PrivateKey (key * ecdsa.PrivateKey ) ([]byte , error ) {
486+ // Create PKCS8 structure for ECDSA private key
487+ pkcs8 := struct {
488+ Version int
489+ Algorithm pkix.AlgorithmIdentifier
490+ PrivateKey []byte
491+ }{
492+ Version : 0 ,
493+ Algorithm : pkix.AlgorithmIdentifier {
494+ Algorithm : asn1.ObjectIdentifier {1 , 2 , 840 , 10045 , 2 , 1 }, // EC algorithm
495+ },
496+ PrivateKey : key .D .Bytes (),
497+ }
498+
499+ // Encode to ASN.1 DER
500+ der , err := asn1 .Marshal (pkcs8 )
501+ if err != nil {
502+ return nil , fmt .Errorf ("failed to marshal ECDSA PKCS8 private key: %w" , err )
503+ }
504+
505+ return der , nil
506+ }
507+
508+ func marshalSM2PKCS8PrivateKey (key * sm2.PrivateKey ) ([]byte , error ) {
509+ // Create PKCS8 structure for SM2 private key
510+ pkcs8 := struct {
511+ Version int
512+ Algorithm pkix.AlgorithmIdentifier
513+ PrivateKey []byte
514+ }{
515+ Version : 0 ,
516+ Algorithm : pkix.AlgorithmIdentifier {
517+ Algorithm : asn1.ObjectIdentifier {1 , 2 , 840 , 10045 , 2 , 1 }, // EC algorithm (SM2 uses EC format)
518+ },
519+ PrivateKey : key .D .Bytes (),
520+ }
521+
522+ // Encode to ASN.1 DER
523+ der , err := asn1 .Marshal (pkcs8 )
524+ if err != nil {
525+ return nil , fmt .Errorf ("failed to marshal SM2 PKCS8 private key: %w" , err )
526+ }
527+
528+ return der , nil
529+ }
530+
438531func marshalGOSTPKCS8PrivateKey (key * gost3410.PrivateKey ) ([]byte , error ) {
439532 // Create PKCS8 structure for GOST private key
440533 pkcs8 := struct {
0 commit comments