blob: 4adefe0a7b753d60213c4610815d8dccb7b7cdd7 [file] [log] [blame]
#
# Copyright 2018-2020 NXP
# SPDX-License-Identifier: Apache-2.0
#
#
"""License text"""
import os
import ctypes
import logging
import binascii
from . import sss_api as apis
from .keystore import KeyStore
from .keyobject import KeyObject
from .asymmetric import Asymmetric
from .const import HASH
from .util import hash_convert, hash_convert_raw, parse_signature, \
load_certificate, transform_key_to_list
log = logging.getLogger(__name__)
class Verify: # pylint: disable=too-few-public-methods
"""
Verify operation
"""
def __init__(self, session_obj):
"""
Constructor
:param session_obj: Instance of session
"""
self._session = session_obj
self._ctx_ks = KeyStore(self._session)
self._ctx_key = KeyObject(self._ctx_ks)
self.hash_algo = apis.kAlgorithm_None
def do_verification(self, key_id, input_file, signature_file, # pylint: disable=too-many-locals, too-many-arguments
encode_format="", hash_algo=''):
"""
Do verify operation
:param key_id: Key index
:param input_file: Input data to verify with signature
:param signature_file: Input signed data to verify with raw data
:param encode_format: file Encode format. Eg: PEM, DER
:param hash_algo: hash algorithm for verify
:return: Status
"""
status, object_type, cipher_type = self._ctx_key.get_handle(key_id) # pylint: disable=unused-variable
if status != apis.kStatus_SSS_Success:
return status
if hash_algo == '':
# Default hash algorithm
if cipher_type in [apis.kSSS_CipherType_RSA, apis.kSSS_CipherType_RSA_CRT]:
log.debug("Considering Algorithm_SSS_RSASSA_PKCS1_PSS_MGF1_SHA256"
" as Default hash algorithm for RSA")
self.hash_algo = apis.kAlgorithm_SSS_RSASSA_PKCS1_PSS_MGF1_SHA256
elif cipher_type in [apis.kSSS_CipherType_EC_TWISTED_ED]:
log.debug("Considering Algorithm_SSS_SHA512 as Default hash algorithm")
self.hash_algo = apis.kAlgorithm_SSS_SHA512
else:
log.debug("Considering Algorithm_SSS_SHA256 as Default hash algorithm")
self.hash_algo = apis.kAlgorithm_SSS_SHA256
else:
# Take hash algorithm from user
self.hash_algo = HASH[hash_algo]
try:
if not os.path.isfile(input_file):
raise Exception("Incorrect input file, try verifying with correct input file !!")
if cipher_type in [apis.kSSS_CipherType_EC_TWISTED_ED]:
digest, digest_len = load_certificate(input_file)
else:
(digest, digest_len) = hash_convert(input_file, encode_format, self.hash_algo)
except Exception as exc: # pylint: disable=broad-except
# If input data is not certificate, then load it as binary data
if 'Unable to load certificate' in str(exc):
if os.path.isfile(input_file):
with open(input_file, 'rb') as raw_data:
src_data = raw_data.read()
if cipher_type in [apis.kSSS_CipherType_EC_TWISTED_ED]:
cert_hex = binascii.hexlify(src_data)
digest = transform_key_to_list(cert_hex)
digest_len = len(digest)
else:
(digest, digest_len) = hash_convert_raw(src_data, self.hash_algo)
else:
raise Exception("Incorrect input file, try verifying with correct input file !!")
else:
raise exc
try:
(signature, signature_len) = parse_signature(signature_file, encode_format)
except IOError as exc:
log.error(exc)
return apis.kStatus_SSS_Fail
digest_ctype = (ctypes.c_ubyte * digest_len)(*digest)
mode = apis.kMode_SSS_Verify
signature_ctype = (ctypes.c_uint8 * signature_len)(*signature)
signature_len_ctype = ctypes.c_size_t(signature_len)
ctx_asymm = Asymmetric(self._session, self._ctx_key, self.hash_algo, mode)
if cipher_type in [apis.kSSS_CipherType_EC_TWISTED_ED]:
status = ctx_asymm.se05x_verify(
digest_ctype, digest_len, signature_ctype, signature_len_ctype)
else:
status = ctx_asymm.verify(
digest_ctype, digest_len, signature_ctype, signature_len_ctype)
return status