def __init__(self, algorithm, key, digest=None, **kwargs): """ Constructor has to obligatory arguments: @param algorithm - which is name of MAC algorithm i.e 'hmac' or 'gost-mac' or equivalent Oid object @param key - byte buffer with key. Optional parameters are: digest - Oid or name of the digest algorithm to use. If none specified, OpenSSL will try to derive one from the MAC algorithm (or if algorithm is hmac, we'll substititute md5 for compatibility with standard hmac module any other keyword argument is passed to EVP_PKEY_CTX as string option. """ if isinstance(algorithm, str): self.algorithm = Oid(algorithm) elif isinstance(algorithm, Oid): self.algorithm = algorithm else: raise TypeError("Algorthm must be string or Oid") if self.algorithm == Oid('hmac') and digest is None: digest = 'md5' self.name = self.algorithm.shortname().lower() if digest is not None: self.digest_type = DigestType(digest) self.name += '-' + self.digest_type.digest_name d = self.digest_type.digest else: self.digest_type = None d = None self.key = libcrypto.EVP_PKEY_new_mac_key(self.algorithm.nid, None, key, len(key)) if self.key is None: raise DigestError("EVP_PKEY_new_mac_key") pctx = c_void_p() self.ctx = libcrypto.EVP_MD_CTX_create() if self.ctx == 0: raise DigestError("Unable to create digest context") if libcrypto.EVP_DigestSignInit(self.ctx, pointer(pctx), d, None, self.key) <= 0: raise DigestError("Unable to intialize digest context") self.digest_finalized = False if self.digest_type is None: self.digest_type = DigestType( Oid(libcrypto.EVP_MD_type(libcrypto.EVP_MD_CTX_md(self.ctx)))) for (name, val) in kwargs.items(): if libcrypto.EVP_PKEY_CTX_ctrl_str(pctx, name, val) <= 0: raise DigestError("Unable to set mac parameter") self.digest_size = self.digest_type.digest_size self.block_size = self.digest_type.block_size
def oid(self): """ Returns Oid object of digest type """ return Oid(libcrypto.EVP_MD_type(self.digest))
def name(self): """ Returns name of the digest """ if not hasattr(self, 'digest_name'): self.digest_name = Oid(libcrypto.EVP_MD_type( self.digest)).longname() return self.digest_name