github.com/emmansun/gmsm@v0.29.1/smx509/x509_additional_test.go (about)

     1  package smx509
     2  
     3  import (
     4  	"crypto/ecdsa"
     5  	"crypto/rand"
     6  	"crypto/x509"
     7  	"crypto/x509/pkix"
     8  	"encoding/base64"
     9  	"encoding/json"
    10  	"encoding/pem"
    11  	"errors"
    12  	"strings"
    13  	"testing"
    14  
    15  	"github.com/emmansun/gmsm/ecdh"
    16  	"github.com/emmansun/gmsm/sm2"
    17  )
    18  
    19  const publicKeyPemFromAliKms = `-----BEGIN PUBLIC KEY-----
    20  MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAELfjZP28bYfGSvbODYlXiB5bcoXE+
    21  2LRjjpIH3DcCCct9FuVhi9cm60nDFrbW49k2D3GJco2iWPlr0+5LV+t4AQ==
    22  -----END PUBLIC KEY-----
    23  `
    24  const publicKeyPemFromHuaweiKms = `-----BEGIN PUBLIC KEY-----
    25  MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAEP3JLMIBPGUx88KChOY3WhjNVKOsk
    26  RzYP5lpimwVS9CAK6MzL4kqudI7Pqi6hcir35zH8/BHMXzQ4fM2Ojp+59w==
    27  -----END PUBLIC KEY-----
    28  `
    29  
    30  const publicKeyPemFromHuaweiKmsForSign = `-----BEGIN PUBLIC KEY-----
    31  MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAENpoOih+9ASfmKYx5lK5mLsrUK3Am
    32  B6kLUsqHlVyglXgoMEwo8Sr8xb/Q3gDMNnd7Wyp2bJE9ksb60ansO4QaKg==
    33  -----END PUBLIC KEY-----
    34  `
    35  
    36  const publicKeyPemFromAliKmsForSign = `-----BEGIN PUBLIC KEY-----
    37  MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAERrsLH25zLm2LIo6tivZM9afLprSX
    38  6TCKAmQJArAO7VOtZyW4PQwfaTsUIF7IXEFG4iI8bNuTQwMykUzLu2ypEA==
    39  -----END PUBLIC KEY-----
    40  `
    41  
    42  const hashBase64 = `Zsfw9GLu7dnR8tRr3BDk4kFnxIdc8veiKX2gK49LqOA=`
    43  const signature = `MEUCIHV5hOCgYzlO4HkrUhct1Cc8BeKmbXNP+ASje5rGOcCYAiEA2XOajXo3/IihtCEJmNpImtWw3uHIy5CX5TIxit7V0gQ=`
    44  const signatureFromHuawei = `MEQCIGK8rWDJw5K7a6RZP5pDii8iqY3yLmavaXpkl7aDLORqAiAlMiiSvp7OJYBCJmzmwadBiBhdBnCCfIdjiWhXHX9xcw==`
    45  
    46  const csrFromAli = `-----BEGIN CERTIFICATE REQUEST-----
    47  MIIBYjCCAQkCAQAwRzELMAkGA1UEBhMCQ04xEzARBgNVBAMMCkNhcmdvU21hcnQx
    48  DzANBgNVBAcMBlpodWhhaTESMBAGA1UECAwJR3Vhbmdkb25nMFkwEwYHKoZIzj0C
    49  AQYIKoEcz1UBgi0DQgAERrsLH25zLm2LIo6tivZM9afLprSX6TCKAmQJArAO7VOt
    50  ZyW4PQwfaTsUIF7IXEFG4iI8bNuTQwMykUzLu2ypEKBgMC4GCSqGSIb3DQEJDjEh
    51  MB8wHQYDVR0OBBYEFA3FO8vT+8qZBfGZa2TRhLRbme+9MC4GCSqGSIb3DQEJDjEh
    52  MB8wHQYDVR0RBBYwFIESZW1tYW4uc3VuQGlxYXguY29tMAoGCCqBHM9VAYN1A0cA
    53  MEQCIBQx6yv3rzfWCkKqDZQOfNKESQc6NtpQbeVvcxfBrciwAiAj78kkrF5R3g4l
    54  bxIHjKZHc2sztHCXe7cseWGiLq0syg==
    55  -----END CERTIFICATE REQUEST-----
    56  `
    57  
    58  func TestParsePKIXPublicKeyFromExternal(t *testing.T) {
    59  	tests := []struct {
    60  		name string
    61  		pem  string
    62  	}{
    63  		{"ALI", publicKeyPemFromAliKms},
    64  		{"HUAWEI", publicKeyPemFromHuaweiKms},
    65  	}
    66  	for _, test := range tests {
    67  		pub, err := getPublicKey([]byte(test.pem))
    68  		if err != nil {
    69  			t.Fatalf("%s failed to get public key %v", test.name, err)
    70  		}
    71  		pub1 := pub.(*ecdsa.PublicKey)
    72  		_, err = sm2.Encrypt(rand.Reader, pub1, []byte("encryption standard"), sm2.ASN1EncrypterOpts)
    73  		if err != nil {
    74  			t.Fatalf("%s failed to encrypt %v", test.name, err)
    75  		}
    76  	}
    77  }
    78  
    79  func TestSignByCloudVerifyAtLocal(t *testing.T) {
    80  	tests := []struct {
    81  		name      string
    82  		pem       string
    83  		signature string
    84  	}{
    85  		{"ALI", publicKeyPemFromAliKmsForSign, signature},
    86  		{"HUAWEI", publicKeyPemFromHuaweiKmsForSign, signatureFromHuawei},
    87  	}
    88  	for _, test := range tests {
    89  		dig, err := base64.StdEncoding.DecodeString(test.signature)
    90  		if err != nil {
    91  			t.Fatalf("%s failed to decode signature %v", test.name, err)
    92  		}
    93  		pub, err := getPublicKey([]byte(test.pem))
    94  		if err != nil {
    95  			t.Fatal(err)
    96  		}
    97  		pub1 := pub.(*ecdsa.PublicKey)
    98  		hashValue, _ := base64.StdEncoding.DecodeString(hashBase64)
    99  		result := sm2.VerifyASN1(pub1, hashValue, dig)
   100  		if !result {
   101  			t.Fatalf("%s Verify fail", test.name)
   102  		}
   103  	}
   104  }
   105  
   106  func getPublicKey(pemContent []byte) (any, error) {
   107  	block, _ := pem.Decode(pemContent)
   108  	if block == nil {
   109  		return nil, errors.New("Failed to parse PEM block")
   110  	}
   111  	return ParsePKIXPublicKey(block.Bytes)
   112  }
   113  
   114  const sm2Certificate = `
   115  -----BEGIN CERTIFICATE-----
   116  MIICiDCCAiygAwIBAgIQLaGmvQznbGJOY0t9ainQKjAMBggqgRzPVQGDdQUAMC4x
   117  CzAJBgNVBAYTAkNOMQ4wDAYDVQQKDAVOUkNBQzEPMA0GA1UEAwwGUk9PVENBMB4X
   118  DTEzMDkxMzA4MTAyNVoXDTMzMDkwODA4MTAyNVowNDELMAkGA1UEBhMCQ04xETAP
   119  BgNVBAoMCFVuaVRydXN0MRIwEAYDVQQDDAlTSEVDQSBTTTIwWTATBgcqhkjOPQIB
   120  BggqgRzPVQGCLQNCAAR90R+RLQZKVBDwhIRVJR28ovu1x3duw2yxaWaY6E3lUKDW
   121  IsmAwMOqE71MW3gQOxm68QJfPy6JT4Evil10FwyAo4IBIjCCAR4wHwYDVR0jBBgw
   122  FoAUTDKxl9kzG8SmBcHG5YtiW/CXdlgwDwYDVR0TAQH/BAUwAwEB/zCBugYDVR0f
   123  BIGyMIGvMEGgP6A9pDswOTELMAkGA1UEBhMCQ04xDjAMBgNVBAoMBU5SQ0FDMQww
   124  CgYDVQQLDANBUkwxDDAKBgNVBAMMA2FybDAqoCigJoYkaHR0cDovL3d3dy5yb290
   125  Y2EuZ292LmNuL2FybC9hcmwuY3JsMD6gPKA6hjhsZGFwOi8vbGRhcC5yb290Y2Eu
   126  Z292LmNuOjM4OS9DTj1hcmwsT1U9QVJMLE89TlJDQUMsQz1DTjAOBgNVHQ8BAf8E
   127  BAMCAQYwHQYDVR0OBBYEFIkxBJF7Q6qqmr+EHZuG7vC4cJmgMAwGCCqBHM9VAYN1
   128  BQADSAAwRQIhAIp7/3vva+ZxFePKdqkzdGoVyGsfGHhiLLQeKrCZQ2Q5AiAmMOdf
   129  0f0b8CilrVWdi8pfZyO6RqYfnpcJ638l7KHfNA==
   130  -----END CERTIFICATE-----`
   131  
   132  const openSSL3Certificate = `
   133  -----BEGIN CERTIFICATE-----
   134  MIICGzCCAcCgAwIBAgIUZ2YpsJJVNcwfjCHBEz8otQDEpUEwCgYIKoEcz1UBg3Uw
   135  YjELMAkGA1UEBhMCSU4xEjAQBgNVBAgMCUJlbmdhbHVydTENMAsGA1UEBwwEQ2l0
   136  eTEQMA4GA1UECgwHU29tZU9yZzENMAsGA1UECwwEVGVzdDEPMA0GA1UEAwwGUm9v
   137  dENBMB4XDTI0MDgyNzAyMzQ1NloXDTM0MDgyNTAyMzQ1NlowYjELMAkGA1UEBhMC
   138  SU4xEjAQBgNVBAgMCUJlbmdhbHVydTENMAsGA1UEBwwEQ2l0eTEQMA4GA1UECgwH
   139  U29tZU9yZzENMAsGA1UECwwEVGVzdDEPMA0GA1UEAwwGUm9vdENBMFowFAYIKoEc
   140  z1UBgi0GCCqBHM9VAYItA0IABC8HaH8+WYCtUk06wAFfzR09nnOlQOJ2oORwD25m
   141  S55CdJv+Svzji0nSeSWtXBzo9y4Q6EKLDpOSQbKYeswVDoejUzBRMB0GA1UdDgQW
   142  BBRSGm5/62dcOw8vkiG8YGoZMf6UIzAfBgNVHSMEGDAWgBRSGm5/62dcOw8vkiG8
   143  YGoZMf6UIzAPBgNVHRMBAf8EBTADAQH/MAoGCCqBHM9VAYN1A0kAMEYCIQDC4s3P
   144  wAKTEz+410/odAO30Wzam895L31T1MQ0EaBYtQIhALbw1l4lcun4RTVWYQN5A2r2
   145  Cm2A1bCQaLWY1jsQTBpf
   146  -----END CERTIFICATE-----`
   147  
   148  func Test_ParseCertificate(t *testing.T) {
   149  	cert, err := ParseCertificatePEM([]byte(sm2Certificate))
   150  	if err != nil {
   151  		t.Fatal(err)
   152  	}
   153  	_, err = json.Marshal(cert)
   154  	if err != nil {
   155  		t.Fatal(err)
   156  	}
   157  	cert, err = ParseCertificatePEM([]byte(openSSL3Certificate))
   158  	if err != nil {
   159  		t.Fatal(err)
   160  	}
   161  	if cert.PublicKeyAlgorithm != x509.ECDSA {
   162  		t.Fatal("should be ECDSA")
   163  	}
   164  	if cert.SignatureAlgorithm != SM2WithSM3 {
   165  		t.Fatal("should be SM2WithSM3")
   166  	}
   167  	_, err = json.Marshal(cert)
   168  	if err != nil {
   169  		t.Fatal(err)
   170  	}
   171  }
   172  
   173  func TestCreateSM2CertificateRequest(t *testing.T) {
   174  	priv, _ := sm2.GenerateKey(rand.Reader)
   175  
   176  	names := pkix.Name{CommonName: "TestName"}
   177  	var template = x509.CertificateRequest{Subject: names, SignatureAlgorithm: SM2WithSM3}
   178  	csrblock, err := CreateCertificateRequest(rand.Reader, &template, priv)
   179  	if err != nil {
   180  		t.Fatal(err)
   181  	}
   182  	block := &pem.Block{Bytes: csrblock, Type: "CERTIFICATE REQUEST"}
   183  	pemContent := string(pem.EncodeToMemory(block))
   184  	err = parseAndCheckCsr([]byte(pemContent))
   185  	if err != nil {
   186  		t.Fatal(err)
   187  	}
   188  }
   189  
   190  func TestParseAliCertificateRequest(t *testing.T) {
   191  	err := parseAndCheckCsr([]byte(csrFromAli))
   192  	if err != nil {
   193  		t.Fatal("ParseCertificateRequest should succeed when parsing CSR with duplicate attributes")
   194  	}
   195  }
   196  
   197  func TestMarshalPKIXPublicKey(t *testing.T) {
   198  	pub, err := getPublicKey([]byte(publicKeyPemFromAliKms))
   199  	if err != nil {
   200  		t.Fatal(err)
   201  	}
   202  	result, err := MarshalPKIXPublicKey(pub)
   203  	if err != nil {
   204  		t.Fatal(err)
   205  	}
   206  	block := &pem.Block{Bytes: result, Type: "PUBLIC KEY"}
   207  	pemContent := string(pem.EncodeToMemory(block))
   208  	if !strings.EqualFold(publicKeyPemFromAliKms, pemContent) {
   209  		t.Errorf("expected=%s, result=%s", publicKeyPemFromAliKms, pemContent)
   210  	}
   211  }
   212  
   213  func parseAndCheckCsr(csrPem []byte) error {
   214  	csr, err := ParseCertificateRequestPEM(csrPem)
   215  	if err != nil {
   216  		return err
   217  	}
   218  	return csr.CheckSignature()
   219  }
   220  
   221  func TestMarshalECDHPKIXPublicKey(t *testing.T) {
   222  	privKey, err := ecdh.P256().GenerateKey(rand.Reader)
   223  	if err != nil {
   224  		t.Fatal(err)
   225  	}
   226  	result1, err := MarshalPKIXPublicKey(privKey.Public())
   227  	if err != nil {
   228  		t.Fatal(err)
   229  	}
   230  	pubKey, err := ParsePKIXPublicKey(result1)
   231  	if err != nil {
   232  		t.Fatal(err)
   233  	}
   234  	sm2PubKey, ok := pubKey.(*ecdsa.PublicKey)
   235  	if !ok {
   236  		t.Fatal("should be valid sm2 public key")
   237  	}
   238  	sm2ecdhPub, err := sm2.PublicKeyToECDH(sm2PubKey)
   239  	if err != nil {
   240  		t.Fatal(err)
   241  	}
   242  	if !privKey.PublicKey().Equal(sm2ecdhPub) {
   243  		t.Fatal("should be same")
   244  	}
   245  }
   246  
   247  func TestToCertificate(t *testing.T) {
   248  	x509Cert := new(x509.Certificate)
   249  
   250  	c, err := toCertificate(x509Cert)
   251  	if err != nil || c != x509Cert {
   252  		t.Fatal("should be no error")
   253  	}
   254  
   255  	smX509Cert := new(Certificate)
   256  	_, err = toCertificate(smX509Cert)
   257  	if err != nil {
   258  		t.Fatal("should be no error")
   259  	}
   260  
   261  	_, err = toCertificate("test")
   262  	if err == nil {
   263  		t.Fatal("should be error")
   264  	}
   265  
   266  	_, err = toCertificate(nil)
   267  	if err == nil {
   268  		t.Fatal("should be error")
   269  	}
   270  }
   271  
   272  func TestInvalidParentTemplate(t *testing.T) {
   273  	random := rand.Reader
   274  
   275  	sm2Priv, err := sm2.GenerateKey(rand.Reader)
   276  	if err != nil {
   277  		t.Fatalf("Failed to generate SM2 key: %s", err)
   278  	}
   279  	_, err = CreateCertificate(random, nil, nil, sm2Priv.PublicKey, sm2Priv)
   280  	if err == nil {
   281  		t.Fatal("should be error")
   282  	}
   283  	if err.Error() != "x509: unsupported template parameter type: <nil>" {
   284  		t.Fatalf("unexpected error message: %v", err.Error())
   285  	}
   286  
   287  	_, err = CreateCertificate(random, new(x509.Certificate), nil, sm2Priv.PublicKey, sm2Priv)
   288  	if err == nil {
   289  		t.Fatal("should be error")
   290  	}
   291  	if err.Error() != "x509: unsupported parent parameter type: <nil>" {
   292  		t.Fatalf("unexpected error message: %v", err.Error())
   293  	}
   294  }