Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
if signing:
algorithm_id = Advapi32Const.CALG_RSA_SIGN
else:
algorithm_id = Advapi32Const.CALG_RSA_KEYX
else:
struct_type = 'DSSBLOBHEADER'
algorithm_id = Advapi32Const.CALG_DSS_SIGN
blob_header_pointer = struct(advapi32, 'BLOBHEADER')
blob_header = unwrap(blob_header_pointer)
blob_header.bType = blob_type
blob_header.bVersion = Advapi32Const.CUR_BLOB_VERSION
blob_header.reserved = 0
blob_header.aiKeyAlg = algorithm_id
blob_struct_pointer = struct(advapi32, struct_type)
blob_struct = unwrap(blob_struct_pointer)
blob_struct.publickeystruc = blob_header
bit_size = key_info.bit_size
len1 = bit_size // 8
len2 = bit_size // 16
if algo == 'rsa':
pubkey_pointer = struct(advapi32, 'RSAPUBKEY')
pubkey = unwrap(pubkey_pointer)
pubkey.bitlen = bit_size
if key_type == 'public':
parsed_key_info = key_info['public_key'].parsed
pubkey.magic = Advapi32Const.RSA1
pubkey.pubexp = parsed_key_info['public_exponent'].native
blob_data = int_to_bytes(parsed_key_info['modulus'].native, signed=False, width=len1)[::-1]
blob_struct.cbSeedLength = q_len
blob_struct.cbGroupSize = q_len
blob_struct.Count = byte_array(count)
blob = struct_bytes(blob_struct_pointer)
blob += seed + q + p + g + public_bytes
if key_type == 'private':
blob += fill_width(private_bytes, q_len)
else:
if key_type == 'public':
magic = BcryptConst.BCRYPT_DSA_PUBLIC_MAGIC
else:
magic = BcryptConst.BCRYPT_DSA_PRIVATE_MAGIC
blob_struct_pointer = struct(bcrypt, 'BCRYPT_DSA_KEY_BLOB')
blob_struct = unwrap(blob_struct_pointer)
blob_struct.dwMagic = magic
blob_struct.cbKey = key_width
blob_struct.Count = byte_array(count)
blob_struct.Seed = byte_array(seed)
blob_struct.q = byte_array(q)
blob = struct_bytes(blob_struct_pointer) + p + g + public_bytes
if key_type == 'private':
blob += fill_width(private_bytes, q_len)
elif algo == 'ec':
if key_type == 'public':
blob_type = BcryptConst.BCRYPT_ECCPUBLIC_BLOB
x, y = key_info['public_key'].to_coords()
else:
public_bytes = fill_width(public_bytes, key_width)
p = fill_width(p, key_width)
g = fill_width(g, key_width)
q = fill_width(q, q_len)
# We don't know the count or seed, so we set them to the max value
# since setting them to 0 results in a parameter error
count = b'\xff' * 4
seed = b'\xff' * q_len
if key_info.bit_size > 1024:
if key_type == 'public':
magic = BcryptConst.BCRYPT_DSA_PUBLIC_MAGIC_V2
else:
magic = BcryptConst.BCRYPT_DSA_PRIVATE_MAGIC_V2
blob_struct_pointer = struct(bcrypt, 'BCRYPT_DSA_KEY_BLOB_V2')
blob_struct = unwrap(blob_struct_pointer)
blob_struct.dwMagic = magic
blob_struct.cbKey = key_width
# We don't know if SHA256 was used here, but the output is long
# enough for the generation of q for the supported 2048/224,
# 2048/256 and 3072/256 FIPS approved pairs
blob_struct.hashAlgorithm = BcryptConst.DSA_HASH_ALGORITHM_SHA256
blob_struct.standardVersion = BcryptConst.DSA_FIPS186_3
blob_struct.cbSeedLength = q_len
blob_struct.cbGroupSize = q_len
blob_struct.Count = byte_array(count)
blob = struct_bytes(blob_struct_pointer)
blob += seed + q + p + g + public_bytes
if key_type == 'private':
blob += fill_width(private_bytes, q_len)
else:
blob_type = BcryptConst.BCRYPT_ECCPRIVATE_BLOB
public_key = key_info['private_key'].parsed['public_key']
# We aren't guaranteed to get the public key coords with the
# key info structure, but BCrypt doesn't seem to have an issue
# importing the private key with 0 values, which can only be
# presumed that it is generating the x and y points from the
# private key value and base point
if public_key:
x, y = public_key.to_coords()
else:
x = 0
y = 0
private_bytes = int_to_bytes(key_info['private_key'].parsed['private_key'].native)
blob_struct_pointer = struct(bcrypt, 'BCRYPT_ECCKEY_BLOB')
blob_struct = unwrap(blob_struct_pointer)
magic = {
('public', 'secp256r1'): BcryptConst.BCRYPT_ECDSA_PUBLIC_P256_MAGIC,
('public', 'secp384r1'): BcryptConst.BCRYPT_ECDSA_PUBLIC_P384_MAGIC,
('public', 'secp521r1'): BcryptConst.BCRYPT_ECDSA_PUBLIC_P521_MAGIC,
('private', 'secp256r1'): BcryptConst.BCRYPT_ECDSA_PRIVATE_P256_MAGIC,
('private', 'secp384r1'): BcryptConst.BCRYPT_ECDSA_PRIVATE_P384_MAGIC,
('private', 'secp521r1'): BcryptConst.BCRYPT_ECDSA_PRIVATE_P521_MAGIC,
}[(key_type, curve_name)]
key_width = {
'secp256r1': 32,
'secp384r1': 48,
'secp521r1': 66
}[curve_name]
padding_info = null()
flags = 0
if certificate_or_public_key.algorithm == 'rsa':
if rsa_pss_padding:
flags = BcryptConst.BCRYPT_PAD_PSS
padding_info_struct_pointer = struct(bcrypt, 'BCRYPT_PSS_PADDING_INFO')
padding_info_struct = unwrap(padding_info_struct_pointer)
# This has to be assigned to a variable to prevent cffi from gc'ing it
hash_buffer = buffer_from_unicode(hash_constant)
padding_info_struct.pszAlgId = cast(bcrypt, 'wchar_t *', hash_buffer)
padding_info_struct.cbSalt = len(digest)
else:
flags = BcryptConst.BCRYPT_PAD_PKCS1
padding_info_struct_pointer = struct(bcrypt, 'BCRYPT_PKCS1_PADDING_INFO')
padding_info_struct = unwrap(padding_info_struct_pointer)
# This has to be assigned to a variable to prevent cffi from gc'ing it
if hash_algorithm == 'raw':
padding_info_struct.pszAlgId = null()
else:
hash_buffer = buffer_from_unicode(hash_constant)
padding_info_struct.pszAlgId = cast(bcrypt, 'wchar_t *', hash_buffer)
padding_info = cast(bcrypt, 'void *', padding_info_struct_pointer)
else:
# Windows doesn't use the ASN.1 Sequence for DSA/ECDSA signatures,
# so we have to convert it here for the verification to work
try:
signature = DSASignature.load(signature).to_p1363()
except (ValueError, OverflowError, TypeError):
raise SignatureError('Signature is invalid')
if self._context_handle_pointer is None:
return
out_buffers = None
try:
# ApplyControlToken fails with SEC_E_UNSUPPORTED_FUNCTION
# when called on Windows 7
if _win_version_info >= (6, 2):
buffers = new(secur32, 'SecBuffer[1]')
# This is a SCHANNEL_SHUTDOWN token (DWORD of 1)
buffers[0].cbBuffer = 4
buffers[0].BufferType = Secur32Const.SECBUFFER_TOKEN
buffers[0].pvBuffer = cast(secur32, 'BYTE *', buffer_from_bytes(b'\x01\x00\x00\x00'))
sec_buffer_desc_pointer = struct(secur32, 'SecBufferDesc')
sec_buffer_desc = unwrap(sec_buffer_desc_pointer)
sec_buffer_desc.ulVersion = Secur32Const.SECBUFFER_VERSION
sec_buffer_desc.cBuffers = 1
sec_buffer_desc.pBuffers = buffers
result = secur32.ApplyControlToken(self._context_handle_pointer, sec_buffer_desc_pointer)
handle_error(result, TLSError)
out_sec_buffer_desc_pointer, out_buffers = self._create_buffers(2)
out_buffers[0].BufferType = Secur32Const.SECBUFFER_TOKEN
out_buffers[1].BufferType = Secur32Const.SECBUFFER_ALERT
output_context_flags_pointer = new(secur32, 'ULONG *')
result = secur32.InitializeSecurityContextW(
padding_info = null()
flags = 0
if private_key.algorithm == 'rsa':
if rsa_pss_padding:
hash_length = {
'md5': 16,
'sha1': 20,
'sha256': 32,
'sha384': 48,
'sha512': 64
}[hash_algorithm]
flags = BcryptConst.BCRYPT_PAD_PSS
padding_info_struct_pointer = struct(bcrypt, 'BCRYPT_PSS_PADDING_INFO')
padding_info_struct = unwrap(padding_info_struct_pointer)
# This has to be assigned to a variable to prevent cffi from gc'ing it
hash_buffer = buffer_from_unicode(hash_constant)
padding_info_struct.pszAlgId = cast(bcrypt, 'wchar_t *', hash_buffer)
padding_info_struct.cbSalt = hash_length
else:
flags = BcryptConst.BCRYPT_PAD_PKCS1
padding_info_struct_pointer = struct(bcrypt, 'BCRYPT_PKCS1_PADDING_INFO')
padding_info_struct = unwrap(padding_info_struct_pointer)
# This has to be assigned to a variable to prevent cffi from gc'ing it
if hash_algorithm == 'raw':
padding_info_struct.pszAlgId = null()
else:
hash_buffer = buffer_from_unicode(hash_constant)
padding_info_struct.pszAlgId = cast(bcrypt, 'wchar_t *', hash_buffer)
padding_info = cast(bcrypt, 'void *', padding_info_struct_pointer)