def cms_sign_data(data_to_sign, signing_cert_file_name, signing_key_file_name, outform=PKI_ASN1_FORM, message_digest=DEFAULT_TOKEN_DIGEST_ALGORITHM): """Uses OpenSSL to sign a document. Produces a Base64 encoding of a DER formatted CMS Document http://en.wikipedia.org/wiki/Cryptographic_Message_Syntax :param data_to_sign: data to sign :param signing_cert_file_name: path to the X509 certificate containing the public key associated with the private key used to sign the data :param signing_key_file_name: path to the private key used to sign the data :param outform: Format for the signed document PKIZ_CMS_FORM or PKI_ASN1_FORM :param message_digest: Digest algorithm to use when signing or resigning """ _ensure_subprocess() if isinstance(data_to_sign, six.string_types): data = bytearray(data_to_sign, encoding='utf-8') else: data = data_to_sign process = subprocess.Popen(['openssl', 'cms', '-sign', '-signer', signing_cert_file_name, '-inkey', signing_key_file_name, '-outform', 'PEM', '-nosmimecap', '-nodetach', '-nocerts', '-noattr', '-md', message_digest, ], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=True) output, err, retcode = _process_communicate_handle_oserror( process, data, (signing_cert_file_name, signing_key_file_name)) if retcode != OpensslCmsExitStatus.SUCCESS or ('Error' in err): if retcode == OpensslCmsExitStatus.CREATE_CMS_READ_MIME_ERROR: LOG.error(_LE('Signing error: Unable to load certificate - ' 'ensure you have configured PKI with ' '"keystone-manage pki_setup"')) else: LOG.error(_LE('Signing error: %s'), err) raise subprocess.CalledProcessError(retcode, 'openssl') if outform == PKI_ASN1_FORM: return output.decode('utf-8') else: return output
def _check_keystone_extensions(self, url): """Call Keystone URL and detects the available extensions.""" try: if not url.endswith("/"): url += '/' resp, body = self._request("%sextensions" % url, "GET", headers={'Accept': 'application/json'}) if resp.status_code in (200, 204): # some cases we get No Content if 'extensions' in body and 'values' in body['extensions']: # Parse correct format (per contract) extensions = body['extensions']['values'] elif 'extensions' in body: # Support incorrect, but prevalent format extensions = body['extensions'] else: return dict(message=( _('Unrecognized extensions response from %s') % url)) return dict(self._get_extension_info(e) for e in extensions) elif resp.status_code == 305: return self._check_keystone_extensions(resp['location']) else: raise exceptions.from_response( resp, "GET", "%sextensions" % url) except Exception: _logger.exception(_LE('Failed to check keystone extensions.'))
def _check_keystone_extensions(self, url): """Call Keystone URL and detects the available extensions.""" try: if not url.endswith("/"): url += '/' resp, body = self._request("%sextensions" % url, "GET", headers={'Accept': 'application/json'}) if resp.status_code in (200, 204): # some cases we get No Content if 'extensions' in body and 'values' in body['extensions']: # Parse correct format (per contract) extensions = body['extensions']['values'] elif 'extensions' in body: # Support incorrect, but prevalent format extensions = body['extensions'] else: return dict(message=( _('Unrecognized extensions response from %s') % url)) return dict(self._get_extension_info(e) for e in extensions) elif resp.status_code == 305: return self._check_keystone_extensions(resp['location']) else: raise exceptions.from_response(resp, "GET", "%sextensions" % url) except Exception: _logger.exception(_LE('Failed to check keystone extensions.'))
def _check_keystone_versions(self, url): """Call Keystone URL and detects the available API versions.""" try: resp, body = self._request(url, "GET", headers={'Accept': 'application/json'}) # Multiple Choices status code is returned by the root # identity endpoint, with references to one or more # Identity API versions -- v3 spec # some cases we get No Content if resp.status_code in (200, 204, 300): try: results = {} if 'version' in body: results['message'] = _("Keystone found at %s") % url version = body['version'] # Stable/diablo incorrect format id, status, version_url = (self._get_version_info( version, url)) results[str(id)] = { "id": id, "status": status, "url": version_url } return results elif 'versions' in body: # Correct format results['message'] = _("Keystone found at %s") % url for version in body['versions']['values']: id, status, version_url = (self._get_version_info( version, url)) results[str(id)] = { "id": id, "status": status, "url": version_url } return results else: results['message'] = ( _("Unrecognized response from %s") % url) return results except KeyError: raise exceptions.AuthorizationFailure() elif resp.status_code == 305: return self._check_keystone_versions(resp['location']) else: raise exceptions.from_response(resp, "GET", url) except Exception: _logger.exception(_LE('Failed to detect available versions.'))
def _check_keystone_versions(self, url): """Call Keystone URL and detects the available API versions.""" try: resp, body = self._request(url, "GET", headers={'Accept': 'application/json'}) # Multiple Choices status code is returned by the root # identity endpoint, with references to one or more # Identity API versions -- v3 spec # some cases we get No Content if resp.status_code in (200, 204, 300): try: results = {} if 'version' in body: results['message'] = _("Keystone found at %s") % url version = body['version'] # Stable/diablo incorrect format id, status, version_url = ( self._get_version_info(version, url)) results[str(id)] = {"id": id, "status": status, "url": version_url} return results elif 'versions' in body: # Correct format results['message'] = _("Keystone found at %s") % url for version in body['versions']['values']: id, status, version_url = ( self._get_version_info(version, url)) results[str(id)] = {"id": id, "status": status, "url": version_url} return results else: results['message'] = ( _("Unrecognized response from %s") % url) return results except KeyError: raise exceptions.AuthorizationFailure() elif resp.status_code == 305: return self._check_keystone_versions(resp['location']) else: raise exceptions.from_response(resp, "GET", url) except Exception: _logger.exception(_LE('Failed to detect available versions.'))