Ai
1 Star 0 Fork 0

yovld/GmSSL-Python

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
gmssl.py 30.02 KB
一键复制 编辑 原始数据 按行查看 历史
guanzhi 提交于 2023-10-12 19:46 +08:00 . Update PHP version
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041
# Copyright 2023 The GmSSL Project. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the License); you may
# not use this file except in compliance with the License.
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# GmSSL-Python - Python binding of the GmSSL library with `ctypes`
from ctypes import *
from ctypes.util import find_library
import datetime
import sys
if find_library('gmssl') == None:
raise ValueError('Install GmSSL dynamic library from https://github.com/guanzhi/GmSSL')
gmssl = cdll.LoadLibrary(find_library("gmssl"))
if gmssl.gmssl_version_num() < 30101:
raise ValueError('GmSSL version < 3.1.1')
if sys.platform == 'win32':
libc = cdll.LoadLibrary(find_library('msvcrt'))
else:
libc = cdll.LoadLibrary(find_library('c'))
class NativeError(Exception):
'''
GmSSL libraray inner error
'''
class StateError(Exception):
'''
Crypto state error
'''
GMSSL_PYTHON_VERSION = "2.2.2"
def gmssl_library_version_num():
return gmssl.gmssl_version_num()
def gmssl_library_version_str():
gmssl.gmssl_version_str.restype = c_char_p
return gmssl.gmssl_version_str().decode('ascii')
GMSSL_LIBRARY_VERSION = gmssl_library_version_str()
def rand_bytes(size):
buf = create_string_buffer(size)
gmssl.rand_bytes(buf, c_size_t(size))
return buf.raw
SM3_DIGEST_SIZE = 32
_SM3_STATE_WORDS = 8
_SM3_BLOCK_SIZE = 64
class Sm3(Structure):
_fields_ = [
("dgst", c_uint32 * _SM3_STATE_WORDS),
("nblocks", c_uint64),
("block", c_uint8 * _SM3_BLOCK_SIZE),
("num", c_size_t)
]
def __init__(self):
gmssl.sm3_init(byref(self))
def reset(self):
gmssl.sm3_init(byref(self))
def update(self, data):
gmssl.sm3_update(byref(self), data, c_size_t(len(data)))
def digest(self):
dgst = create_string_buffer(SM3_DIGEST_SIZE)
gmssl.sm3_finish(byref(self), dgst)
return dgst.raw
SM3_HMAC_MIN_KEY_SIZE = 16
SM3_HMAC_MAX_KEY_SIZE = 64
SM3_HMAC_SIZE = SM3_DIGEST_SIZE
class Sm3Hmac(Structure):
_fields_ = [
("sm3_ctx", Sm3),
("key", c_uint8 * _SM3_BLOCK_SIZE)
]
def __init__(self, key):
if len(key) < SM3_HMAC_MIN_KEY_SIZE or len(key) > SM3_HMAC_MAX_KEY_SIZE:
raise ValueError('Invalid SM3 HMAC key length')
gmssl.sm3_hmac_init(byref(self), key, c_size_t(len(key)))
def reset(self, key):
if len(key) < SM3_HMAC_MIN_KEY_SIZE or len(key) > SM3_HMAC_MAX_KEY_SIZE:
raise ValueError('Invalid SM3 HMAC key length')
gmssl.sm3_hmac_init(byref(self), key, c_size_t(len(key)))
def update(self, data):
gmssl.sm3_hmac_update(byref(self), data, c_size_t(len(data)))
def generate_mac(self):
hmac = create_string_buffer(SM3_HMAC_SIZE)
gmssl.sm3_hmac_finish(byref(self), hmac)
return hmac.raw
SM3_PBKDF2_MIN_ITER = 10000 # from <gmssl/pbkdf2.h>
SM3_PBKDF2_MAX_ITER = 16777216 # 2^24
SM3_PBKDF2_MAX_SALT_SIZE = 64 # from <gmssl/pbkdf2.h>
SM3_PBKDF2_DEFAULT_SALT_SIZE = 8 # from <gmssl/pbkdf2.h>
SM3_PBKDF2_MAX_KEY_SIZE = 256 # from gmssljni.c:sm3_pbkdf2():sizeof(keybuf)
def sm3_pbkdf2(passwd, salt, iterator, keylen):
if len(salt) > SM3_PBKDF2_MAX_SALT_SIZE:
raise ValueError('Invalid salt length')
if iterator < SM3_PBKDF2_MIN_ITER or iterator > SM3_PBKDF2_MAX_ITER:
raise ValueError('Invalid iterator value')
if keylen > SM3_PBKDF2_MAX_KEY_SIZE:
raise ValueError('Invalid key length')
passwd = passwd.encode('utf-8')
key = create_string_buffer(keylen)
if gmssl.pbkdf2_hmac_sm3_genkey(c_char_p(passwd), c_size_t(len(passwd)),
salt, c_size_t(len(salt)), c_size_t(iterator), c_size_t(keylen), key) != 1:
raise NativeError('libgmssl inner error')
return key.raw
SM4_KEY_SIZE = 16
SM4_BLOCK_SIZE = 16
_SM4_NUM_ROUNDS = 32
class Sm4(Structure):
_fields_ = [
("rk", c_uint32 * _SM4_NUM_ROUNDS)
]
def __init__(self, key, encrypt):
if len(key) != SM4_KEY_SIZE:
raise ValueError('Invalid key length')
if encrypt:
gmssl.sm4_set_encrypt_key(byref(self), key)
else:
gmssl.sm4_set_decrypt_key(byref(self), key)
def encrypt(self, block):
if len(block) != SM4_BLOCK_SIZE:
raise ValueError('Invalid block size')
outbuf = create_string_buffer(SM4_BLOCK_SIZE)
gmssl.sm4_encrypt(byref(self), block, outbuf)
return outbuf.raw
SM4_CBC_IV_SIZE = SM4_BLOCK_SIZE
class Sm4Cbc(Structure):
_fields_ = [
("sm4_key", Sm4),
("iv", c_uint8 * SM4_BLOCK_SIZE),
("block", c_uint8 * SM4_BLOCK_SIZE),
("block_nbytes", c_size_t)
]
def __init__(self, key, iv, encrypt):
if len(key) != SM4_KEY_SIZE:
raise ValueError('Invalid key length')
if len(iv) != SM4_BLOCK_SIZE:
raise ValueError('Invalid IV size')
if encrypt == DO_ENCRYPT:
if gmssl.sm4_cbc_encrypt_init(byref(self), key, iv) != 1:
raise NativeError('libgmssl inner error')
else:
if gmssl.sm4_cbc_decrypt_init(byref(self), key, iv) != 1:
raise NativeError('libgmssl inner error')
self._encrypt = encrypt
def update(self, data):
outbuf = create_string_buffer(len(data) + SM4_BLOCK_SIZE)
outlen = c_size_t()
if self._encrypt == DO_ENCRYPT:
if gmssl.sm4_cbc_encrypt_update(byref(self), data, c_size_t(len(data)),
outbuf, byref(outlen)) != 1:
raise NativeError('libgmssl inner error')
else:
if gmssl.sm4_cbc_decrypt_update(byref(self), data, c_size_t(len(data)),
outbuf, byref(outlen)) != 1:
raise NativeError('libgmssl inner error')
return outbuf[0:outlen.value]
def finish(self):
outbuf = create_string_buffer(SM4_BLOCK_SIZE)
outlen = c_size_t()
if self._encrypt == True:
if gmssl.sm4_cbc_encrypt_finish(byref(self), outbuf, byref(outlen)) != 1:
raise NativeError('libgmssl inner error')
else:
if gmssl.sm4_cbc_decrypt_finish(byref(self), outbuf, byref(outlen)) != 1:
raise NativeError('libgmssl inner error')
return outbuf[:outlen.value]
SM4_CTR_IV_SIZE = 16
class Sm4Ctr(Structure):
_fields_ = [
("sm4_key", Sm4),
("ctr", c_uint8 * SM4_BLOCK_SIZE),
("block", c_uint8 * SM4_BLOCK_SIZE),
("block_nbytes", c_size_t)
]
def __init__(self, key, iv):
if len(key) != SM4_KEY_SIZE:
raise ValueError('Invalid key length')
if len(iv) != SM4_BLOCK_SIZE:
raise ValueError('Invalid IV size')
if gmssl.sm4_ctr_encrypt_init(byref(self), key, iv) != 1:
raise NativeError('libgmssl inner error')
def update(self, data):
outbuf = create_string_buffer(len(data) + SM4_BLOCK_SIZE)
outlen = c_size_t()
if gmssl.sm4_ctr_encrypt_update(byref(self), data, c_size_t(len(data)),
outbuf, byref(outlen)) != 1:
raise NativeError('libgmssl inner error')
return outbuf[0:outlen.value]
def finish(self):
outbuf = create_string_buffer(SM4_BLOCK_SIZE)
outlen = c_size_t()
if gmssl.sm4_ctr_encrypt_finish(byref(self), outbuf, byref(outlen)) != 1:
raise NativeError('libgmssl inner error')
return outbuf[:outlen.value]
ZUC_KEY_SIZE = 16
ZUC_IV_SIZE = 16
class ZucState(Structure):
_fields_ = [
("LFSR", c_uint32 * 16),
("R1", c_uint32),
("R2", c_uint32)
]
class Zuc(Structure):
_fields_ = [
("zuc_state", ZucState),
("block", c_uint8 * 4),
("block_nbytes", c_size_t)
]
def __init__(self, key, iv):
if len(key) != ZUC_KEY_SIZE:
raise ValueError('Invalid key length')
if len(iv) != ZUC_IV_SIZE:
raise ValueError('Invalid IV size')
if gmssl.zuc_encrypt_init(byref(self), key, iv) != 1:
raise NativeError('libgmssl inner error')
def update(self, data):
outbuf = create_string_buffer(len(data) + SM4_BLOCK_SIZE)
outlen = c_size_t()
if gmssl.zuc_encrypt_update(byref(self), data, c_size_t(len(data)),
outbuf, byref(outlen)) != 1:
raise NativeError('libgmssl inner error')
return outbuf[0:outlen.value]
def finish(self):
outbuf = create_string_buffer(SM4_BLOCK_SIZE)
outlen = c_size_t()
if gmssl.zuc_encrypt_finish(byref(self), outbuf, byref(outlen)) != 1:
raise NativeError('libgmssl inner error')
return outbuf[:outlen.value]
class gf128_t(Structure):
_fields_ = [
("hi", c_uint64),
("lo", c_uint64)
]
class Ghash(Structure):
_fields_ = [
("H", gf128_t),
("X", gf128_t),
("aadlen", c_size_t),
("clen", c_size_t),
("block", c_uint8 * 16),
("num", c_size_t)
]
SM4_GCM_MIN_IV_SIZE = 1
SM4_GCM_MAX_IV_SIZE = 64
SM4_GCM_DEFAULT_IV_SIZE = 12
SM4_GCM_DEFAULT_TAG_SIZE = 16
SM4_GCM_MAX_TAG_SIZE = 16
class Sm4Gcm(Structure):
_fields_ = [
("sm4_ctr_ctx", Sm4Ctr),
("mac_ctx", Ghash),
("Y", c_uint8 * 16),
("taglen", c_size_t),
("mac", c_uint8 * 16),
("maclen", c_size_t)
]
def __init__(self, key, iv, aad, taglen = SM4_GCM_DEFAULT_TAG_SIZE, encrypt = True):
if len(key) != SM4_KEY_SIZE:
raise ValueError('Invalid key length')
if len(iv) < SM4_GCM_MIN_IV_SIZE or len(iv) > SM4_GCM_MAX_IV_SIZE:
raise ValueError('Invalid IV size')
if taglen < 1 or taglen > SM4_GCM_MAX_TAG_SIZE:
raise ValueError('Invalid Tag length')
if encrypt == DO_ENCRYPT:
if gmssl.sm4_gcm_encrypt_init(byref(self), key, c_size_t(len(key)),
iv, c_size_t(len(iv)), aad, c_size_t(len(aad)),
c_size_t(taglen)) != 1:
raise NativeError('libgmssl inner error')
else:
if gmssl.sm4_gcm_decrypt_init(byref(self), key, c_size_t(len(key)),
iv, c_size_t(len(iv)), aad, c_size_t(len(aad)),
c_size_t(taglen)) != 1:
raise NativeError('libgmssl inner error')
self._encrypt = encrypt
def update(self, data):
outbuf = create_string_buffer(len(data) + SM4_BLOCK_SIZE)
outlen = c_size_t()
if self._encrypt == DO_ENCRYPT:
if gmssl.sm4_gcm_encrypt_update(byref(self), data, c_size_t(len(data)),
outbuf, byref(outlen)) != 1:
raise NativeError('libgmssl inner error')
else:
if gmssl.sm4_gcm_decrypt_update(byref(self), data, c_size_t(len(data)),
outbuf, byref(outlen)) != 1:
raise NativeError('libgmssl inner error')
return outbuf[0:outlen.value]
def finish(self):
outbuf = create_string_buffer(SM4_BLOCK_SIZE + SM4_GCM_MAX_TAG_SIZE)
outlen = c_size_t()
if self._encrypt == DO_ENCRYPT:
if gmssl.sm4_gcm_encrypt_finish(byref(self), outbuf, byref(outlen)) != 1:
raise NativeError('libgmssl inner error')
else:
if gmssl.sm4_gcm_decrypt_finish(byref(self), outbuf, byref(outlen)) != 1:
raise NativeError('libgmssl inner error')
return outbuf[:outlen.value]
SM2_DEFAULT_ID = '1234567812345678'
SM2_MAX_SIGNATURE_SIZE = 72
SM2_MIN_PLAINTEXT_SIZE = 1
SM2_MAX_PLAINTEXT_SIZE = 255
SM2_MIN_CIPHERTEXT_SIZE = 45
SM2_MAX_CIPHERTEXT_SIZE = 366
class Sm2Point(Structure):
_fields_ = [
("x", c_uint8 * 32),
("y", c_uint8 * 32)
]
class Sm2Key(Structure):
_fields_ = [
("public_key", Sm2Point),
("private_key", c_uint8 * 32)
]
def __init__(self):
self._has_public_key = False
self._has_private_key = False
def generate_key(self):
if gmssl.sm2_key_generate(byref(self)) != 1:
raise NativeError('libgmssl inner error')
self._has_public_key = True
self._has_private_key = True
def has_private_key(self):
return self._has_private_key
def has_public_key(self):
return self._has_public_key
def compute_z(self, signer_id = SM2_DEFAULT_ID):
if self._has_public_key == False:
raise TypeError('has no public key')
signer_id = signer_id.encode('utf-8')
z = create_string_buffer(SM3_DIGEST_SIZE)
gmssl.sm2_compute_z(z, byref(self), c_char_p(signer_id), c_size_t(len(signer_id)))
return z.raw
def export_encrypted_private_key_info_pem(self, path, passwd):
if self._has_private_key == False:
raise TypeError('has no private key')
libc.fopen.restype = c_void_p
fp = libc.fopen(path.encode('utf-8'), 'wb')
passwd = passwd.encode('utf-8')
if gmssl.sm2_private_key_info_encrypt_to_pem(byref(self), c_char_p(passwd), c_void_p(fp)) != 1:
raise NativeError('libgmssl inner error')
libc.fclose(c_void_p(fp))
def import_encrypted_private_key_info_pem(self, path, passwd):
libc.fopen.restype = c_void_p
fp = libc.fopen(path.encode('utf-8'), 'rb')
passwd = passwd.encode('utf-8')
if gmssl.sm2_private_key_info_decrypt_from_pem(byref(self), c_char_p(passwd), c_void_p(fp)) != 1:
raise NativeError('libgmssl inner error')
libc.fclose(c_void_p(fp))
self._has_public_key = True
self._has_private_key = True
def export_public_key_info_pem(self, path):
if self._has_public_key == False:
raise TypeError('has no public key')
libc.fopen.restype = c_void_p
fp = libc.fopen(path.encode('utf-8'), 'wb')
if gmssl.sm2_public_key_info_to_pem(byref(self), c_void_p(fp)) != 1:
raise NativeError('libgmssl inner error')
libc.fclose(c_void_p(fp))
def import_public_key_info_pem(self, path):
libc.fopen.restype = c_void_p
fp = libc.fopen(path.encode('utf-8'), 'rb')
if gmssl.sm2_public_key_info_from_pem(byref(self), c_void_p(fp)) != 1:
raise NativeError('libgmssl inner error')
libc.fclose(c_void_p(fp))
self._has_public_key = True
self._has_private_key = False
def sign(self, dgst):
if self._has_private_key == False:
raise TypeError('has no private key')
if len(dgst) != SM3_DIGEST_SIZE:
raise ValueError('Invalid SM3 digest size')
sig = create_string_buffer(SM2_MAX_SIGNATURE_SIZE)
siglen = c_size_t()
if gmssl.sm2_sign(byref(self), dgst, sig, byref(siglen)) != 1:
raise NativeError('libgmssl inner error')
return sig[:siglen.value]
def verify(self, dgst, signature):
if self._has_public_key == False:
raise TypeError('has no public key')
if len(dgst) != SM3_DIGEST_SIZE:
raise ValueError('Invalid SM3 digest size')
if gmssl.sm2_verify(byref(self), dgst, signature, c_size_t(len(signature))) != 1:
return False
return True
def encrypt(self, data):
if self._has_public_key == False:
raise TypeError('has no public key')
if len(data) > SM2_MAX_PLAINTEXT_SIZE:
raise NativeError('libgmssl inner error')
outbuf = create_string_buffer(SM2_MAX_CIPHERTEXT_SIZE)
outlen = c_size_t()
if gmssl.sm2_encrypt(byref(self), data, c_size_t(len(data)),
outbuf, byref(outlen)) != 1:
raise NativeError('libgmssl inner error')
return outbuf[:outlen.value]
def decrypt(self, ciphertext):
if self._has_private_key == False:
raise TypeError('has no private key')
outbuf = create_string_buffer(SM2_MAX_PLAINTEXT_SIZE)
outlen = c_size_t()
if gmssl.sm2_decrypt(byref(self), ciphertext, c_size_t(len(ciphertext))
, outbuf, byref(outlen)) != 1:
raise NativeError('libgmssl inner error')
return outbuf[:outlen.value]
DO_ENCRYPT = True
DO_DECRYPT = False
DO_SIGN = True
DO_VERIFY = False
class Sm2Signature(Structure):
_fields_ = [
("sm3_ctx", Sm3),
("key", Sm2Key)
]
def __init__(self, sm2_key, signer_id = SM2_DEFAULT_ID, sign = DO_SIGN):
signer_id = signer_id.encode('utf-8')
if sign == DO_SIGN:
if sm2_key.has_private_key() != True:
raise NativeError('libgmssl inner error')
if gmssl.sm2_sign_init(byref(self), byref(sm2_key),
c_char_p(signer_id), c_size_t(len(signer_id))) != 1:
raise NativeError('libgmssl inner error')
else:
if sm2_key.has_public_key() != True:
raise NativeError('libgmssl inner error')
if gmssl.sm2_verify_init(byref(self), byref(sm2_key),
c_char_p(signer_id), c_size_t(len(signer_id))) != 1:
raise NativeError('libgmssl inner error')
self._sign = sign
def update(self, data):
if self._sign == DO_SIGN:
if gmssl.sm2_sign_update(byref(self), data, c_size_t(len(data))) != 1:
raise NativeError('libgmssl inner error')
else:
if gmssl.sm2_verify_update(byref(self), data, c_size_t(len(data))) != 1:
raise NativeError('libgmssl inner error')
def sign(self):
if self._sign != DO_SIGN:
raise StateError('not sign state')
sig = create_string_buffer(SM2_MAX_SIGNATURE_SIZE)
siglen = c_size_t()
if gmssl.sm2_sign_finish(byref(self), sig, byref(siglen)) != 1:
raise NativeError('libgmssl inner error')
return sig[:siglen.value]
def verify(self, signature):
if self._sign != DO_VERIFY:
raise StateError('not verify state')
if gmssl.sm2_verify_finish(byref(self), signature, c_size_t(len(signature))) != 1:
return False
return True
class sm9_bn_t(Structure):
_fields_ = [
("d", c_uint64 * 8)
]
class sm9_fp2_t(Structure):
_fields_ = [
("d", sm9_bn_t * 2)
]
class Sm9Point(Structure):
_fields_ = [
("X", sm9_bn_t),
("Y", sm9_bn_t),
("Z", sm9_bn_t)
]
class Sm9TwistPoint(Structure):
_fields_ = [
("X", sm9_fp2_t),
("Y", sm9_fp2_t),
("Z", sm9_fp2_t)
]
SM9_MAX_ID_SIZE = 63
SM9_MAX_PLAINTEXT_SIZE = 255
SM9_MAX_CIPHERTEXT_SIZE = 367
class Sm9EncKey(Structure):
_fields_ = [
("Ppube", Sm9Point),
("de", Sm9TwistPoint)
]
def __init__(self, owner_id):
self._id = owner_id.encode('utf-8')
self._has_private_key = False
def get_id(self):
return self._id;
def has_private_key(self):
return self._has_private_key
def import_encrypted_private_key_info_pem(self, path, passwd):
libc.fopen.restype = c_void_p
fp = libc.fopen(path.encode('utf-8'), 'rb')
passwd = passwd.encode('utf-8')
if gmssl.sm9_enc_key_info_decrypt_from_pem(byref(self), c_char_p(passwd), c_void_p(fp)) != 1:
raise NativeError('libgmssl inner error')
libc.fclose(c_void_p(fp))
self._has_private_key = True
def export_encrypted_private_key_info_pem(self, path, passwd):
if self._has_private_key != True:
raise TypeError('has no private key')
libc.fopen.restype = c_void_p
fp = libc.fopen(path.encode('utf-8'), 'wb')
passwd = passwd.encode('utf-8')
if gmssl.sm9_enc_key_info_encrypt_to_pem(byref(self), c_char_p(passwd), c_void_p(fp)) != 1:
raise NativeError('libgmssl inner error')
libc.fclose(c_void_p(fp))
def decrypt(self, ciphertext):
if self._has_private_key != True:
raise TypeError('has no private key')
plaintext = create_string_buffer(SM9_MAX_PLAINTEXT_SIZE)
outlen = c_size_t()
if gmssl.sm9_decrypt(byref(self), c_char_p(self._id), c_size_t(len(self._id)),
ciphertext, c_size_t(len(ciphertext)), plaintext, byref(outlen)) != 1:
raise NativeError('libgmssl inner error')
return plaintext[0:outlen.value]
class Sm9EncMasterKey(Structure):
_fields_ = [
("Ppube", Sm9Point),
("ke", sm9_bn_t)
]
def __init__(self):
self._has_public_key = False
self._has_private_key = False
def generate_master_key(self):
if gmssl.sm9_enc_master_key_generate(byref(self)) != 1:
raise NativeError('libgmssl inner error')
self._has_public_key = True
self._has_private_key = True
def extract_key(self, identity):
if self._has_private_key != True:
raise TypeError('has no master key')
key = Sm9EncKey(identity)
identity = identity.encode('utf-8')
if gmssl.sm9_enc_master_key_extract_key(byref(self),
c_char_p(identity), c_size_t(len(identity)), byref(key)) != 1:
raise NativeError('libgmssl inner error')
key._has_public_key = True
key._has_private_key = True
return key
def import_encrypted_master_key_info_pem(self, path, passwd):
libc.fopen.restype = c_void_p
fp = libc.fopen(path.encode('utf-8'), 'rb')
passwd = passwd.encode('utf-8')
if gmssl.sm9_enc_master_key_info_decrypt_from_pem(byref(self), c_char_p(passwd), c_void_p(fp)) != 1:
raise NativeError('libgmssl inner error')
libc.fclose(c_void_p(fp))
self._has_public_key = True
self._has_private_key = True
def export_encrypted_master_key_info_pem(self, path, passwd):
if self._has_private_key != True:
raise TypeError('has no master key')
libc.fopen.restype = c_void_p
fp = libc.fopen(path.encode('utf-8'), 'wb')
passwd = passwd.encode('utf-8')
if gmssl.sm9_enc_master_key_info_encrypt_to_pem(byref(self), c_char_p(passwd), c_void_p(fp)) != 1:
raise NativeError('libgmssl inner error')
libc.fclose(c_void_p(fp))
def export_public_master_key_pem(self, path):
if self._has_public_key != True:
raise TypeError('has no public master key')
libc.fopen.restype = c_void_p
fp = libc.fopen(path.encode('utf-8'), 'wb')
if gmssl.sm9_enc_master_public_key_to_pem(byref(self), c_void_p(fp)) != 1:
raise NativeError('libgmssl inner error')
libc.fclose(c_void_p(fp))
def import_public_master_key_pem(self, path):
libc.fopen.restype = c_void_p
fp = libc.fopen(path.encode('utf-8'), 'rb')
if gmssl.sm9_enc_master_public_key_from_pem(byref(self), c_void_p(fp)) != 1:
raise NativeError('libgmssl inner error')
libc.fclose(c_void_p(fp))
self._has_public_key = True
self._has_private_key = False
def encrypt(self, plaintext, to):
if self._has_public_key != True:
raise TypeError('has no public master key')
to = to.encode('utf-8')
ciphertext = create_string_buffer(SM9_MAX_CIPHERTEXT_SIZE)
outlen = c_size_t()
if gmssl.sm9_encrypt(byref(self), c_char_p(to), c_size_t(len(to)),
plaintext, c_size_t(len(plaintext)), ciphertext, byref(outlen)) != 1:
raise NativeError('libgmssl inner error')
return ciphertext[0:outlen.value]
class Sm9SignKey(Structure):
_fields_ = [
("Ppubs", Sm9TwistPoint),
("ds", Sm9Point)
]
def __init__(self, owner_id):
self._id = owner_id.encode('utf-8')
self._has_private_key = False
def get_id(self):
return self._id;
def has_private_key(self):
return self._has_private_key
def import_encrypted_private_key_info_pem(self, path, passwd):
libc.fopen.restype = c_void_p
fp = libc.fopen(path.encode('utf-8'), 'rb')
passwd = passwd.encode('utf-8')
if gmssl.sm9_sign_key_info_decrypt_from_pem(byref(self), c_char_p(passwd), c_void_p(fp)) != 1:
raise NativeError('libgmssl inner error')
libc.fclose(c_void_p(fp))
self._has_private_key = True
def export_encrypted_private_key_info_pem(self, path, passwd):
if self._has_private_key == False:
raise TypeError('has no master key')
libc.fopen.restype = c_void_p
fp = libc.fopen(path.encode('utf-8'), 'wb')
passwd = passwd.encode('utf-8')
if gmssl.sm9_sign_key_info_encrypt_to_pem(byref(self), c_char_p(passwd), c_void_p(fp)) != 1:
raise NativeError('libgmssl inner error')
libc.fclose(c_void_p(fp))
class Sm9SignMasterKey(Structure):
_fields_ = [
("Ppubs", Sm9TwistPoint),
("ks", sm9_bn_t)
]
def __init__(self):
self._has_public_key = False
self._has_private_key = False
def generate_master_key(self):
if gmssl.sm9_sign_master_key_generate(byref(self)) != 1:
raise NativeError('libgmssl inner error')
self._has_public_key = True
self._has_private_key = True
def extract_key(self, identity):
if self._has_private_key != True:
raise TypeError('has no master key')
key = Sm9SignKey(identity)
identity = identity.encode('utf-8')
if gmssl.sm9_sign_master_key_extract_key(byref(self),
c_char_p(identity), c_size_t(len(identity)), byref(key)) != 1:
raise NativeError('libgmssl inner error')
key._has_public_key = True
key._has_private_key = True
return key
def import_encrypted_master_key_info_pem(self, path, passwd):
libc.fopen.restype = c_void_p
fp = libc.fopen(path.encode('utf-8'), 'rb')
passwd = passwd.encode('utf-8')
if gmssl.sm9_sign_master_key_info_decrypt_from_pem(byref(self),
c_char_p(passwd), c_void_p(fp)) != 1:
raise NativeError('libgmssl inner error')
libc.fclose(c_void_p(fp))
self._has_public_key = True
self._has_private_key = True
def export_encrypted_master_key_info_pem(self, path, passwd):
if self._has_private_key != True:
raise TypeError('has no master key')
libc.fopen.restype = c_void_p
fp = libc.fopen(path.encode('utf-8'), 'wb')
passwd = passwd.encode('utf-8')
if gmssl.sm9_sign_master_key_info_encrypt_to_pem(byref(self),
c_char_p(passwd), c_void_p(fp)) != 1:
raise NativeError('libgmssl inner error')
libc.fclose(c_void_p(fp))
def export_public_master_key_pem(self, path):
if self._has_public_key != True:
raise TypeError('has no public master key')
libc.fopen.restype = c_void_p
fp = libc.fopen(path.encode('utf-8'), 'wb')
if gmssl.sm9_sign_master_public_key_to_pem(byref(self), c_void_p(fp)) != 1:
raise NativeError('libgmssl inner error')
libc.fclose(c_void_p(fp))
def import_public_master_key_pem(self, path):
libc.fopen.restype = c_void_p
fp = libc.fopen(path.encode('utf-8'), 'rb')
if gmssl.sm9_sign_master_public_key_from_pem(byref(self), c_void_p(fp)) != 1:
raise NativeError('libgmssl inner error')
libc.fclose(c_void_p(fp))
self._has_public_key = True
self._has_private_key = False
SM9_SIGNATURE_SIZE = 104
class Sm9Signature(Structure):
_fields_ = [
("sm3", Sm3)
]
def __init__(self, sign = DO_SIGN):
if sign == DO_SIGN:
if gmssl.sm9_sign_init(byref(self)) != 1:
raise NativeError('libgmssl inner error')
else:
if gmssl.sm9_verify_init(byref(self)) != 1:
raise NativeError('libgmssl inner error')
self._sign = sign
self._inited = True
def reset(self):
if self._inited != True:
raise StateError('not initialized')
if self._sign == DO_SIGN:
if gmssl.sm9_sign_init(byref(self)) != 1:
raise NativeError('libgmssl inner error')
else:
if gmssl.sm9_verify_init(byref(self)) != 1:
raise NativeError('libgmssl inner error')
def update(self, data):
if self._inited != True:
raise StateError('not initialized')
if self._sign == DO_SIGN:
if gmssl.sm9_sign_update(byref(self), data, c_size_t(len(data))) != 1:
raise NativeError('libgmssl inner error')
else:
if gmssl.sm9_verify_update(byref(self), data, c_size_t(len(data))) != 1:
raise NativeError('libgmssl inner error')
def sign(self, sign_key):
if self._inited != True:
raise StateError('not initialized')
if self._sign != DO_SIGN:
raise StateError('not sign state')
sig = create_string_buffer(SM9_SIGNATURE_SIZE)
siglen = c_size_t()
if gmssl.sm9_sign_finish(byref(self), byref(sign_key), sig, byref(siglen)) != 1:
raise NativeError('libgmssl inner error')
return sig[:siglen.value]
def verify(self, signature, public_master_key, signer_id):
if self._inited != True:
raise StateError('not initialized')
if self._sign != DO_VERIFY:
raise StateError('not verify state')
signer_id = signer_id.encode('utf-8')
if gmssl.sm9_verify_finish(byref(self), signature, c_size_t(len(signature)),
byref(public_master_key), c_char_p(signer_id), c_size_t(len(signer_id))) != 1:
return False
return True
_ASN1_TAG_IA5String = 22
_ASN1_TAG_SEQUENCE = 0x30
_ASN1_TAG_SET = 0x31
def gmssl_parse_attr_type_and_value(name, d, dlen):
oid = c_int()
tag = c_int()
val = c_void_p()
vlen = c_size_t()
if gmssl.x509_name_type_from_der(byref(oid), byref(d), byref(dlen)) != 1:
raise NativeError('libgmssl inner error')
gmssl.x509_name_type_name.restype = c_char_p
oid_name = gmssl.x509_name_type_name(oid).decode('ascii')
if oid_name == 'emailAddress':
if gmssl.asn1_ia5_string_from_der_ex(_ASN1_TAG_IA5String, byref(val), byref(vlen), byref(d), byref(dlen)) != 1:
raise NativeError('libgmssl inner error')
else:
if gmssl.x509_directory_name_from_der(byref(tag), byref(val), byref(vlen), byref(d), byref(dlen)) != 1:
raise NativeError('libgmssl inner error')
if dlen.value != 0:
raise ValueError('invalid der encoding')
value = create_string_buffer(vlen.value)
libc.memcpy(value, val, vlen)
name[oid_name] = value.raw.decode('utf-8')
return True
def gmssl_parse_rdn(name, d, dlen):
v = c_void_p()
vlen = c_size_t()
while dlen.value > 0:
if gmssl.asn1_type_from_der(_ASN1_TAG_SEQUENCE, byref(v), byref(vlen), byref(d), byref(dlen)) != 1:
raise NativeError('libgmssl inner error')
if gmssl_parse_attr_type_and_value(name, v, vlen) != 1:
raise NativeError('libgmssl inner error')
return True
# https://stacktuts.com/how-to-correctly-pass-pointer-to-pointer-into-dll-in-python-and-ctypes#
def gmssl_parse_name(name, d, dlen):
v = c_void_p()
vlen = c_size_t()
while dlen.value > 0:
if gmssl.asn1_nonempty_type_from_der(c_int(_ASN1_TAG_SET), byref(v), byref(vlen), byref(d), byref(dlen)) != 1:
raise NativeError('libgmssl inner error')
gmssl_parse_rdn(name, v, vlen)
return True
class Validity:
def __init__(self, not_before, not_after):
self.not_before = datetime.datetime.fromtimestamp(not_before)
self.not_after = datetime.datetime.fromtimestamp(not_after)
class Sm2Certificate:
def import_pem(self, path):
cert = c_void_p()
certlen = c_size_t()
if gmssl.x509_cert_new_from_file(byref(cert), byref(certlen), path.encode('utf-8')) != 1:
raise NativeError('libgmssl inner error')
self._cert = create_string_buffer(certlen.value)
libc.memcpy(self._cert, cert, certlen)
libc.free(cert)
def get_raw(self):
return self._cert;
def export_pem(self, path):
libc.fopen.restype = c_void_p
fp = libc.fopen(path.encode('utf-8'), 'wb')
if gmssl.x509_cert_to_pem(self._cert, c_size_t(len(self._cert)), c_void_p(fp)) != 1:
raise NativeError('libgmssl inner error')
def get_serial_number(self):
serial_ptr = c_void_p()
serial_len = c_size_t()
if gmssl.x509_cert_get_issuer_and_serial_number(self._cert, c_size_t(len(self._cert)),
None, None, byref(serial_ptr), byref(serial_len)) != 1:
raise NativeError('libgmssl inner error')
serial = create_string_buffer(serial_len.value)
libc.memcpy(serial, serial_ptr, serial_len)
return serial.raw
def get_issuer(self):
issuer_ptr = c_void_p()
issuer_len = c_size_t()
if gmssl.x509_cert_get_issuer(self._cert, c_size_t(len(self._cert)),
byref(issuer_ptr), byref(issuer_len)) != 1:
raise NativeError('libgmssl inner error')
issuer_raw = create_string_buffer(issuer_len.value)
libc.memcpy(issuer_raw, issuer_ptr, issuer_len)
issuer = { "raw_data" : issuer_raw.raw }
gmssl_parse_name(issuer, issuer_ptr, issuer_len)
return issuer
def get_subject(self):
subject_ptr = c_void_p()
subject_len = c_size_t()
if gmssl.x509_cert_get_subject(self._cert, c_size_t(len(self._cert)),
byref(subject_ptr), byref(subject_len)) != 1:
raise NativeError('libgmssl inner error')
subject_raw = create_string_buffer(subject_len.value)
libc.memcpy(subject_raw, subject_ptr, subject_len)
subject = { "raw_data" : subject_raw.raw }
gmssl_parse_name(subject, subject_ptr, subject_len)
return subject
def get_subject_public_key(self):
public_key = Sm2Key()
gmssl.x509_cert_get_subject_public_key(self._cert, c_size_t(len(self._cert)), byref(public_key))
public_key._has_private_key = False
public_key._has_public_key = True
return public_key
def get_validity(self):
not_before = c_ulong()
not_after = c_ulong()
if gmssl.x509_cert_get_details(self._cert, c_size_t(len(self._cert)),
None, None, None, None, None, None,
byref(not_before), byref(not_after),
None, None, None, None, None, None, None, None, None, None, None, None) != 1:
raise NativeError('libgmssl inner error')
return Validity(not_before.value, not_after.value)
def verify_by_ca_certificate(self, cacert, sm2_id):
cacert_raw = cacert.get_raw()
sm2_id = sm2_id.encode('utf-8')
if gmssl.x509_cert_verify_by_ca_cert(self._cert, c_size_t(len(self._cert)),
cacert_raw, c_size_t(len(cacert_raw)), c_char_p(sm2_id), c_size_t(len(sm2_id))) != 1:
return False
return True
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/czbaa/GmSSL-Python.git
git@gitee.com:czbaa/GmSSL-Python.git
czbaa
GmSSL-Python
GmSSL-Python
main

搜索帮助