Skip to content

Commit

Permalink
src/OpenSSL/crypto.py: support SM2 sign with OpenSSL 1.1.1x
Browse files Browse the repository at this point in the history
In openssl 1.1.1 docs/man3/EVP_PKEY_set1_RSA.pod
(https://github.com/openssl/openssl/blob/OpenSSL_1_1_1/doc/man3/EVP_PKEY_set1_RSA.pod)
The EVP_PKEY_set_alias_type(pkey, EVP_PKEY_SM2) API is possible to convert it to using
SM2 algorithms After loading an ECC key.

Besides, pyca/cryptography support to export `The EVP_PKEY_set_alias_type(pkey, EVP_PKEY_SM2) API`
in pyca/cryptography@c28bfb3 .

So in pyopenssl, we can support SM2 sign with OpenSSL 1.1.1x and pyca/cryptography.

Signed-off-by: YiLin.Li <[email protected]>
  • Loading branch information
hustliyilin authored and YuQing-Rain committed Mar 2, 2023
1 parent cac7478 commit 31d316d
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 0 deletions.
19 changes: 19 additions & 0 deletions src/OpenSSL/crypto.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,9 @@
TYPE_DH: int = _lib.EVP_PKEY_DH
TYPE_EC: int = _lib.EVP_PKEY_EC

NID_sm2 = 1172
EVP_PKEY_SM2 = NID_sm2


class Error(Exception):
"""
Expand Down Expand Up @@ -3104,6 +3107,22 @@ def sign(pkey: PKey, data: Union[str, bytes], digest: str) -> bytes:
if digest_obj == _ffi.NULL:
raise ValueError("No such digest method")

if (
_lib.OPENSSL_VERSION_NUMBER < 0x30000000
and _lib.EVP_PKEY_id(pkey._pkey) == _lib.EVP_PKEY_EC
):
if (
_lib.EC_GROUP_get_curve_name(
_lib.EC_KEY_get0_group(_lib.EVP_PKEY_get1_EC_KEY(pkey._pkey))
)
== NID_sm2
):
if hasattr(_lib, "EVP_PKEY_set_alias_type"):
_lib.EVP_PKEY_set_alias_type(pkey._pkey, EVP_PKEY_SM2)
else:
print("The SM2 Signing isn't enable in current OpenSSL 1.1.x")
return b""

md_ctx = _lib.EVP_MD_CTX_new()
md_ctx = _ffi.gc(md_ctx, _lib.EVP_MD_CTX_free)

Expand Down
43 changes: 43 additions & 0 deletions tests/test_crypto.py
Original file line number Diff line number Diff line change
Expand Up @@ -787,6 +787,31 @@ def normalize_privatekey_pem(pem):
Td8GMrwKz0557OxxtKN6uVVy4ACFMqEw0zN/KJI1vxc9
-----END CERTIFICATE-----"""

sm2_root_key_pem = b"""-----BEGIN EC PARAMETERS-----
BggqgRzPVQGCLQ==
-----END EC PARAMETERS-----
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEII/sRQnfpXCVx5kjmRbPp7KGgwJlOCx0kBX2Tr2lXrM2oAoGCCqBHM9V
AYItoUQDQgAEkZX7gPPNGa0uwJMjTCBgVxlTD2krqPL1rZg2z9HLg3wnH06IxQ8r
3su/VOmyoYBLBYcEjI7GSzvBy6ynX1ZDwA==
-----END EC PRIVATE KEY-----"""

sm2_root_cert_pem = b"""-----BEGIN CERTIFICATE-----
MIICUzCCAfqgAwIBAgIUbVTzHqqPG7Agtp9RPBqzzueBOLkwCgYIKoEcz1UBg3Uw
fjELMAkGA1UEBhMCQ04xETAPBgNVBAgMCFpoZWppYW5nMREwDwYDVQQHDAhIYW5n
emhvdTEQMA4GA1UECgwHQWxpYmFiYTELMAkGA1UECwwCT1MxDTALBgNVBAMMBHRl
c3QxGzAZBgkqhkiG9w0BCQEWDHRlc3RAZm9vLmNvbTAgFw0yMzAzMDIwMjAzMDda
GA8yMTIzMDIwNjAyMDMwN1owfjELMAkGA1UEBhMCQ04xETAPBgNVBAgMCFpoZWpp
YW5nMREwDwYDVQQHDAhIYW5nemhvdTEQMA4GA1UECgwHQWxpYmFiYTELMAkGA1UE
CwwCT1MxDTALBgNVBAMMBHRlc3QxGzAZBgkqhkiG9w0BCQEWDHRlc3RAZm9vLmNv
bTBaMBQGCCqBHM9VAYItBggqgRzPVQGCLQNCAASRlfuA880ZrS7AkyNMIGBXGVMP
aSuo8vWtmDbP0cuDfCcfTojFDyvey79U6bKhgEsFhwSMjsZLO8HLrKdfVkPAo1Mw
UTAdBgNVHQ4EFgQUT0EN5zYFPijk0Pzh+qA2m7JrH2UwHwYDVR0jBBgwFoAUT0EN
5zYFPijk0Pzh+qA2m7JrH2UwDwYDVR0TAQH/BAUwAwEB/zAKBggqgRzPVQGDdQNH
ADBEAiBuCQFJs1MxtD9+jc4zbQ3YV0xxRbRysJAx4ZsQ3v1g7gIgaNEsBOZZTdTn
iKUt/0PJ33RxuywagIkBoU+NOjZiObw=
-----END CERTIFICATE-----"""

rsa_p_not_prime_pem = """
-----BEGIN RSA PRIVATE KEY-----
MBsCAQACAS0CAQcCAQACAQ8CAQMCAQACAQACAQA=
Expand Down Expand Up @@ -4397,6 +4422,24 @@ def test_sign_verify_ecdsa(self):
sig = sign(priv_key, content, "sha256")
verify(cert, sig, content, "sha256")

def test_sign_verify_sm2(self):
"""
`sign` generates a SM2 cryptographic signature which `verify` can
check.
"""
content = (
b"It was a bright cold day in April, and the clocks were striking "
b"thirteen. Winston Smith, his chin nuzzled into his breast in an "
b"effort to escape the vile wind, slipped quickly through the "
b"glass doors of Victory Mansions, though not quickly enough to "
b"prevent a swirl of gritty dust from entering along with him."
)
priv_key = load_privatekey(FILETYPE_PEM, sm2_root_key_pem)
cert = load_certificate(FILETYPE_PEM, sm2_root_cert_pem)
sig = sign(priv_key, content, "sm3")
if sig != b"":
verify(cert, sig, content, "sm3")

def test_sign_nulls(self):
"""
`sign` produces a signature for a string with embedded nulls.
Expand Down

0 comments on commit 31d316d

Please sign in to comment.