Ejemplo n.º 1
0
def verify_rsa_signature(signature, signature_method, public_key, data):
    """
  <Purpose>
    Determine whether the corresponding private key of 'public_key' produced
    'signature'.  verify_signature() will use the public key, signature method,
    and 'data' to complete the verification.

    >>> public, private = generate_rsa_public_and_private(2048)
    >>> data = b'The quick brown fox jumps over the lazy dog'
    >>> signature, method = create_rsa_signature(private, data)
    >>> verify_rsa_signature(signature, method, public, data)
    True
    >>> verify_rsa_signature(signature, method, public, b'bad_data')
    False

  <Arguments>
    signature:
      An RSASSA PSS signature, as a string.  This is the signature returned
      by create_rsa_signature().

    signature_method:
      A string that indicates the signature algorithm used to generate
      'signature'.  'RSASSA-PSS' is currently supported.

    public_key:
      The RSA public key, a string in PEM format.

    data:
      Data used by tuf.keys.create_signature() to generate
      'signature'.  'data' (a string) is needed here to verify 'signature'.

  <Exceptions>
    tuf.FormatError, if 'signature', 'signature_method', 'public_key', or
    'data' are improperly formatted.

    tuf.UnknownMethodError, if the signing method used by
    'signature' is not one supported by tuf.keys.create_signature().

    tuf.CryptoError, if the private key cannot be decoded or its key type
    is unsupported.

  <Side Effects>
    pyca/cryptography's RSAPublicKey.verifier() called to do the actual
    verification.

   <Returns>
    Boolean.  True if the signature is valid, False otherwise.
  """

    I_TO_PRINT = TO_PRINT + uptane.YELLOW + '[verify_rsa_signature(signature, signature_method, public_key, data)]: ' + uptane.ENDCOLORS
    #TODO: Print to be deleted
    print(
        str('%s %s %s %s %s %s %s %s %s' %
            (I_TO_PRINT, 'Verifying RSA public_key:', public_key,
             'has generate signature:', signature, 'signature_method:',
             signature_method, 'data:', data)))
    #TODO: Until here

    # Does 'public_key' have the correct format?
    # This check will ensure 'public_key' conforms to 'tuf.formats.PEMRSA_SCHEMA'.
    # Raise 'tuf.FormatError' if the check fails.
    tuf.formats.PEMRSA_SCHEMA.check_match(public_key)

    # Does 'signature_method' have the correct format?
    tuf.formats.NAME_SCHEMA.check_match(signature_method)

    # Does 'signature' have the correct format?
    tuf.formats.PYCACRYPTOSIGNATURE_SCHEMA.check_match(signature)

    # What about 'data'?
    tuf.formats.DATA_SCHEMA.check_match(data)

    # Verify whether the private key of 'public_key' produced 'signature'.
    # Before returning the 'valid_signature' Boolean result, ensure 'RSASSA-PSS'
    # was used as the signing method.
    valid_signature = False

    # Verify the expected 'signature_method' value.
    if signature_method != 'RSASSA-PSS':
        raise tuf.UnknownMethodError(signature_method)

    # Verify the RSASSA-PSS signature with pyca/cryptography.
    try:
        public_key_object = serialization.load_pem_public_key(
            public_key.encode('utf-8'), backend=default_backend())

        # 'salt_length' is set to the digest size of the hashing algorithm (to
        # match the default size used by 'tuf.pycrypto_keys.py').
        verifier = public_key_object.verifier(
            signature,
            padding.PSS(mgf=padding.MGF1(hashes.SHA256()),
                        salt_length=hashes.SHA256().digest_size),
            hashes.SHA256())

        verifier.update(data)

        # verify() raises 'cryptograpahy.exceptions.InvalidSignature' if the
        # signature is invalid.
        try:
            verifier.verify()
            return True

        except cryptography.exceptions.InvalidSignature:
            return False

    # Raised by load_pem_public_key().
    except ValueError:
        raise tuf.CryptoError('The PEM could not be decoded successfully.')

    # Raised by load_pem_public_key().
    except cryptography.exceptions.UnsupportedAlgorithm:
        raise tuf.CryptoError('The private key type is not supported.')
