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 }