Fix a double free issue when signing SM2 cert
authorPaul Yang <kaishen.yy@antfin.com>
Fri, 20 Sep 2019 16:32:57 +0000 (00:32 +0800)
committerPaul Yang <kaishen.yy@antfin.com>
Sun, 29 Sep 2019 01:54:19 +0000 (09:54 +0800)
If the SM2 ID value has not been passed correctly when signing an SM2
certificate/certificate request, a double free occurs. For instance:

  openssl req -x509 ... -sm2-id 1234567812345678

The '-sm2-id' should not be used in this scenario, while the '-sigopt' is
the correct one to use. Documentation has also been updated to make the
options more clear.

Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/9958)

apps/req.c
doc/man1/openssl-req.pod

index f11d341c122d5e57f89ebd286f3a03a2df3c1111..1c9672cca15fa650cf9520ad56590e05b3a11228 100644 (file)
@@ -1751,15 +1751,19 @@ int do_X509_sign(X509 *x, EVP_PKEY *pkey, const EVP_MD *md,
 #endif
 
     rv = do_sign_init(mctx, pkey, md, sigopts);
-    if (rv > 0)
+    if (rv > 0) {
         rv = X509_sign_ctx(x, mctx);
 #ifndef OPENSSL_NO_SM2
-    /* only in SM2 case we need to free the pctx explicitly */
-    if (ec_pkey_is_sm2(pkey)) {
-        pctx = EVP_MD_CTX_pkey_ctx(mctx);
-        EVP_PKEY_CTX_free(pctx);
-    }
+        /*
+         * only in SM2 case we need to free the pctx explicitly
+         * if do_sign_init() fails, pctx is already freed in it
+         */
+        if (ec_pkey_is_sm2(pkey)) {
+            pctx = EVP_MD_CTX_pkey_ctx(mctx);
+            EVP_PKEY_CTX_free(pctx);
+        }
 #endif
+    }
     EVP_MD_CTX_free(mctx);
     return rv > 0 ? 1 : 0;
 }
@@ -1774,15 +1778,19 @@ int do_X509_REQ_sign(X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md,
 #endif
 
     rv = do_sign_init(mctx, pkey, md, sigopts);
-    if (rv > 0)
+    if (rv > 0) {
         rv = X509_REQ_sign_ctx(x, mctx);
 #ifndef OPENSSL_NO_SM2
-    /* only in SM2 case we need to free the pctx explicitly */
-    if (ec_pkey_is_sm2(pkey)) {
-        pctx = EVP_MD_CTX_pkey_ctx(mctx);
-        EVP_PKEY_CTX_free(pctx);
-    }
+        /*
+         * only in SM2 case we need to free the pctx explicitly
+         * if do_sign_init() fails, pctx is already freed in it
+         */
+        if (ec_pkey_is_sm2(pkey)) {
+            pctx = EVP_MD_CTX_pkey_ctx(mctx);
+            EVP_PKEY_CTX_free(pctx);
+        }
 #endif
+    }
     EVP_MD_CTX_free(mctx);
     return rv > 0 ? 1 : 0;
 }
@@ -1797,15 +1805,19 @@ int do_X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md,
 #endif
 
     rv = do_sign_init(mctx, pkey, md, sigopts);
-    if (rv > 0)
+    if (rv > 0) {
         rv = X509_CRL_sign_ctx(x, mctx);
 #ifndef OPENSSL_NO_SM2
-    /* only in SM2 case we need to free the pctx explicitly */
-    if (ec_pkey_is_sm2(pkey)) {
-        pctx = EVP_MD_CTX_pkey_ctx(mctx);
-        EVP_PKEY_CTX_free(pctx);
-    }
+        /*
+         * only in SM2 case we need to free the pctx explicitly
+         * if do_sign_init() fails, no need to double free pctx
+         */
+        if (ec_pkey_is_sm2(pkey)) {
+            pctx = EVP_MD_CTX_pkey_ctx(mctx);
+            EVP_PKEY_CTX_free(pctx);
+        }
 #endif
+    }
     EVP_MD_CTX_free(mctx);
     return rv > 0 ? 1 : 0;
 }
index 4300504f872dae5dd46c813f6e3453fb058df92b..02635b56eacf1ecdea3bb86d5e054d4f9f4e131b 100644 (file)
@@ -342,8 +342,8 @@ for key generation operations.
 
 =item B<-sm2-id>
 
-Specify the ID string to use when verifying an SM2 certificate. The ID string is
-required by the SM2 signature algorithm for signing and verification.
+Specify the ID string to use when verifying an SM2 certificate request. The ID
+string is required by the SM2 signature algorithm for signing and verification.
 
 =item B<-sm2-hex-id>