Ejemplo n.º 2
0
def verify_signature(public_key, method, signature, data, use_pynacl=False):
    """
  <Purpose>
    Determine whether the private key corresponding to 'public_key' produced
    'signature'.  verify_signature() will use the public key, the 'method' and
    'sig', and 'data' arguments to complete the verification.

    >>> public, private = generate_public_and_private()
    >>> data = b'The quick brown fox jumps over the lazy dog'
    >>> signature, method = \
        create_signature(public, private, data)
    >>> verify_signature(public, method, signature, data, use_pynacl=False)
    True
    >>> verify_signature(public, method, signature, data, use_pynacl=True)
    True
    >>> bad_data = b'The sly brown fox jumps over the lazy dog'
    >>> bad_signature, method = \
        create_signature(public, private, bad_data)
    >>> verify_signature(public, method, bad_signature, data, use_pynacl=False)
    False
  
  <Arguments>
    public_key:
      The public key is a 32-byte string.

    method:
      'ed25519' signature method generated by either the pure python
      implementation (i.e., 'tuf._vendor.ed25519.ed25519.py') or PyNacl
      (i.e., 'nacl').
      
    signature:
      The signature is a 64-byte string. 
      
    data:
      Data object used by tuf.ed25519_keys.create_signature() to generate
      'signature'.  'data' is needed here to verify the signature.
    
    use_pynacl:
      True, if the ed25519 signature should be verified by PyNaCl.  False,
      if the signature should be verified with the pure Python implementation
      of ed25519 (slower).

  <Exceptions>
    tuf.UnknownMethodError.  Raised if the signing method used by
    'signature' is not one supported by tuf.ed25519_keys.create_signature().
    
    tuf.FormatError. Raised if the arguments are improperly formatted. 

  <Side Effects>
    tuf._vendor.ed25519.ed25519.checkvalid() called to do the actual
    verification.  nacl.signing.VerifyKey.verify() called if 'use_pynacl' is
    True.

  <Returns>
    Boolean.  True if the signature is valid, False otherwise.
  """

    # Does 'public_key' have the correct format?
    # This check will ensure 'public_key' conforms to
    # 'tuf.formats.ED25519PUBLIC_SCHEMA', which must have length 32 bytes.
    # Raise 'tuf.FormatError' if the check fails.
    tuf.formats.ED25519PUBLIC_SCHEMA.check_match(public_key)

    # Is 'method' properly formatted?
    tuf.formats.NAME_SCHEMA.check_match(method)

    # Is 'signature' properly formatted?
    tuf.formats.ED25519SIGNATURE_SCHEMA.check_match(signature)

    # Is 'use_pynacl' properly formatted?
    tuf.formats.BOOLEAN_SCHEMA.check_match(use_pynacl)

    # Verify 'signature'.  Before returning the Boolean result,
    # ensure 'ed25519' was used as the signing method.
    # Raise 'tuf.UnsupportedLibraryError' if 'use_pynacl' is True but 'nacl' is
    # unavailable.
    public = public_key
    valid_signature = False

    if method in _SUPPORTED_ED25519_SIGNING_METHODS:
        if use_pynacl:
            try:
                nacl_verify_key = nacl.signing.VerifyKey(public)
                nacl_message = nacl_verify_key.verify(data, signature)
                valid_signature = True

            except NameError:  # pragma: no cover
                message = 'The PyNaCl library and/or its dependencies unavailable.'
                raise tuf.UnsupportedLibraryError(message)

            except nacl.exceptions.BadSignatureError:
                pass

        # Verify 'ed25519' signature with the pure Python implementation.
        else:
            try:
                tuf._vendor.ed25519.ed25519.checkvalid(signature, data, public)
                valid_signature = True

            # The pure Python implementation raises 'Exception' if 'signature' is
            # invalid.
            except Exception as e:
                pass

    else:
        message = 'Unsupported ed25519 signing method: '+repr(method)+'.\n'+ \
          'Supported methods: '+repr(_SUPPORTED_ED25519_SIGNING_METHODS)+'.'
        raise tuf.UnknownMethodError(message)

    return valid_signature
