def fake_old_verify_signature(context, checksum_hash, image_properties): if (image_properties is not None and 'signature' in image_properties and image_properties['signature'] == 'VALID'): return True else: raise exception.SignatureVerificationError( 'Signature verification failed.')
def get_public_key(context, signature_certificate_uuid, signature_key_type): """Create the public key object from a retrieved certificate. :param context: the user context for authentication :param signature_certificate_uuid: the uuid to use to retrieve the certificate :param signature_key_type: a SignatureKeyType object :returns: the public key cryptography object :raises xmonitor.common.exception.SignatureVerificationError: if public key format is invalid """ certificate = get_certificate(context, signature_certificate_uuid) # Note that this public key could either be # RSAPublicKey, DSAPublicKey, or EllipticCurvePublicKey public_key = certificate.public_key() # Confirm the type is of the type expected based on the signature key type if not isinstance(public_key, signature_key_type.public_key_type): raise exception.SignatureVerificationError( _('Invalid public key type for signature key type: %s') % signature_key_type ) return public_key
def get_certificate(context, signature_certificate_uuid): """Create the certificate object from the retrieved certificate data. :param context: the user context for authentication :param signature_certificate_uuid: the uuid to use to retrieve the certificate :returns: the certificate cryptography object :raises xmonitor.common.exception.SignatureVerificationError: if the retrieval fails or the format is invalid """ keymgr_api = key_manager.API() try: # The certificate retrieved here is a castellan certificate object cert = keymgr_api.get(context, signature_certificate_uuid) except Exception as e: # The problem encountered may be backend-specific, since castellan # can use different backends. Rather than importing all possible # backends here, the generic "Exception" is used. msg = (_LE("Unable to retrieve certificate with ID %(id)s: %(e)s") % {'id': signature_certificate_uuid, 'e': encodeutils.exception_to_unicode(e)}) LOG.error(msg) raise exception.SignatureVerificationError( _('Unable to retrieve certificate with ID: %s') % signature_certificate_uuid ) if cert.format not in CERTIFICATE_FORMATS: raise exception.SignatureVerificationError( _('Invalid certificate format: %s') % cert.format ) if cert.format == X_509: # castellan always encodes certificates in DER format cert_data = cert.get_encoded() certificate = x509.load_der_x509_certificate(cert_data, default_backend()) else: raise exception.SignatureVerificationError( _('Certificate format not supported: %s') % cert.format ) # verify the certificate verify_certificate(certificate) return certificate
def get_verifier(context, image_properties): """Retrieve the image properties and use them to create a verifier. :param context: the user context for authentication :param image_properties: the key-value properties about the image :return: instance of cryptography AsymmetricVerificationContext :raises xmonitor.common.exception.SignatureVerificationError: if building the verifier fails """ if not should_create_verifier(image_properties): raise exception.SignatureVerificationError( _('Required image properties for signature verification do not' ' exist. Cannot verify signature.') ) signature = get_signature(image_properties[SIGNATURE]) hash_method = get_hash_method(image_properties[HASH_METHOD]) signature_key_type = SignatureKeyType.lookup( image_properties[KEY_TYPE]) public_key = get_public_key(context, image_properties[CERT_UUID], signature_key_type) # create the verifier based on the signature key type try: verifier = signature_key_type.create_verifier(signature, hash_method, public_key) except crypto_exception.UnsupportedAlgorithm as e: msg = (_LE("Unable to create verifier since algorithm is " "unsupported: %(e)s") % {'e': encodeutils.exception_to_unicode(e)}) LOG.error(msg) raise exception.SignatureVerificationError( _('Unable to verify signature since the algorithm is unsupported ' 'on this system') ) if verifier: return verifier else: # Error creating the verifier raise exception.SignatureVerificationError( _('Error occurred while creating the verifier') )
def verify_certificate(certificate): """Verify that the certificate has not expired. :param certificate: the cryptography certificate object :raises xmonitor.common.exception.SignatureVerificationError: if the certificate valid time range does not include now """ # Get now in UTC, since certificate returns times in UTC now = datetime.datetime.utcnow() # Confirm the certificate valid time range includes now if now < certificate.not_valid_before: raise exception.SignatureVerificationError( _('Certificate is not valid before: %s UTC') % certificate.not_valid_before ) elif now > certificate.not_valid_after: raise exception.SignatureVerificationError( _('Certificate is not valid after: %s UTC') % certificate.not_valid_after )
def lookup(cls, name): """Look up the signature key type. :param name: the name of the signature key type :returns: the SignatureKeyType object :raises: xmonitor.common.exception.SignatureVerificationError if signature key type is invalid """ if name not in cls._REGISTERED_TYPES: raise exception.SignatureVerificationError( _('Invalid signature key type: %s') % name ) return cls._REGISTERED_TYPES[name]
def get_hash_method(hash_method_name): """Verify the hash method name and create the hash method. :param hash_method_name: the name of the hash method to retrieve :returns: the hash method, a cryptography object :raises xmonitor.common.exception.SignatureVerificationError: if the hash method name is invalid """ if hash_method_name not in HASH_METHODS: raise exception.SignatureVerificationError( _('Invalid signature hash method: %s') % hash_method_name ) return HASH_METHODS[hash_method_name]
def get_signature(signature_data): """Decode the signature data and returns the signature. :param signature_data: the base64-encoded signature data :returns: the decoded signature :raises xmonitor.common.exception.SignatureVerificationError: if the signature data is malformatted """ try: signature = base64.decode_as_bytes(signature_data) except (TypeError, binascii.Error): raise exception.SignatureVerificationError( _('The signature data was not properly encoded using base64') ) return signature
def set_data(self, data, size=None): if size is None: size = 0 # NOTE(markwash): zero -> unknown size # Create the verifier for signature verification (if correct properties # are present) if (signature_utils.should_create_verifier( self.image.extra_properties)): # NOTE(bpoulos): if creating verifier fails, exception will be # raised verifier = signature_utils.get_verifier( self.context, self.image.extra_properties) else: verifier = None location, size, checksum, loc_meta = self.store_api.add_to_backend( CONF, self.image.image_id, utils.LimitingReader(utils.CooperativeReader(data), CONF.image_size_cap), size, context=self.context, verifier=verifier) # NOTE(bpoulos): if verification fails, exception will be raised if verifier: try: verifier.verify() LOG.info(_LI("Successfully verified signature for image %s"), self.image.image_id) except crypto_exception.InvalidSignature: raise exception.SignatureVerificationError( _('Signature verification failed')) self.image.locations = [{ 'url': location, 'metadata': loc_meta, 'status': 'active' }] self.image.size = size self.image.checksum = checksum self.image.status = 'active'