ó 9(Zc@s=dZddlZddlZddlZddlZddlmZmZmZm Z m Z ddl m Z ddl ZddlmZejeƒZejdeƒdefd„ƒYƒZejejƒd efd „ƒYƒZejdeƒd efd „ƒYƒZejejƒd efd„ƒYƒZdS(s.Base class interface for Master Key Providers.iÿÿÿÿN(tConfigMismatchErrortDecryptKeyErrortIncorrectMasterKeyErrortInvalidKeyIdErrortMasterKeyProviderError(tto_bytes(t MasterKeyInfothashtMasterKeyProviderConfigcBseZdZRS(s‡Provides a common ancestor for MasterKeyProvider configuration objects and a stand-in point if common params are needed later. (t__name__t __module__t__doc__(((sQ/tmp/pip-build-wDUJoH/aws-encryption-sdk/aws_encryption_sdk/key_providers/base.pyRstMasterKeyProvidercBs¶eZdZeZejd„ƒZejd„ƒZd„Z d„Z dd„Z ej d„ƒZd„Zd„Zd „Zd „Zd „ZeZd „Zd „Zd„ZRS(s¯Parent interface for Master Key Provider classes. :param config: Configuration object :type config: aws_encryption_sdk.key_providers.base.MasterKeyProviderConfig cCsdS(s‡String defining provider ID. .. note:: Must be implemented by specific MasterKeyProvider implementations. N((tself((sQ/tmp/pip-build-wDUJoH/aws-encryption-sdk/aws_encryption_sdk/key_providers/base.pyt provider_id1scCsdS(s¡Configuration class to use when setting up this class. .. note:: Must be implemented by specific MasterKeyProvider implementations. N((R ((sQ/tmp/pip-build-wDUJoH/aws-encryption-sdk/aws_encryption_sdk/key_providers/base.pyt _config_class9scKsvtt|ƒj|ƒ}|jddƒ}t||jƒsN|j|}n||_i|_g|_ i|_ |S(s}Set key index and member set for all new instances here to avoid requiring child classes to call super init. tconfigN( tsuperR t__new__tpoptNonet isinstanceRRt_encrypt_key_indext_memberst_decrypt_key_index(tclstkwargstinstanceR((sQ/tmp/pip-build-wDUJoH/aws-encryption-sdk/aws_encryption_sdk/key_providers/base.pyRAs    c CsVdjd|jjddjd„ttj|jdtƒj ƒdd„ƒDƒƒƒS( sBuilds the proper repr string.s{name}({kwargs})tnameRs, css-|]#\}}djd|d|ƒVqdS(s {key}={value}tkeytvalueN(tformat(t.0RR((sQ/tmp/pip-build-wDUJoH/aws-encryption-sdk/aws_encryption_sdk/key_providers/base.pys WstrecurseRcSs|dS(Ni((tx((sQ/tmp/pip-build-wDUJoH/aws-encryption-sdk/aws_encryption_sdk/key_providers/base.pyt\s( Rt __class__R tjointsortedtattrtasdictRtTruetitems(R ((sQ/tmp/pip-build-wDUJoH/aws-encryption-sdk/aws_encryption_sdk/key_providers/base.pyt__repr__Rs  c Cs|d}g}xN|jD]C}|j|||ƒ\}}|dkrL|}n|j|ƒqW|srtdƒ‚n||fS(sÄReturns a set containing all Master Keys added to this Provider, or any member Providers, which should be used to encrypt data keys for the specified data. .. note:: This does not necessarily include all Master Keys accessible from this Provider. .. note:: The Primary Master Key is the first Master Key added to this Master Key Provider and is the Master Key which will be used to generate the data key. .. warning:: If plaintext_rostream seek position is modified, it must be returned before leaving method. :param dict encryption_context: Encryption context passed to client :param plaintext_rostream: Source plaintext read-only stream :type plaintext_rostream: aws_encryption_sdk.internal.utils.streams.ROStream :param int plaintext_length: Length of source plaintext (optional) :returns: Tuple containing Primary Master Key and List of all Master Keys added to this Provider and any member Providers :rtype: tuple containing :class:`aws_encryption_sdk.key_providers.base.MasterKey` and list of :class:`aws_encryption_sdk.key_providers.base.MasterKey` s1No Master Keys available from Master Key ProviderN(RRtmaster_keys_for_encryptiontextendR( R tencryption_contexttplaintext_rostreamtplaintext_lengthtprimaryt master_keystmember_providert_primaryt _master_keys((sQ/tmp/pip-build-wDUJoH/aws-encryption-sdk/aws_encryption_sdk/key_providers/base.pyR,as  cCsdS(sReturns a Master Key based on the specified key_id. .. note:: Must be implemented by specific MasterKeyProvider implementations. :param bytes key_id: Key ID with which to create MasterKey :returns: Master Key based on key_id :rtype: aws_encryption_sdk.key_providers.base.MasterKey :raises MasterKeyProviderError: if invalid key id format N((R tkey_id((sQ/tmp/pip-build-wDUJoH/aws-encryption-sdk/aws_encryption_sdk/key_providers/base.pyt_new_master_key‡scCsNt|ƒ}||jkrJ|j|ƒ}|jj|ƒ||j|(R t key_providersR=((sQ/tmp/pip-build-wDUJoH/aws-encryption-sdk/aws_encryption_sdk/key_providers/base.pyt"add_master_key_providers_from_list¯s cCs$t|ƒ}|j|ƒ|j|S(s>Returns a master key for encrypt based on the specified key_id, adding it to this provider if not already present. :param bytes key_id: Key ID with which to find or create Master Key :returns: Master Key based on key_id :rtype: aws_encryption_sdk.key_providers.base.MasterKey (RR:R(R R6((sQ/tmp/pip-build-wDUJoH/aws-encryption-sdk/aws_encryption_sdk/key_providers/base.pytmaster_key_for_encrypt¸s  cCsrt|ƒ}y|j|SWntk r.nXy|j|SWntk rQnX|j|ƒ}||j|<|S(sHReturns a master key for decrypt based on the specified key_info. This is only added to this master key provider for the decrypt path. :param bytes key_info: Key info from encrypted data key :returns: Master Key based on key_info :rtype: aws_encryption_sdk.key_providers.base.MasterKey (RRtKeyErrorRR7(R tkey_infotdecrypt_master_key((sQ/tmp/pip-build-wDUJoH/aws-encryption-sdk/aws_encryption_sdk/key_providers/base.pytmaster_key_for_decryptÆs    cCssd }d }tjdƒx>|g|jD],}|j|jjkr*tjd|jƒt|tƒr}tjdƒ|}nk|jr*y/tjd|jj ƒ|j |jj ƒ}Wqèt k rátjd|jj ƒq*qèXnq*y/tjd|jj ƒ|j |||ƒ}Wn8t tfk rQ}tjdt|ƒ|jƒq*nXPq*q*W|sotdƒ‚n|S( sªIterates through all currently added Master Keys and Master Key Providers to attempt to decrypt data key. :param encrypted_data_key: Encrypted data key to decrypt :type encrypted_data_key: aws_encryption_sdk.structures.EncryptedDataKey :param algorithm: Algorithm object which directs how this Master Key will encrypt the data key :type algorithm: aws_encryption_sdk.identifiers.Algorithm :param dict encryption_context: Encryption context to use in encryption :returns: Decrypted data key :rtype: aws_encryption_sdk.structures.DataKey :raises DecryptKeyError: if unable to decrypt encrypted data key s!starting decrypt data key attempts5attempting to locate master key from key provider: %ssusing existing master keys attempting to add master key: %ss'master key %s not available in providers/attempting to decrypt data key with provider %ss@%s raised when attempting to decrypt data key with master key %ssUnable to decrypt data keyN(Rt_LOGGERtdebugRRR=Rt MasterKeytvend_masterkey_on_decryptRCRERtdecrypt_data_keyRRtrepr(R tencrypted_data_keyt algorithmR.tdata_keyR9tmemberterror((sQ/tmp/pip-build-wDUJoH/aws-encryption-sdk/aws_encryption_sdk/key_providers/base.pyRJÛsD           cCsad}x?|D]7}y|j|||ƒ}Wntk rBq q XPq W|s]tdƒ‚n|S(sÇReceives a list of encrypted data keys and returns the first one which this provider is able to decrypt. :param encrypted_data_keys: List of encrypted data keys :type encrypted_data_keys: list of :class:`aws_encryption_sdk.structures.EncryptedDataKey` :param algorithm: Algorithm object which directs how this Master Key will encrypt the data key :type algorithm: aws_encryption_sdk.identifiers.Algorithm :param dict encryption_context: Encryption context to use in encryption :returns: Decrypted data key :rtype: aws_encryption_sdk.structures.DataKey :raises DecryptKeyError: if unable to decrypt any of the supplied encrypted data keys sUnable to decrypt any data keyN(RRJR(R tencrypted_data_keysRMR.RNRL((sQ/tmp/pip-build-wDUJoH/aws-encryption-sdk/aws_encryption_sdk/key_providers/base.pytdecrypt_data_key_from_lists   N(R R R R)RItabctabstractpropertyRRRR+RR,tabstractmethodR7R:R<R>R@RAR9RERJRR(((sQ/tmp/pip-build-wDUJoH/aws-encryption-sdk/aws_encryption_sdk/key_providers/base.pyR &s"   &     4tMasterKeyConfigcBsJeZdZejdedejjej e fƒde ƒZ d„Z RS(s`Configuration object for MasterKey objects. :param bytes key_id: Key ID for Master Key Rt validatortconvertcCs"t|dƒstdƒ‚ndS(sDVerify that children of this class define a "provider_id" attribute.RsIInstances of MasterKeyConfig must have a "provider_id" attribute defined.N(thasattrt TypeError(R ((sQ/tmp/pip-build-wDUJoH/aws-encryption-sdk/aws_encryption_sdk/key_providers/base.pyt__attrs_post_init__5s(R R R R'tibR)t validatorst instance_oftsixt string_typestbytesRR6R[(((sQ/tmp/pip-build-wDUJoH/aws-encryption-sdk/aws_encryption_sdk/key_providers/base.pyRV(s   RHcBsžeZdZd„Zed„ƒZd„Zd d„Zd„Z d„Z d„Z e j d„ƒZd „Ze j d „ƒZd „Ze j d „ƒZRS(sÍParent interface for Master Key classes. :param bytes key_id: Key ID for Master Key :param config: Configuration object :type config: aws_encryption_sdk.key_providers.base.MasterKeyConfig cKsìtt|ƒj||}t|jdƒs<tdƒ‚n|jjdk r±|jdkro|jj|_q±|j|jjkr±tdj d|jjd|jƒƒ‚q±n|jj |_ i||j 6|_ i|_ |g|_ |S(s0Performs universal prep work for all MasterKeys.RsEMasterKey config classes must have a "provider_id" attribute defined.sOConfig provider_id does not match MasterKey provider_id: {config} != {instance}RRN(RRHRRYRRZRRRRR6RRR(RRR((sQ/tmp/pip-build-wDUJoH/aws-encryption-sdk/aws_encryption_sdk/key_providers/base.pyRDs     cCst|j|jƒS(s¾Provides the MasterKeyInfo object identifying this MasterKey. :returns: This MasterKey's Identifying Information :rtype: aws_encryption_sdk.structures.MasterKeyInfo (RRR6(R ((sQ/tmp/pip-build-wDUJoH/aws-encryption-sdk/aws_encryption_sdk/key_providers/base.pyR=]scCs|j|jkrtStS(s…Determines if data_key object is owned by this MasterKey. :param data_key: Data key to evaluate :type data_key: :class:`aws_encryption_sdk.structures.DataKey`, :class:`aws_encryption_sdk.structures.RawDataKey`, or :class:`aws_encryption_sdk.structures.EncryptedDataKey` :returns: Boolean statement of ownership :rtype: bool (R=R)tFalse(R RN((sQ/tmp/pip-build-wDUJoH/aws-encryption-sdk/aws_encryption_sdk/key_providers/base.pyt owns_data_keyfs cCs ||gfS(sþReturns self and a list containing self, to match the format of output for a Master Key Provider. .. warning:: If plaintext_stream seek position is modified, it must be returned before leaving method. :param dict encryption_context: Encryption context passed to client :param plaintext_rostream: Source plaintext read-only stream :type plaintext_rostream: aws_encryption_sdk.internal.utils.streams.ROStream :param int plaintext_length: Length of source plaintext (optional) :returns: Tuple containing self and a list of self :rtype: tuple containing :class:`aws_encryption_sdk.key_providers.base.MasterKey` and list of :class:`aws_encryption_sdk.key_providers.base.MasterKey` ((R R.R/R0((sQ/tmp/pip-build-wDUJoH/aws-encryption-sdk/aws_encryption_sdk/key_providers/base.pyR,tscCs7||jkr3tdjd|d|jƒƒ‚n|S(s¶Returns self as master key instance. :param bytes key_id: ID of key to return :returns: self :raises InvalidKeyIdError: if key_id is not ID for self sZMasterKeys can only provide themselves. Requested {requested} but only {key} is availablet requestedR(R6RR(R R6((sQ/tmp/pip-build-wDUJoH/aws-encryption-sdk/aws_encryption_sdk/key_providers/base.pyR7„s  cCs:|j|ƒs6tdjd|jd|jƒƒ‚ndS(s®Verifies that supplied Data Key's key provider matches this Master Key. :param data_key: Data Key to verify :type data_key: :class:`aws_encryption_sdk.structures.RawDataKey`, :class:`aws_encryption_sdk.structures.DataKey`, or :class:`aws_encryption_sdk.structures.EncryptedDataKey` :raises IncorrectMasterKeyError: if Data Key's key provider does not match this Master Key sLProvided data key provider {key} does not match Master Key provider {master}RtmasterN(RcRRR=(R RN((sQ/tmp/pip-build-wDUJoH/aws-encryption-sdk/aws_encryption_sdk/key_providers/base.pyt _key_check”s   cCsHtjd|ƒ|jd|d|ƒ}tjjjd|d|ƒ|S(soGenerates and returns data key for use encrypting message. :param algorithm: Algorithm on which to base data key :type algorithm: aws_encryption_sdk.identifiers.Algorithm :param dict encryption_context: Encryption context to use in encryption :returns: Generated data key :rtype: aws_encryption_sdk.structures.DataKey s/generating data key with encryption context: %sRMR.tsource_data_key(RFtinfot_generate_data_keytaws_encryption_sdktinternaltutilstsource_data_key_length_check(R RMR.tgenerated_data_key((sQ/tmp/pip-build-wDUJoH/aws-encryption-sdk/aws_encryption_sdk/key_providers/base.pytgenerate_data_key¥s   cCsdS(sÇPerforms the provider-specific data key generation task. .. note:: Must be implemented by specific MasterKey implementations. :param algorithm: Algorithm on which to base data key :type algorithm: aws_encryption_sdk.identifiers.Algorithm :param dict encryption_context: Encryption context to use in encryption :returns: Generated data key :rtype: aws_encryption_sdk.structures.DataKey N((R RMR.((sQ/tmp/pip-build-wDUJoH/aws-encryption-sdk/aws_encryption_sdk/key_providers/base.pyRi¹scCs,tjd|ƒ|jd|d|d|ƒS(s±Encrypts a supplied data key. :param data_key: Unencrypted data key :type data_key: :class:`aws_encryption_sdk.structures.RawDataKey` or :class:`aws_encryption_sdk.structures.DataKey` :param algorithm: Algorithm object which directs how this Master Key will encrypt the data key :type algorithm: aws_encryption_sdk.identifiers.Algorithm :param dict encryption_context: Encryption context to use in encryption :returns: Data key containing encrypted data key :rtype: aws_encryption_sdk.structures.EncryptedDataKey :raises IncorrectMasterKeyError: if Data Key's key provider does not match this Master Key s/encrypting data key with encryption context: %sRNRMR.(RFRht_encrypt_data_key(R RNRMR.((sQ/tmp/pip-build-wDUJoH/aws-encryption-sdk/aws_encryption_sdk/key_providers/base.pytencrypt_data_keyÇs  cCsdS(sÿPerforms the provider-specific data key encryption actions. .. note:: Must be implemented by specific MasterKey implementations. :param data_key: Unencrypted data key :type data_key: :class:`aws_encryption_sdk.structures.RawDataKey` or :class:`aws_encryption_sdk.structures.DataKey` :param algorithm: Algorithm object which directs how this Master Key will encrypt the data key :type algorithm: aws_encryption_sdk.identifiers.Algorithm :param dict encryption_context: Encryption context to use in encryption :returns: Decrypted data key :rtype: aws_encryption_sdk.structures.EncryptedDataKey :raises EncryptKeyError: if Master Key is unable to encrypt data key N((R RNRMR.((sQ/tmp/pip-build-wDUJoH/aws-encryption-sdk/aws_encryption_sdk/key_providers/base.pyRpÛscCs[tjd|ƒ|j|ƒ|jd|d|d|ƒ}tjjjd|d|ƒ|S(smDecrypts an encrypted data key and returns the plaintext. :param data_key: Encrypted data key :type data_key: aws_encryption_sdk.structures.EncryptedDataKey :param algorithm: Algorithm object which directs how this Master Key will encrypt the data key :type algorithm: aws_encryption_sdk.identifiers.Algorithm :param dict encryption_context: Encryption context to use in decryption :returns: Decrypted data key :rtype: aws_encryption_sdk.structures.DataKey :raises IncorrectMasterKeyError: if Data Key's key provider does not match this Master Key s/decrypting data key with encryption context: %sRLRMR.Rg(RFRhRft_decrypt_data_keyRjRkRlRm(R RLRMR.tdecrypted_data_key((sQ/tmp/pip-build-wDUJoH/aws-encryption-sdk/aws_encryption_sdk/key_providers/base.pyRJís    cCsdS(sÅDecrypts an encrypted data key and returns the plaintext. .. note:: Must be implemented by specific MasterKey implementations. :param data_key: Encrypted data key :type data_key: aws_encryption_sdk.structures.EncryptedDataKey :param algorithm: Algorithm object which directs how this Master Key will encrypt the data key :type algorithm: aws_encryption_sdk.identifiers.Algorithm :param dict encryption_context: Encryption context to use in decryption :returns: Data key containing decrypted data key :rtype: aws_encryption_sdk.structures.DataKey :raises DecryptKeyError: if Master Key is unable to decrypt data key N((R RLRMR.((sQ/tmp/pip-build-wDUJoH/aws-encryption-sdk/aws_encryption_sdk/key_providers/base.pyRrsN(R R R RtpropertyR=RcRR,R7RfRoRSRURiRqRpRJRr(((sQ/tmp/pip-build-wDUJoH/aws-encryption-sdk/aws_encryption_sdk/key_providers/base.pyRH;s        (R RStloggingR'R_taws_encryption_sdk.exceptionsRRRRRt#aws_encryption_sdk.internal.str_opsRt!aws_encryption_sdk.internal.utilsRjtaws_encryption_sdk.structuresRt getLoggerR RFtsR)tobjectRt add_metaclasstABCMetaR RVRH(((sQ/tmp/pip-build-wDUJoH/aws-encryption-sdk/aws_encryption_sdk/key_providers/base.pyt s$    ( ÿ