Ejemplo n.º 3
0
def verify_rsa_signature(signature, signature_method, public_key, data):
    """
  <Purpose>
    Determine whether the corresponding private key of 'public_key' produced
    'signature'.  verify_signature() will use the public key, signature method,
    and 'data' to complete the verification.
    
    >>> public, private = generate_rsa_public_and_private(2048)
    >>> data = b'The quick brown fox jumps over the lazy dog'
    >>> signature, method = create_rsa_signature(private, data)
    >>> verify_rsa_signature(signature, method, public, data)
    True
    >>> verify_rsa_signature(signature, method, public, b'bad_data')
    False

  <Arguments>
    signature:
      An RSASSA PSS signature as a string.  This is the signature returned
      by create_rsa_signature(). 

    signature_method:
      A string that indicates the signature algorithm used to generate
      'signature'.  'RSASSA-PSS' is currently supported.

    public_key:
      The RSA public key, a string in PEM format.

    data:
      Data object used by tuf.keys.create_signature() to generate
      'signature'.  'data' is needed here to verify the signature.

  <Exceptions>
    tuf.UnknownMethodError.  Raised if the signing method used by
    'signature' is not one supported by tuf.keys.create_signature().
    
    tuf.FormatError. Raised if 'signature', 'signature_method', or 'public_key'
    is improperly formatted.

  <Side Effects>
    Crypto.Signature.PKCS1_PSS.verify() called to do the actual verification.

  <Returns>
    Boolean.  True if the signature is valid, False otherwise.
  """

    # Does 'public_key' have the correct format?
    # This check will ensure 'public_key' conforms to 'tuf.formats.PEMRSA_SCHEMA'.
    # Raise 'tuf.FormatError' if the check fails.
    tuf.formats.PEMRSA_SCHEMA.check_match(public_key)

    # Does 'signature_method' have the correct format?
    tuf.formats.NAME_SCHEMA.check_match(signature_method)

    # Does 'signature' have the correct format?
    tuf.formats.PYCRYPTOSIGNATURE_SCHEMA.check_match(signature)

    # Verify whether the private key of 'public_key' produced 'signature'.
    # Before returning the 'valid_signature' Boolean result, ensure 'RSASSA-PSS'
    # was used as the signing method.
    valid_signature = False

    # Verify the signature with PyCrypto if the signature method is valid,
    # otherwise raise 'tuf.UnknownMethodError'.
    if signature_method == 'RSASSA-PSS':
        try:
            rsa_key_object = Crypto.PublicKey.RSA.importKey(public_key)
            pkcs1_pss_verifier = Crypto.Signature.PKCS1_PSS.new(rsa_key_object)
            sha256_object = Crypto.Hash.SHA256.new(data)
            valid_signature = pkcs1_pss_verifier.verify(
                sha256_object, signature)

        except (ValueError, IndexError, TypeError) as e:
            message = 'The RSA signature could not be verified.'
            raise tuf.CryptoError(message)

    else:
        raise tuf.UnknownMethodError(signature_method)

    return valid_signature
Ejemplo n.º 4
0
    if method == 'PyCrypto-PKCS#1 PSS':
        try:
            rsa_key_object = Crypto.PublicKey.RSA.importKey(public_key)
            pkcs1_pss_verifier = Crypto.Signature.PKCS1_PSS.new(rsa_key_object)
            sha256_object = Crypto.Hash.SHA256.new(data)

            # The metadata stores signatures in hex.  Unhexlify and verify the
            # signature.
            signature = binascii.unhexlify(sig)
            valid_signature = pkcs1_pss_verifier.verify(
                sha256_object, signature)
        except (ValueError, IndexError, TypeError), e:
            message = 'The RSA signature could not be verified.'
            raise tuf.CryptoError(message)
    else:
        raise tuf.UnknownMethodError(method)

    return valid_signature


def create_encrypted_pem(rsakey_dict, passphrase):
    """
  <Purpose>
    Return a string in PEM format, where the private part of the RSA key is
    encrypted.  The private part of the RSA key is encrypted by the Triple
    Data Encryption Algorithm (3DES) and Cipher-block chaining (CBC) for the 
    mode of operation.  Password-Based Key Derivation Function 1 (PBKF1) + MD5
    is used to strengthen 'passphrase'.

    https://en.wikipedia.org/wiki/Triple_DES
    https://en.wikipedia.org/wiki/PBKDF2
Ejemplo n.º 5
0
def verify_signature(rsakey_dict, signature, data):
    """
  <Purpose>
    Determine whether the private key belonging to 'rsakey_dict' produced
    'signature'.  verify_signature() will use the public key found in
    'rsakey_dict', the 'method' and 'sig' objects contained in 'signature',
    and 'data' to complete the verification.  Type-checking performed on both
    'rsakey_dict' and 'signature'.

  <Arguments>
    rsakey_dict:
      A dictionary containing the RSA keys and other identifying information.
      'rsakey_dict' has the form:
     
      {'keytype': 'rsa',
       'keyid': keyid,
       'keyval': {'public': '-----BEGIN RSA PUBLIC KEY----- ...',
                  'private': '-----BEGIN RSA PRIVATE KEY----- ...'}}

      The public and private keys are in PEM format and stored as strings.
      
    signature:
      The signature dictionary produced by tuf.rsa_key.create_signature().
      'signature' has the form:
      {'keyid': keyid, 'method': 'method', 'sig': sig}.  Conformant to
      tuf.formats.SIGNATURE_SCHEMA.
      
    data:
      Data object used by tuf.rsa_key.create_signature() to generate
      'signature'.  'data' is needed here to verify the signature.

  <Exceptions>
    tuf.UnknownMethodError.  Raised if the signing method used by
    'signature' is not one supported by tuf.rsa_key.create_signature().
    
    tuf.FormatError. Raised if either 'rsakey_dict'
    or 'signature' do not match their respective tuf.formats schema.
    'rsakey_dict' must conform to tuf.formats.RSAKEY_SCHEMA.
    'signature' must conform to tuf.formats.SIGNATURE_SCHEMA.

  <Side Effects>
    evpy.signature_verify() called to do the actual verification.

  <Returns>
    Boolean.

  """

    # Does 'rsakey_dict' have the correct format?
    # This check will ensure 'rsakey_dict' has the appropriate number
    # of objects and object types, and that all dict keys are properly named.
    # Raise 'tuf.FormatError' if the check fails.
    tuf.formats.RSAKEY_SCHEMA.check_match(rsakey_dict)

    # Does 'signature' have the correct format?
    tuf.formats.SIGNATURE_SCHEMA.check_match(signature)

    # Using the public key belonging to 'rsakey_dict'
    # (i.e., rsakey_dict['keyval']['public']), verify whether 'signature'
    # was produced by rsakey_dict's corresponding private key
    # rsakey_dict['keyval']['private'].  Before returning the Boolean result,
    # ensure 'evp' was used as the signing method.

    method = signature['method']
    sig = signature['sig']
    public_key = rsakey_dict['keyval']['public']

    if method != 'evp':
        raise tuf.UnknownMethodError(method)
    return evpy.signature.verify(data, binascii.unhexlify(sig), key=public_key)
Ejemplo n.º 6
0
                nacl_message = nacl_verify_key.verify(data, sig)
                if nacl_message == data:
                    valid_signature = True
            except nacl.signing.BadSignatureError:
                pass

        # Verify signature with 'ed25519-python' (i.e., pure Python implementation).
        else:
            try:
                ed25519.ed25519.checkvalid(sig, data, public)
                valid_signature = True

            # The pure Python implementation raises 'Exception' if 'signature' is
            # invalid.
            except Exception, e:
                pass
    else:
        message = 'Unsupported ed25519 signing method: '+repr(method)+'.\n'+ \
          'Supported methods: '+repr(_SUPPORTED_ED25519_SIGNING_METHODS)+'.'
        raise tuf.UnknownMethodError(message)

    return valid_signature


if __name__ == '__main__':
    # The interactive sessions of the documentation strings can
    # be tested by running 'ed25519_key.py' as a standalone module.
    # python -B ed25519_key.py
    import doctest
    doctest.testmod()