diff --git a/doc/source/configuration.rst b/doc/source/configuration.rst index 310ab05eda..8246f753ce 100644 --- a/doc/source/configuration.rst +++ b/doc/source/configuration.rst @@ -437,8 +437,8 @@ configuring the following property. :class:`keystone.token.providers.uuid.Provider` -UUID, PKI, PKIZ, or Fernet? -^^^^^^^^^^^^^^^^^^^^^^^^^^^ +UUID or Fernet? +^^^^^^^^^^^^^^^ Each token format uses different technologies to achieve various performance, scaling and architectural requirements. @@ -449,29 +449,6 @@ transport and are thus URL-friendly. They must be persisted by the identity service in order to be later validated. Revoking them is simply a matter of deleting them from the token persistence backend. -Both PKI and PKIZ tokens contain JSON payloads that represent the entire token -validation response that would normally be retrieved from keystone. The payload -is then signed using `Cryptographic Message Syntax (CMS) -`_. The combination -of CMS and the exhaustive payload allows PKI and PKIZ tokens to be verified -offline using keystone's public signing key. The only reason for them to be -persisted by the identity service is to later build token revocation *lists* -(explicit lists of tokens that have been revoked), otherwise they are -theoretically ephemeral when supported by token revocation *events* (which -describe invalidated tokens rather than enumerate them). PKIZ tokens add zlib -compression after signing to achieve a smaller overall token size. To make them -URL-friendly, PKI tokens are base64 encoded and then arbitrarily manipulated to -replace unsafe characters with safe ones whereas PKIZ tokens use conventional -base64url encoding. Due to the size of the payload and the overhead incurred by -the CMS format, both PKI and PKIZ tokens may be too long to fit in either -headers or URLs if they contain extensive service catalogs or other additional -attributes. Some third-party applications such as web servers and clients may -need to be recompiled from source to customize the limitations that PKI and -PKIZ tokens would otherwise exceed). Both PKI and PKIZ tokens require signing -certificates which may be created using ``keystone-manage pki_setup`` for -demonstration purposes (this is not recommended for production deployments: use -certificates issued by an trusted CA instead). - Fernet tokens contain a limited amount of identity and authorization data in a `MessagePacked `_ payload. The payload is then wrapped as a `Fernet `_ message for transport, where @@ -481,7 +458,7 @@ established using ``keystone-manage fernet_setup`` and periodically rotated using ``keystone-manage fernet_rotate``. .. WARNING:: - UUID, PKI, PKIZ, and Fernet tokens are all bearer tokens, meaning that they + UUID and Fernet tokens are both bearer tokens, meaning that they must be protected from unnecessary disclosure to prevent unauthorized access. @@ -1338,7 +1315,7 @@ through the normal REST API. At the moment, the following calls are supported: * ``mapping_engine``: Test your federation mapping rules. * ``mapping_populate``: Prepare domain-specific LDAP backend * ``mapping_purge``: Purge the identity mapping table. -* ``pki_setup``: Initialize the certificates used to sign tokens. +* ``pki_setup``: Initialize the certificates used to sign revocation lists. * ``saml_idp_metadata``: Generate identity provider metadata. * ``token_flush``: Purge expired tokens diff --git a/doc/source/man/keystone-manage.rst b/doc/source/man/keystone-manage.rst index a7f6369c9b..c8d98cf1ca 100644 --- a/doc/source/man/keystone-manage.rst +++ b/doc/source/man/keystone-manage.rst @@ -53,7 +53,7 @@ Available commands: * ``mapping_populate``: Prepare domain-specific LDAP backend. * ``mapping_purge``: Purge the identity mapping table. * ``mapping_engine``: Test your federation mapping rules. -* ``pki_setup``: Initialize the certificates used to sign tokens. **deprecated** +* ``pki_setup``: Initialize the certificates used to sign revocation lists. **deprecated** * ``saml_idp_metadata``: Generate identity provider metadata. * ``token_flush``: Purge expired tokens. diff --git a/doc/source/token-support-matrix.ini b/doc/source/token-support-matrix.ini index 4236f362eb..78e83830fa 100644 --- a/doc/source/token-support-matrix.ini +++ b/doc/source/token-support-matrix.ini @@ -56,8 +56,6 @@ # drivers should maintain their own equivalent document, and merge it with this # when their code merges into core. driver-impl-uuid=UUID tokens -driver-impl-pki=PKI tokens -driver-impl-pkiz=PKIZ tokens driver-impl-fernet=Fernet tokens [operation.create_unscoped_token] @@ -68,8 +66,6 @@ notes=All token providers must be capable of issuing tokens without an explicit cli=openstack --os-username= --os-user-domain-name= --os-password= token issue driver-impl-uuid=complete -driver-impl-pki=complete -driver-impl-pkiz=complete driver-impl-fernet=complete [operation.create_project_scoped_token] @@ -80,8 +76,6 @@ cli=openstack --os-username= --os-user-domain-name= --os-password= --os-project-name= --os-project-domain-name= token issue driver-impl-uuid=complete -driver-impl-pki=complete -driver-impl-pkiz=complete driver-impl-fernet=complete [operation.create_domain_scoped_token] @@ -92,8 +86,6 @@ notes=Domain-scoped tokens are not required for all use cases, and for some use cli=openstack --os-username= --os-user-domain-name= --os-password= --os-domain-name= token issue driver-impl-uuid=complete -driver-impl-pki=complete -driver-impl-pkiz=complete driver-impl-fernet=complete [operation.create_trust_scoped_token] @@ -104,8 +96,6 @@ notes=Tokens scoped to a trust convey only the user impersonation and cli=openstack --os-username= --os-user-domain-name= --os-password= --os-trust-id= token issue driver-impl-uuid=complete -driver-impl-pki=complete -driver-impl-pkiz=complete driver-impl-fernet=complete [operation.create_token_using_oauth] @@ -114,8 +104,6 @@ status=optional notes=OAuth access tokens can be exchanged for keystone tokens. cli= driver-impl-uuid=complete -driver-impl-pki=complete -driver-impl-pkiz=complete driver-impl-fernet=complete [operation.create_token_with_bind] @@ -125,8 +113,6 @@ notes=Tokens can express a binding to an additional authentication method, such as kerberos or x509. cli= driver-impl-uuid=complete -driver-impl-pki=complete -driver-impl-pkiz=complete driver-impl-fernet=missing [operation.revoke_token] @@ -138,8 +124,6 @@ notes=Tokens may be individually revoked, such as when a user logs out of revoked token was previously used to create additional tokens). cli=openstack token revoke driver-impl-uuid=complete -driver-impl-pki=complete -driver-impl-pkiz=complete driver-impl-fernet=complete [feature.online_validation] @@ -149,8 +133,6 @@ notes=Keystone must be able to validate the tokens that it issues when presented with a token that it previously issued. cli= driver-impl-uuid=complete -driver-impl-pki=complete -driver-impl-pkiz=complete driver-impl-fernet=complete [feature.offline_validation] @@ -161,8 +143,6 @@ notes=Services using Keystone for authentication may want to validate tokens performance and scalability. cli= driver-impl-uuid=missing -driver-impl-pki=complete -driver-impl-pkiz=complete driver-impl-fernet=missing [feature.non_persistent] @@ -174,6 +154,4 @@ notes=If a token format does not require persistence (such as to a SQL operations such as `keystone-manage token_flush`. cli= driver-impl-uuid=missing -driver-impl-pki=partial -driver-impl-pkiz=partial driver-impl-fernet=complete diff --git a/examples/pki/cms/auth_token_revoked.json b/examples/pki/cms/auth_token_revoked.json deleted file mode 100644 index 57d35280e9..0000000000 --- a/examples/pki/cms/auth_token_revoked.json +++ /dev/null @@ -1,85 +0,0 @@ -{ - "access": { - "serviceCatalog": [ - { - "endpoints": [ - { - "adminURL": "http://127.0.0.1:8776/v1/64b6f3fbcc53435e8a60fcf89bb6617a", - "region": "RegionOne", - "internalURL": "http://127.0.0.1:8776/v1/64b6f3fbcc53435e8a60fcf89bb6617a", - "publicURL": "http://127.0.0.1:8776/v1/64b6f3fbcc53435e8a60fcf89bb6617a" - } - ], - "endpoints_links": [], - "type": "volume", - "name": "volume" - }, - { - "endpoints": [ - { - "adminURL": "http://127.0.0.1:9292/v1", - "region": "RegionOne", - "internalURL": "http://127.0.0.1:9292/v1", - "publicURL": "http://127.0.0.1:9292/v1" - } - ], - "endpoints_links": [], - "type": "image", - "name": "glance" - }, - { - "endpoints": [ - { - "adminURL": "http://127.0.0.1:8774/v1.1/64b6f3fbcc53435e8a60fcf89bb6617a", - "region": "RegionOne", - "internalURL": "http://127.0.0.1:8774/v1.1/64b6f3fbcc53435e8a60fcf89bb6617a", - "publicURL": "http://127.0.0.1:8774/v1.1/64b6f3fbcc53435e8a60fcf89bb6617a" - } - ], - "endpoints_links": [], - "type": "compute", - "name": "nova" - }, - { - "endpoints": [ - { - "adminURL": "http://127.0.0.1:35357/v2.0", - "region": "RegionOne", - "internalURL": "http://127.0.0.1:35357/v2.0", - "publicURL": "http://127.0.0.1:5000/v2.0" - } - ], - "endpoints_links": [], - "type": "identity", - "name": "keystone" - } - ], - "token": { - "expires": "2012-06-02T14:47:34Z", - "id": "placeholder", - "tenant": { - "enabled": true, - "description": null, - "name": "tenant_name1", - "id": "tenant_id1" - } - }, - "user": { - "username": "revoked_username1", - "roles_links": [ - "role1", - "role2" - ], - "id": "revoked_user_id1", - "roles": [ - { - "name": "role1" - }, - { - "name": "role2" - } - ], - "name": "revoked_username1" - } - } -} diff --git a/examples/pki/cms/auth_token_revoked.pem b/examples/pki/cms/auth_token_revoked.pem deleted file mode 100644 index 1435c1e9cc..0000000000 --- a/examples/pki/cms/auth_token_revoked.pem +++ /dev/null @@ -1,44 +0,0 @@ ------BEGIN CMS----- -MIIH1wYJKoZIhvcNAQcCoIIHyDCCB8QCAQExCTAHBgUrDgMCGjCCBeQGCSqGSIb3 -DQEHAaCCBdUEggXReyJhY2Nlc3MiOiB7InNlcnZpY2VDYXRhbG9nIjogW3siZW5k -cG9pbnRzIjogW3siYWRtaW5VUkwiOiAiaHR0cDovLzEyNy4wLjAuMTo4Nzc2L3Yx -LzY0YjZmM2ZiY2M1MzQzNWU4YTYwZmNmODliYjY2MTdhIiwgInJlZ2lvbiI6ICJy -ZWdpb25PbmUiLCAiaW50ZXJuYWxVUkwiOiAiaHR0cDovLzEyNy4wLjAuMTo4Nzc2 -L3YxLzY0YjZmM2ZiY2M1MzQzNWU4YTYwZmNmODliYjY2MTdhIiwgInB1YmxpY1VS -TCI6ICJodHRwOi8vMTI3LjAuMC4xOjg3NzYvdjEvNjRiNmYzZmJjYzUzNDM1ZThh -NjBmY2Y4OWJiNjYxN2EifV0sICJlbmRwb2ludHNfbGlua3MiOiBbXSwgInR5cGUi -OiAidm9sdW1lIiwgIm5hbWUiOiAidm9sdW1lIn0sIHsiZW5kcG9pbnRzIjogW3si -YWRtaW5VUkwiOiAiaHR0cDovLzEyNy4wLjAuMTo5MjkyL3YxIiwgInJlZ2lvbiI6 -ICJyZWdpb25PbmUiLCAiaW50ZXJuYWxVUkwiOiAiaHR0cDovLzEyNy4wLjAuMTo5 -MjkyL3YxIiwgInB1YmxpY1VSTCI6ICJodHRwOi8vMTI3LjAuMC4xOjkyOTIvdjEi -fV0sICJlbmRwb2ludHNfbGlua3MiOiBbXSwgInR5cGUiOiAiaW1hZ2UiLCAibmFt -ZSI6ICJnbGFuY2UifSwgeyJlbmRwb2ludHMiOiBbeyJhZG1pblVSTCI6ICJodHRw -Oi8vMTI3LjAuMC4xOjg3NzQvdjEuMS82NGI2ZjNmYmNjNTM0MzVlOGE2MGZjZjg5 -YmI2NjE3YSIsICJyZWdpb24iOiAicmVnaW9uT25lIiwgImludGVybmFsVVJMIjog -Imh0dHA6Ly8xMjcuMC4wLjE6ODc3NC92MS4xLzY0YjZmM2ZiY2M1MzQzNWU4YTYw -ZmNmODliYjY2MTdhIiwgInB1YmxpY1VSTCI6ICJodHRwOi8vMTI3LjAuMC4xOjg3 -NzQvdjEuMS82NGI2ZjNmYmNjNTM0MzVlOGE2MGZjZjg5YmI2NjE3YSJ9XSwgImVu -ZHBvaW50c19saW5rcyI6IFtdLCAidHlwZSI6ICJjb21wdXRlIiwgIm5hbWUiOiAi -bm92YSJ9LCB7ImVuZHBvaW50cyI6IFt7ImFkbWluVVJMIjogImh0dHA6Ly8xMjcu -MC4wLjE6MzUzNTcvdjIuMCIsICJyZWdpb24iOiAiUmVnaW9uT25lIiwgImludGVy -bmFsVVJMIjogImh0dHA6Ly8xMjcuMC4wLjE6MzUzNTcvdjIuMCIsICJwdWJsaWNV -UkwiOiAiaHR0cDovLzEyNy4wLjAuMTo1MDAwL3YyLjAifV0sICJlbmRwb2ludHNf -bGlua3MiOiBbXSwgInR5cGUiOiAiaWRlbnRpdHkiLCAibmFtZSI6ICJrZXlzdG9u -ZSJ9XSwidG9rZW4iOiB7ImV4cGlyZXMiOiAiMjAxMi0wNi0wMlQxNDo0NzozNFoi -LCAiaWQiOiAicGxhY2Vob2xkZXIiLCAidGVuYW50IjogeyJlbmFibGVkIjogdHJ1 -ZSwgImRlc2NyaXB0aW9uIjogbnVsbCwgIm5hbWUiOiAidGVuYW50X25hbWUxIiwg -ImlkIjogInRlbmFudF9pZDEifX0sICJ1c2VyIjogeyJ1c2VybmFtZSI6ICJyZXZv -a2VkX3VzZXJuYW1lMSIsICJyb2xlc19saW5rcyI6IFsicm9sZTEiLCJyb2xlMiJd -LCAiaWQiOiAicmV2b2tlZF91c2VyX2lkMSIsICJyb2xlcyI6IFt7Im5hbWUiOiAi -cm9sZTEifSwgeyJuYW1lIjogInJvbGUyIn1dLCAibmFtZSI6ICJyZXZva2VkX3Vz -ZXJuYW1lMSJ9fX0NCjGCAcowggHGAgEBMIGkMIGeMQowCAYDVQQFEwE1MQswCQYD -VQQGEwJVUzELMAkGA1UECBMCQ0ExEjAQBgNVBAcTCVN1bm55dmFsZTESMBAGA1UE -ChMJT3BlblN0YWNrMREwDwYDVQQLEwhLZXlzdG9uZTElMCMGCSqGSIb3DQEJARYW -a2V5c3RvbmVAb3BlbnN0YWNrLm9yZzEUMBIGA1UEAxMLU2VsZiBTaWduZWQCAREw -BwYFKw4DAhowDQYJKoZIhvcNAQEBBQAEggEAXY8JvllpyctcNlJByPLxhgLyRfFo -Ew+8Yq3O4FxOyfVkINvOz4EHTipY0M/K8OLwfxpRt7o/iGLGRDBTI6Dd+erXsus8 -NecnNxcWN9RUE2CZhoGj/0nhnNEGF+9Mlv3tMBngwoUJg2paSw/Vn2Q7RaqbOC05 -aZOSDoSX7Zf0DIS/T0ZPnmOUb9+N25M20ctMHksPMEq0qyf2oove0O+WMa/cA8JT -c2EAhew4WSD0Zv0GOAP30GS+hkNfA1GZTrvCQrpRs9jXhK4dR2bBsnUFVix1BEZ0 -sDhI8cXLvm16IpOO8ov6002ZoZhPn6Qo+0J8QOfdnjiwNnxLOEbuOIwPeQ== ------END CMS----- diff --git a/examples/pki/cms/auth_token_scoped.json b/examples/pki/cms/auth_token_scoped.json deleted file mode 100644 index 31b1044b1a..0000000000 --- a/examples/pki/cms/auth_token_scoped.json +++ /dev/null @@ -1,85 +0,0 @@ -{ - "access": { - "serviceCatalog": [ - { - "endpoints": [ - { - "adminURL": "http://127.0.0.1:8776/v1/64b6f3fbcc53435e8a60fcf89bb6617a", - "region": "RegionOne", - "internalURL": "http://127.0.0.1:8776/v1/64b6f3fbcc53435e8a60fcf89bb6617a", - "publicURL": "http://127.0.0.1:8776/v1/64b6f3fbcc53435e8a60fcf89bb6617a" - } - ], - "endpoints_links": [], - "type": "volume", - "name": "volume" - }, - { - "endpoints": [ - { - "adminURL": "http://127.0.0.1:9292/v1", - "region": "RegionOne", - "internalURL": "http://127.0.0.1:9292/v1", - "publicURL": "http://127.0.0.1:9292/v1" - } - ], - "endpoints_links": [], - "type": "image", - "name": "glance" - }, - { - "endpoints": [ - { - "adminURL": "http://127.0.0.1:8774/v1.1/64b6f3fbcc53435e8a60fcf89bb6617a", - "region": "RegionOne", - "internalURL": "http://127.0.0.1:8774/v1.1/64b6f3fbcc53435e8a60fcf89bb6617a", - "publicURL": "http://127.0.0.1:8774/v1.1/64b6f3fbcc53435e8a60fcf89bb6617a" - } - ], - "endpoints_links": [], - "type": "compute", - "name": "nova" - }, - { - "endpoints": [ - { - "adminURL": "http://127.0.0.1:35357/v2.0", - "region": "RegionOne", - "internalURL": "http://127.0.0.1:35357/v2.0", - "publicURL": "http://127.0.0.1:5000/v2.0" - } - ], - "endpoints_links": [], - "type": "identity", - "name": "keystone" - } - ], - "token": { - "expires": "2012-06-02T14:47:34Z", - "id": "placeholder", - "tenant": { - "enabled": true, - "description": null, - "name": "tenant_name1", - "id": "tenant_id1" - } - }, - "user": { - "username": "user_name1", - "roles_links": [ - "role1", - "role2" - ], - "id": "user_id1", - "roles": [ - { - "name": "role1" - }, - { - "name": "role2" - } - ], - "name": "user_name1" - } - } -} diff --git a/examples/pki/cms/auth_token_scoped.pem b/examples/pki/cms/auth_token_scoped.pem deleted file mode 100644 index 5c02c954ef..0000000000 --- a/examples/pki/cms/auth_token_scoped.pem +++ /dev/null @@ -1,44 +0,0 @@ ------BEGIN CMS----- -MIIHwQYJKoZIhvcNAQcCoIIHsjCCB64CAQExCTAHBgUrDgMCGjCCBc4GCSqGSIb3 -DQEHAaCCBb8EggW7eyJhY2Nlc3MiOiB7InNlcnZpY2VDYXRhbG9nIjogW3siZW5k -cG9pbnRzIjogW3siYWRtaW5VUkwiOiAiaHR0cDovLzEyNy4wLjAuMTo4Nzc2L3Yx -LzY0YjZmM2ZiY2M1MzQzNWU4YTYwZmNmODliYjY2MTdhIiwgInJlZ2lvbiI6ICJy -ZWdpb25PbmUiLCAiaW50ZXJuYWxVUkwiOiAiaHR0cDovLzEyNy4wLjAuMTo4Nzc2 -L3YxLzY0YjZmM2ZiY2M1MzQzNWU4YTYwZmNmODliYjY2MTdhIiwgInB1YmxpY1VS -TCI6ICJodHRwOi8vMTI3LjAuMC4xOjg3NzYvdjEvNjRiNmYzZmJjYzUzNDM1ZThh -NjBmY2Y4OWJiNjYxN2EifV0sICJlbmRwb2ludHNfbGlua3MiOiBbXSwgInR5cGUi -OiAidm9sdW1lIiwgIm5hbWUiOiAidm9sdW1lIn0sIHsiZW5kcG9pbnRzIjogW3si -YWRtaW5VUkwiOiAiaHR0cDovLzEyNy4wLjAuMTo5MjkyL3YxIiwgInJlZ2lvbiI6 -ICJyZWdpb25PbmUiLCAiaW50ZXJuYWxVUkwiOiAiaHR0cDovLzEyNy4wLjAuMTo5 -MjkyL3YxIiwgInB1YmxpY1VSTCI6ICJodHRwOi8vMTI3LjAuMC4xOjkyOTIvdjEi -fV0sICJlbmRwb2ludHNfbGlua3MiOiBbXSwgInR5cGUiOiAiaW1hZ2UiLCAibmFt -ZSI6ICJnbGFuY2UifSwgeyJlbmRwb2ludHMiOiBbeyJhZG1pblVSTCI6ICJodHRw -Oi8vMTI3LjAuMC4xOjg3NzQvdjEuMS82NGI2ZjNmYmNjNTM0MzVlOGE2MGZjZjg5 -YmI2NjE3YSIsICJyZWdpb24iOiAicmVnaW9uT25lIiwgImludGVybmFsVVJMIjog -Imh0dHA6Ly8xMjcuMC4wLjE6ODc3NC92MS4xLzY0YjZmM2ZiY2M1MzQzNWU4YTYw -ZmNmODliYjY2MTdhIiwgInB1YmxpY1VSTCI6ICJodHRwOi8vMTI3LjAuMC4xOjg3 -NzQvdjEuMS82NGI2ZjNmYmNjNTM0MzVlOGE2MGZjZjg5YmI2NjE3YSJ9XSwgImVu -ZHBvaW50c19saW5rcyI6IFtdLCAidHlwZSI6ICJjb21wdXRlIiwgIm5hbWUiOiAi -bm92YSJ9LCB7ImVuZHBvaW50cyI6IFt7ImFkbWluVVJMIjogImh0dHA6Ly8xMjcu -MC4wLjE6MzUzNTcvdjIuMCIsICJyZWdpb24iOiAiUmVnaW9uT25lIiwgImludGVy -bmFsVVJMIjogImh0dHA6Ly8xMjcuMC4wLjE6MzUzNTcvdjIuMCIsICJwdWJsaWNV -UkwiOiAiaHR0cDovLzEyNy4wLjAuMTo1MDAwL3YyLjAifV0sICJlbmRwb2ludHNf -bGlua3MiOiBbXSwgInR5cGUiOiAiaWRlbnRpdHkiLCAibmFtZSI6ICJrZXlzdG9u -ZSJ9XSwidG9rZW4iOiB7ImV4cGlyZXMiOiAiMjAxMi0wNi0wMlQxNDo0NzozNFoi -LCAiaWQiOiAicGxhY2Vob2xkZXIiLCAidGVuYW50IjogeyJlbmFibGVkIjogdHJ1 -ZSwgImRlc2NyaXB0aW9uIjogbnVsbCwgIm5hbWUiOiAidGVuYW50X25hbWUxIiwg -ImlkIjogInRlbmFudF9pZDEifX0sICJ1c2VyIjogeyJ1c2VybmFtZSI6ICJ1c2Vy -X25hbWUxIiwgInJvbGVzX2xpbmtzIjogWyJyb2xlMSIsInJvbGUyIl0sICJpZCI6 -ICJ1c2VyX2lkMSIsICJyb2xlcyI6IFt7Im5hbWUiOiAicm9sZTEifSwgeyJuYW1l -IjogInJvbGUyIn1dLCAibmFtZSI6ICJ1c2VyX25hbWUxIn19fQ0KMYIByjCCAcYC -AQEwgaQwgZ4xCjAIBgNVBAUTATUxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDQTES -MBAGA1UEBxMJU3Vubnl2YWxlMRIwEAYDVQQKEwlPcGVuU3RhY2sxETAPBgNVBAsT -CEtleXN0b25lMSUwIwYJKoZIhvcNAQkBFhZrZXlzdG9uZUBvcGVuc3RhY2sub3Jn -MRQwEgYDVQQDEwtTZWxmIFNpZ25lZAIBETAHBgUrDgMCGjANBgkqhkiG9w0BAQEF -AASCAQCAtuVtqTU9h1uaRrYU1eusSnHwD6jizp/xltTrYTyFPfYjhJdglS+bjSeS -Iau9pN3Tfug98ozUTJ5ByNepAQtxBxPz5bDXhBmAbU6ywaolqRAG+b/s2ShNGQ2a -tn80NeZmDNbtoqdHVAkD3EZXjsEKr2w+3JTTF2indzczyGe5EeSfNUaT+ZhNEmPR -Urob62t8atW+zehCSurpaa8pC5m1NcbK8Uu6Y+qO2m08KU9w5kmbOQtWAGCmtpIx -F2yM1AbSgd90yzen7dv5mNkgZyzQ6SYgRUvkKOKnCyBb97EZK3ZR4qUxQzRYM++8 -g8HdaIfoYVPoPHqODet8Xmhw/Wtp ------END CMS----- diff --git a/examples/pki/cms/auth_token_unscoped.json b/examples/pki/cms/auth_token_unscoped.json deleted file mode 100644 index 5c6d1f850d..0000000000 --- a/examples/pki/cms/auth_token_unscoped.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "access": { - "token": { - "expires": "2012-08-17T15:35:34Z", - "id": "01e032c996ef4406b144335915a41e79" - }, - "serviceCatalog": {}, - "user": { - "username": "user_name1", - "roles_links": [], - "id": "c9c89e3be3ee453fbf00c7966f6d3fbd", - "roles": [ - { - "name": "role1" - }, - { - "name": "role2" - } - ], - "name": "user_name1" - } - } -} diff --git a/examples/pki/cms/auth_token_unscoped.pem b/examples/pki/cms/auth_token_unscoped.pem deleted file mode 100644 index 60649090df..0000000000 --- a/examples/pki/cms/auth_token_unscoped.pem +++ /dev/null @@ -1,19 +0,0 @@ ------BEGIN CMS----- -MIIDKAYJKoZIhvcNAQcCoIIDGTCCAxUCAQExCTAHBgUrDgMCGjCCATUGCSqGSIb3 -DQEHAaCCASYEggEieyJhY2Nlc3MiOiB7InRva2VuIjogeyJleHBpcmVzIjogIjIw -MTItMDgtMTdUMTU6MzU6MzRaIiwgImlkIjogIjAxZTAzMmM5OTZlZjQ0MDZiMTQ0 -MzM1OTE1YTQxZTc5In0sICJzZXJ2aWNlQ2F0YWxvZyI6IHt9LCAidXNlciI6IHsi -dXNlcm5hbWUiOiAidXNlcl9uYW1lMSIsICJyb2xlc19saW5rcyI6IFtdLCAiaWQi -OiAiYzljODllM2JlM2VlNDUzZmJmMDBjNzk2NmY2ZDNmYmQiLCAicm9sZXMiOiBb -eyduYW1lJzogJ3JvbGUxJ30seyduYW1lJzogJ3JvbGUyJ30sXSwgIm5hbWUiOiAi -dXNlcl9uYW1lMSJ9fX0xggHKMIIBxgIBATCBpDCBnjEKMAgGA1UEBRMBNTELMAkG -A1UEBhMCVVMxCzAJBgNVBAgTAkNBMRIwEAYDVQQHEwlTdW5ueXZhbGUxEjAQBgNV -BAoTCU9wZW5TdGFjazERMA8GA1UECxMIS2V5c3RvbmUxJTAjBgkqhkiG9w0BCQEW -FmtleXN0b25lQG9wZW5zdGFjay5vcmcxFDASBgNVBAMTC1NlbGYgU2lnbmVkAgER -MAcGBSsOAwIaMA0GCSqGSIb3DQEBAQUABIIBAFyD9IH2bXsafCTyHEWS28zBuq03 -ZNWXV4+0BfdMbX1ONkaQ7mLGRmfabLHwfE5RaSASFh/Doq7KTc8XrBVfTm9HQPGr -TLZUawdYlyBFVq0PEE1cPvO9Blz4X/2Awcp/Q67YRd/oLCY2dFWMClMroXu1fy3P -oFlpWPPhURrbU1GjhUgPIz0IxNGjfWEHVsb5kz7Bo4E8J3pgIkccm97XZZtiCwf7 -DVNj+Eb5mRegGG6IgSSRpZULgnCmSofQ3RnW3jSCkDxLXDQm9IsaaLJsuUFLylGs -mB/98w9mP192IGl5MVr8/tANXwb5ok2VatUp/Ww1U0IlWbhN374PbK76vcE= ------END CMS----- diff --git a/examples/pki/cms/revocation_list.json b/examples/pki/cms/revocation_list.json deleted file mode 100644 index 9ad97287ec..0000000000 --- a/examples/pki/cms/revocation_list.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "revoked": [ - { - "id": "7acfcfdaf6a14aebe97c61c5947bc4d3", - "expires": "2012-08-14T17:58:48Z" - } - ] -} diff --git a/examples/pki/cms/revocation_list.pem b/examples/pki/cms/revocation_list.pem deleted file mode 100644 index bd22d3f2de..0000000000 --- a/examples/pki/cms/revocation_list.pem +++ /dev/null @@ -1,15 +0,0 @@ ------BEGIN CMS----- -MIICWgYJKoZIhvcNAQcCoIICSzCCAkcCAQExCTAHBgUrDgMCGjBpBgkqhkiG9w0B -BwGgXARaeyJyZXZva2VkIjpbeyJpZCI6IjdhY2ZjZmRhZjZhMTRhZWJlOTdjNjFj -NTk0N2JjNGQzIiwiZXhwaXJlcyI6IjIwMTItMDgtMTRUMTc6NTg6NDhaIn1dfQ0K -MYIByjCCAcYCAQEwgaQwgZ4xCjAIBgNVBAUTATUxCzAJBgNVBAYTAlVTMQswCQYD -VQQIEwJDQTESMBAGA1UEBxMJU3Vubnl2YWxlMRIwEAYDVQQKEwlPcGVuU3RhY2sx -ETAPBgNVBAsTCEtleXN0b25lMSUwIwYJKoZIhvcNAQkBFhZrZXlzdG9uZUBvcGVu -c3RhY2sub3JnMRQwEgYDVQQDEwtTZWxmIFNpZ25lZAIBETAHBgUrDgMCGjANBgkq -hkiG9w0BAQEFAASCAQC2f05VHM7zjNT3TBO80AmZ00n7AEWUjbFe5nqIM8kWGM83 -01Bi3uU/nQ0daAd3tqCmDL2EfETAjD+xnIzjlN6eIA74Vy51wFD/KiyWYPWzw8mH -WcATHmE4E8kLdt8NhUodCY9TCFxcHJNDR1Eai/U7hH+5O4p9HcmMjv/GWegZL6HB -Up9Cxu6haxvPFmYylzM6Qt0Ad/WiO/JZLPTA4qXJEJSa9EMFMb0c2wSDSn30swJe -7J79VTFktTr2djv8KFvaHr4vLFYv2Y3ZkTeHqam0m91vllxLZJUP5QTSHjjY6LFE -5eEjIlOv9wOOm1uTtPIq6pxCugU1Wm7gstkqr55R ------END CMS----- diff --git a/examples/pki/gen_pki.sh b/examples/pki/gen_pki.sh deleted file mode 100755 index da800413ed..0000000000 --- a/examples/pki/gen_pki.sh +++ /dev/null @@ -1,233 +0,0 @@ -#!/bin/bash - -# Copyright 2012 OpenStack Foundation -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -# This script generates the crypto necessary for the SSL tests. - -DIR=`dirname "$0"` -CURRENT_DIR=`cd "$DIR" && pwd` -CERTS_DIR=$CURRENT_DIR/certs -PRIVATE_DIR=$CURRENT_DIR/private -CMS_DIR=$CURRENT_DIR/cms - - -function rm_old { - rm -rf $CERTS_DIR/*.pem - rm -rf $PRIVATE_DIR/*.pem -} - -function cleanup { - rm -rf *.conf > /dev/null 2>&1 - rm -rf index* > /dev/null 2>&1 - rm -rf *.crt > /dev/null 2>&1 - rm -rf newcerts > /dev/null 2>&1 - rm -rf *.pem > /dev/null 2>&1 - rm -rf serial* > /dev/null 2>&1 -} - -function generate_ca_conf { - echo ' -[ req ] -default_bits = 2048 -default_keyfile = cakey.pem -default_md = default - -prompt = no -distinguished_name = ca_distinguished_name - -x509_extensions = ca_extensions - -[ ca_distinguished_name ] -serialNumber = 5 -countryName = US -stateOrProvinceName = CA -localityName = Sunnyvale -organizationName = OpenStack -organizationalUnitName = Keystone -emailAddress = keystone@openstack.org -commonName = Self Signed - -[ ca_extensions ] -basicConstraints = critical,CA:true -' > ca.conf -} - -function generate_ssl_req_conf { - echo ' -[ req ] -default_bits = 2048 -default_keyfile = keystonekey.pem -default_md = default - -prompt = no -distinguished_name = distinguished_name - -[ distinguished_name ] -countryName = US -stateOrProvinceName = CA -localityName = Sunnyvale -organizationName = OpenStack -organizationalUnitName = Keystone -commonName = localhost -emailAddress = keystone@openstack.org -' > ssl_req.conf -} - -function generate_cms_signing_req_conf { - echo ' -[ req ] -default_bits = 2048 -default_keyfile = keystonekey.pem -default_md = default - -prompt = no -distinguished_name = distinguished_name - -[ distinguished_name ] -countryName = US -stateOrProvinceName = CA -localityName = Sunnyvale -organizationName = OpenStack -organizationalUnitName = Keystone -commonName = Keystone -emailAddress = keystone@openstack.org -' > cms_signing_req.conf -} - -function generate_signing_conf { - echo ' -[ ca ] -default_ca = signing_ca - -[ signing_ca ] -dir = . -database = $dir/index.txt -new_certs_dir = $dir/newcerts - -certificate = $dir/certs/cacert.pem -serial = $dir/serial -private_key = $dir/private/cakey.pem - -default_days = 21360 -default_crl_days = 30 -default_md = default - -policy = policy_any - -[ policy_any ] -countryName = supplied -stateOrProvinceName = supplied -localityName = optional -organizationName = supplied -organizationalUnitName = supplied -emailAddress = supplied -commonName = supplied -' > signing.conf -} - -function setup { - touch index.txt - echo '10' > serial - generate_ca_conf - mkdir newcerts -} - -function check_error { - if [ $1 != 0 ] ; then - echo "Failed! rc=${1}" - echo 'Bailing ...' - cleanup - exit $1 - else - echo 'Done' - fi -} - -function generate_ca { - echo 'Generating New CA Certificate ...' - openssl req -x509 -newkey rsa:2048 -days 21360 -out $CERTS_DIR/cacert.pem \ - -keyout $PRIVATE_DIR/cakey.pem -outform PEM -config ca.conf -nodes - check_error $? -} - -function ssl_cert_req { - echo 'Generating SSL Certificate Request ...' - generate_ssl_req_conf - openssl req -newkey rsa:2048 -keyout $PRIVATE_DIR/ssl_key.pem \ - -keyform PEM -out ssl_req.pem -outform PEM -config ssl_req.conf -nodes - check_error $? - #openssl req -in req.pem -text -noout -} - -function cms_signing_cert_req { - echo 'Generating CMS Signing Certificate Request ...' - generate_cms_signing_req_conf - openssl req -newkey rsa:2048 -keyout $PRIVATE_DIR/signing_key.pem \ - -keyform PEM -out cms_signing_req.pem -outform PEM \ - -config cms_signing_req.conf -nodes - check_error $? - #openssl req -in req.pem -text -noout -} - -function issue_certs { - generate_signing_conf - echo 'Issuing SSL Certificate ...' - openssl ca -in ssl_req.pem -config signing.conf -batch - check_error $? - openssl x509 -in $CURRENT_DIR/newcerts/10.pem -out $CERTS_DIR/ssl_cert.pem - check_error $? - echo 'Issuing CMS Signing Certificate ...' - openssl ca -in cms_signing_req.pem -config signing.conf -batch - check_error $? - openssl x509 -in $CURRENT_DIR/newcerts/11.pem \ - -out $CERTS_DIR/signing_cert.pem - check_error $? -} - -function create_middleware_cert { - cp $CERTS_DIR/ssl_cert.pem $CERTS_DIR/middleware.pem - cat $PRIVATE_DIR/ssl_key.pem >> $CERTS_DIR/middleware.pem -} - -function check_openssl { - echo 'Checking openssl availability ...' - which openssl - check_error $? -} - -function gen_sample_cms { - FILES="${CMS_DIR}/auth_token_revoked.json" - FILES+=" ${CMS_DIR}/auth_token_unscoped.json" - FILES+=" ${CMS_DIR}/auth_token_scoped.json" - FILES+=" ${CMS_DIR}/revocation_list.json" - for json_file in $FILES; do - openssl cms -sign -in $json_file -nosmimecap \ - -signer $CERTS_DIR/signing_cert.pem \ - -inkey $PRIVATE_DIR/signing_key.pem -outform PEM -nodetach \ - -nocerts -noattr -out ${json_file/.json/.pem} - done -} - -check_openssl -rm_old -cleanup -setup -generate_ca -ssl_cert_req -cms_signing_cert_req -issue_certs -create_middleware_cert -gen_sample_cms -cleanup diff --git a/keystone/cmd/cli.py b/keystone/cmd/cli.py index 55ff16bb96..26a7d0b639 100644 --- a/keystone/cmd/cli.py +++ b/keystone/cmd/cli.py @@ -518,7 +518,7 @@ class BaseCertificateSetup(BasePermissionsSetup): class PKISetup(BaseCertificateSetup): - """Set up Key pairs and certificates for token signing and verification. + """Setup keys and certificates for signing and verifying revocation lists. This is NOT intended for production use, see Keystone Configuration documentation for details. As of the Mitaka release, this command has diff --git a/keystone/cmd/doctor/tokens.py b/keystone/cmd/doctor/tokens.py index bb4b07feb9..185e92eb67 100644 --- a/keystone/cmd/doctor/tokens.py +++ b/keystone/cmd/doctor/tokens.py @@ -28,10 +28,6 @@ def symptom_unreasonable_max_token_size(): - For UUID, set `keystone.conf [DEFAULT] max_token_size = 32`, because UUID tokens are always exactly 32 characters. - - For PKI and PKIZ, set `keystone.conf [DEFAULT] max_token_size = 8192`, - because PKI and PKIZ tokens can be quite large, but any larger than 8192 - and they tend to break certain implementations of HTTP. - - For Fernet, set `keystone.conf [DEFAULT] max_token_size = 255`, because Fernet tokens should never exceed this length in most deployments. However, if you are also using `keystone.conf [identity] driver = ldap`, @@ -41,6 +37,4 @@ def symptom_unreasonable_max_token_size(): """ return ( 'uuid' in CONF.token.provider and CONF.max_token_size != 32 - or 'pki' in CONF.token.provider and CONF.max_token_size < 8192 - or 'pkiz' in CONF.token.provider and CONF.max_token_size < 8192 or 'fernet' in CONF.token.provider and CONF.max_token_size > 255) diff --git a/keystone/common/utils.py b/keystone/common/utils.py index 16f44e19ce..c5a3a22047 100644 --- a/keystone/common/utils.py +++ b/keystone/common/utils.py @@ -95,13 +95,6 @@ class SmarterEncoder(jsonutils.json.JSONEncoder): return super(SmarterEncoder, self).default(obj) -class PKIEncoder(SmarterEncoder): - """Special encoder to make token JSON a bit shorter.""" - - item_separator = ',' - key_separator = ':' - - def verify_length_and_trunc_password(password): """Verify and truncate the provided password to the max_password_length.""" max_length = CONF.identity.max_password_length diff --git a/keystone/conf/constants.py b/keystone/conf/constants.py index 9fb56d0f5b..4a724be251 100644 --- a/keystone/conf/constants.py +++ b/keystone/conf/constants.py @@ -16,15 +16,8 @@ package. """ -from keystone.conf import utils - _DEFAULT_AUTH_METHODS = ['external', 'password', 'token', 'oauth1'] _CERTFILE = '/etc/keystone/ssl/certs/signing_cert.pem' _KEYFILE = '/etc/keystone/ssl/private/signing_key.pem' - -_DEPRECATE_PKI_MSG = utils.fmt(""" -PKI token support has been deprecated in the M release and will be removed in -the O release. Fernet or UUID tokens are recommended. -""") diff --git a/keystone/conf/default.py b/keystone/conf/default.py index db59674e57..68e569d06a 100644 --- a/keystone/conf/default.py +++ b/keystone/conf/default.py @@ -82,16 +82,16 @@ max_param_size = cfg.IntOpt( Limit the sizes of user & project ID/names. """)) -# we allow tokens to be a bit larger to accommodate PKI +# NOTE(breton): 255 is the size of the database columns used for ID fields. +# This size is picked so that the tokens can be indexed in-place as opposed to +# being entries in a string table. Thus, this is a performance decision. max_token_size = cfg.IntOpt( 'max_token_size', - default=8192, + default=255, help=utils.fmt(""" Similar to `[DEFAULT] max_param_size`, but provides an exception for token -values. With PKI / PKIZ tokens, this needs to be set close to 8192 (any higher, -and other HTTP implementations may break), depending on the size of your -service catalog and other factors. With Fernet tokens, this can be set as low -as 255. With UUID tokens, this should be set to 32). +values. With Fernet tokens, this can be set as low as 255. With UUID tokens, +this should be set to 32). """)) member_role_id = cfg.StrOpt( diff --git a/keystone/conf/token.py b/keystone/conf/token.py index f4ac9c58eb..b0c25c0dd7 100644 --- a/keystone/conf/token.py +++ b/keystone/conf/token.py @@ -10,13 +10,10 @@ # License for the specific language governing permissions and limitations # under the License. -import hashlib import sys from oslo_config import cfg -from oslo_log import versionutils -from keystone.conf import constants from keystone.conf import utils @@ -66,14 +63,12 @@ provider = cfg.StrOpt( help=utils.fmt(""" Entry point for the token provider in the `keystone.token.provider` namespace. The token provider controls the token construction, validation, and revocation -operations. Keystone includes `fernet`, `pkiz`, `pki`, and `uuid` token +operations. Keystone includes `fernet` and `uuid` token providers. `uuid` tokens must be persisted (using the backend specified in the `[token] driver` option), but do not require any extra configuration or setup. `fernet` tokens do not need to be persisted at all, but require that you run `keystone-manage fernet_setup` (also see the `keystone-manage fernet_rotate` -command). `pki` and `pkiz` tokens can be validated offline, without making HTTP -calls to keystone, but require that certificates be installed and distributed -to facilitate signing tokens and later validating those signatures. +command). """)) driver = cfg.StrOpt( @@ -128,26 +123,6 @@ for tokens with a more specific scope) or to provide their credentials in every request for a scoped token to avoid re-scoping altogether. """)) -# This attribute only exists in Python 2.7.8+ or 3.2+ -hash_choices = getattr(hashlib, 'algorithms_guaranteed', None) -hash_choices = sorted(hash_choices) if hash_choices else None -hash_algorithm = cfg.StrOpt( - 'hash_algorithm', - default='md5', - choices=hash_choices, - deprecated_for_removal=True, - deprecated_reason=constants._DEPRECATE_PKI_MSG, - deprecated_since=versionutils.deprecated.MITAKA, - help=utils.fmt(""" -This controls the hash algorithm to use to uniquely identify PKI tokens without -having to transmit the entire token to keystone (which may be several -kilobytes). This can be set to any algorithm that hashlib supports. WARNING: -Before changing this value, the `auth_token` middleware protecting all other -services must be configured with the set of hash algorithms to expect from -keystone (both your old and new value for this option), otherwise token -revocation will not be processed correctly. -""")) - infer_roles = cfg.BoolOpt( 'infer_roles', default=True, @@ -176,7 +151,6 @@ ALL_OPTS = [ cache_time, revoke_by_id, allow_rescope_scoped_token, - hash_algorithm, infer_roles, cache_on_issue, ] diff --git a/keystone/exception.py b/keystone/exception.py index d941f23eea..39bf5d0fa5 100644 --- a/keystone/exception.py +++ b/keystone/exception.py @@ -176,12 +176,6 @@ class RegionDeletionError(ForbiddenNotSecurity): "its child regions have associated endpoints.") -class PKITokenExpected(ForbiddenNotSecurity): - message_format = _('The certificates you requested are not available. ' - 'It is likely that this server does not use PKI tokens ' - 'otherwise this is the result of misconfiguration.') - - class SecurityError(Error): """Security error exception. diff --git a/keystone/models/token_model.py b/keystone/models/token_model.py index 620e73fe69..724ea4b0c0 100644 --- a/keystone/models/token_model.py +++ b/keystone/models/token_model.py @@ -12,7 +12,6 @@ """Unified in-memory token model.""" -from keystoneclient.common import cms from oslo_utils import reflection from oslo_utils import timeutils import six @@ -51,8 +50,7 @@ class KeystoneToken(dict): super(KeystoneToken, self).__init__(**token_data['token']) except KeyError: raise exception.UnsupportedTokenVersionException() - self.short_id = cms.cms_hash_token(token_id, - mode=CONF.token.hash_algorithm) + self.token_id = token_id if self.project_scoped and self.domain_scoped: raise exception.UnexpectedError(_('Found invalid token: scoped to ' diff --git a/keystone/tests/unit/common/test_utils.py b/keystone/tests/unit/common/test_utils.py index b65c22644c..2a260000bb 100644 --- a/keystone/tests/unit/common/test_utils.py +++ b/keystone/tests/unit/common/test_utils.py @@ -18,7 +18,6 @@ import uuid import freezegun from oslo_config import fixture as config_fixture from oslo_log import log -from oslo_serialization import jsonutils import six from keystone.common import fernet_utils @@ -196,12 +195,6 @@ class UtilsTestCase(unit.BaseTestCase): TZ = 'UTC' + d _test_unixtime() - def test_pki_encoder(self): - data = {'field': 'value'} - json = jsonutils.dumps(data, cls=common_utils.PKIEncoder) - expected_json = '{"field":"value"}' - self.assertEqual(expected_json, json) - def test_url_safe_check(self): base_str = 'i am safe' self.assertFalse(common_utils.is_not_url_safe(base_str)) diff --git a/keystone/tests/unit/test_auth.py b/keystone/tests/unit/test_auth.py index 16173f440e..3f3fb8c127 100644 --- a/keystone/tests/unit/test_auth.py +++ b/keystone/tests/unit/test_auth.py @@ -664,18 +664,6 @@ class FernetAuthWithToken(AuthWithToken, AuthTest): self.skip_test_overrides('Fernet with v2.0 and revocation is broken') -class PKIAuthWithToken(AuthWithToken, AuthTest): - def config_overrides(self): - super(PKIAuthWithToken, self).config_overrides() - self.config_fixture.config(group='token', provider='pki') - - -class PKIZAuthWithToken(AuthWithToken, AuthTest): - def config_overrides(self): - super(PKIZAuthWithToken, self).config_overrides() - self.config_fixture.config(group='token', provider='pkiz') - - class AuthWithPasswordCredentials(AuthTest): def test_auth_invalid_user(self): """Verify exception is raised if invalid user.""" @@ -880,20 +868,6 @@ class UUIDAuthWithRemoteUser(AuthWithRemoteUser, AuthTest): self.config_fixture.config(group='token', provider='uuid') -class PKIAuthWithRemoteUser(AuthWithRemoteUser, AuthTest): - - def config_overrides(self): - super(PKIAuthWithRemoteUser, self).config_overrides() - self.config_fixture.config(group='token', provider='pki') - - -class PKIZAuthWithRemoteUser(AuthWithRemoteUser, AuthTest): - - def config_overrides(self): - super(PKIZAuthWithRemoteUser, self).config_overrides() - self.config_fixture.config(group='token', provider='pkiz') - - class AuthWithTrust(object): def setUp(self): super(AuthWithTrust, self).setUp() diff --git a/keystone/tests/unit/test_backend_sql.py b/keystone/tests/unit/test_backend_sql.py index d7bbda20d9..c6b73c72f8 100644 --- a/keystone/tests/unit/test_backend_sql.py +++ b/keystone/tests/unit/test_backend_sql.py @@ -854,33 +854,6 @@ class SqlTokenCacheInvalidationWithUUID(SqlTests, self.config_fixture.config(group='token', provider='uuid') -class SqlTokenCacheInvalidationWithPKI(SqlTests, - token_tests.TokenCacheInvalidation): - def setUp(self): - super(SqlTokenCacheInvalidationWithPKI, self).setUp() - self._create_test_data() - - def config_overrides(self): - super(SqlTokenCacheInvalidationWithPKI, self).config_overrides() - # NOTE(lbragstad): The TokenCacheInvalidation tests are coded to work - # against a persistent token backend. Only run these with token - # providers that issue persistent tokens. - self.config_fixture.config(group='token', provider='pki') - - -class SqlTokenCacheInvalidationWithPKIZ(SqlTests, - token_tests.TokenCacheInvalidation): - def setUp(self): - super(SqlTokenCacheInvalidationWithPKIZ, self).setUp() - self._create_test_data() - - def config_overrides(self): - super(SqlTokenCacheInvalidationWithPKIZ, self).config_overrides() - # NOTE(lbragstad): The TokenCacheInvalidation tests are coded to work - # against a persistent token backend. Only run these with token - # providers that issue persistent tokens. - self.config_fixture.config(group='token', provider='pkiz') - # NOTE(lbragstad): The Fernet token provider doesn't persist tokens in a # backend, so running the TokenCacheInvalidation tests here doesn't make sense. diff --git a/keystone/tests/unit/test_cert_setup.py b/keystone/tests/unit/test_cert_setup.py index 895bc060d2..255a721a94 100644 --- a/keystone/tests/unit/test_cert_setup.py +++ b/keystone/tests/unit/test_cert_setup.py @@ -22,10 +22,9 @@ from six.moves import http_client from testtools import matchers from keystone.common import openssl -from keystone import exception from keystone.tests import unit +from keystone.tests.unit import ksfixtures from keystone.tests.unit import rest -from keystone import token SSLDIR = unit.dirs.tmp('ssl') @@ -60,23 +59,14 @@ class CertSetupTestCase(rest.RestfulTestCase): ca_certs=ca_certs, ca_key=ca_key, keyfile=os.path.join(KEYDIR, 'signing_key.pem')) - self.config_fixture.config(group='token', provider='pkiz') - - def test_can_handle_missing_certs(self): - controller = token.controllers.Auth() - - self.config_fixture.config(group='signing', certfile='invalid') - user = unit.create_user(self.identity_api, - domain_id=CONF.identity.default_domain_id) - body_dict = { - 'passwordCredentials': { - 'userId': user['id'], - 'password': user['password'], - }, - } - self.assertRaises(exception.UnexpectedError, - controller.authenticate, - self.make_request(), body_dict) + self.config_fixture.config(group='token', provider='fernet') + self.useFixture( + ksfixtures.KeyRepository( + self.config_fixture, + 'fernet_tokens', + CONF.fernet_tokens.max_active_keys + ) + ) def test_create_pki_certs(self, rebuild=False): pki = openssl.ConfigurePKI(None, None, rebuild=rebuild) diff --git a/keystone/tests/unit/test_revoke.py b/keystone/tests/unit/test_revoke.py index c1db2ac3dd..19426e5165 100644 --- a/keystone/tests/unit/test_revoke.py +++ b/keystone/tests/unit/test_revoke.py @@ -23,7 +23,6 @@ from keystone import exception from keystone.models import revoke_model from keystone.revoke.backends import sql from keystone.tests import unit -from keystone.tests.unit import test_backend_sql from keystone.token.providers import common @@ -367,15 +366,6 @@ class RevokeTests(object): token_values) -class SqlRevokeTests(test_backend_sql.SqlTests, RevokeTests): - def config_overrides(self): - super(SqlRevokeTests, self).config_overrides() - self.config_fixture.config( - group='token', - provider='pki', - revoke_by_id=False) - - def add_event(events, event): events.append(event) return event diff --git a/keystone/tests/unit/test_token_provider.py b/keystone/tests/unit/test_token_provider.py index d81ffc7fbe..e3578b3100 100644 --- a/keystone/tests/unit/test_token_provider.py +++ b/keystone/tests/unit/test_token_provider.py @@ -15,7 +15,6 @@ import datetime from oslo_utils import timeutils -from six.moves import reload_module from keystone.common import dependency from keystone.common import utils @@ -26,8 +25,6 @@ from keystone.tests.unit import ksfixtures from keystone.tests.unit.ksfixtures import database from keystone import token from keystone.token.providers import fernet -from keystone.token.providers import pki -from keystone.token.providers import pkiz from keystone.token.providers import uuid @@ -759,14 +756,6 @@ class TestTokenProvider(unit.TestCase): self.config_fixture.config(group='token', provider='uuid') self.assertIsInstance(token.provider.Manager().driver, uuid.Provider) - dependency.reset() - self.config_fixture.config(group='token', provider='pki') - self.assertIsInstance(token.provider.Manager().driver, pki.Provider) - - dependency.reset() - self.config_fixture.config(group='token', provider='pkiz') - self.assertIsInstance(token.provider.Manager().driver, pkiz.Provider) - dependency.reset() self.config_fixture.config(group='token', provider='fernet') self.assertIsInstance(token.provider.Manager().driver, fernet.Provider) @@ -797,42 +786,3 @@ class TestTokenProvider(unit.TestCase): exception.TokenNotFound, self.token_provider_api.validate_token, None) - - -# NOTE(ayoung): renamed to avoid automatic test detection -class PKIProviderTests(object): - - def setUp(self): - super(PKIProviderTests, self).setUp() - - from keystoneclient.common import cms - self.cms = cms - - old_cms_subprocess = cms.subprocess - self.addCleanup(setattr, cms, 'subprocess', old_cms_subprocess) - - self.cms.subprocess = self.target_subprocess - - # force module reload so the imports get re-evaluated - reload_module(pki) - - def test_get_token_id_error_handling(self): - # cause command-line failure - self.config_fixture.config(group='signing', - keyfile='--please-break-me') - - provider = pki.Provider() - token_data = {} - self.assertRaises(exception.UnexpectedError, - provider._get_token_id, - token_data) - - -class TestPKIProviderWithStdlib(PKIProviderTests, unit.TestCase): - - def setUp(self): - # force keystoneclient.common.cms to use the stdlib subprocess - import subprocess - self.target_subprocess = subprocess - - super(TestPKIProviderWithStdlib, self).setUp() diff --git a/keystone/tests/unit/test_v2.py b/keystone/tests/unit/test_v2.py index 8fe996b798..e6676a1e51 100644 --- a/keystone/tests/unit/test_v2.py +++ b/keystone/tests/unit/test_v2.py @@ -12,14 +12,10 @@ # License for the specific language governing permissions and limitations # under the License. -import time import uuid -from keystoneclient.common import cms -from oslo_serialization import jsonutils import six from six.moves import http_client -from testtools import matchers from keystone.common import extension as keystone_extension import keystone.conf @@ -1226,68 +1222,6 @@ class V2TestCase(object): def assertValidRevocationListResponse(self, response): self.assertIsNotNone(response.result['signed']) - def _fetch_parse_revocation_list(self): - - token1 = self.get_scoped_token() - - # TODO(morganfainberg): Because this is making a restful call to the - # app a change to UTCNOW via mock.patch will not affect the returned - # token. The only surefire way to ensure there is not a transient bug - # based upon when the second token is issued is with a sleep. This - # issue all stems from the limited resolution (no microseconds) on the - # expiry time of tokens and the way revocation events utilizes token - # expiry to revoke individual tokens. This is a stop-gap until all - # associated issues with resolution on expiration and revocation events - # are resolved. - time.sleep(1) - - token2 = self.get_scoped_token() - - self.admin_request(method='DELETE', - path='/v2.0/tokens/%s' % token2, - token=token1) - - r = self.admin_request( - method='GET', - path='/v2.0/tokens/revoked', - token=token1, - expected_status=http_client.OK) - signed_text = r.result['signed'] - - data_json = cms.cms_verify(signed_text, CONF.signing.certfile, - CONF.signing.ca_certs) - - data = jsonutils.loads(data_json) - - return (data, token2) - - def test_fetch_revocation_list_md5(self): - """Hash for tokens in revocation list and server config should match. - - If the server is configured for md5, then the revocation list has - tokens hashed with MD5. - """ - # The default hash algorithm is md5. - hash_algorithm = 'md5' - - (data, token) = self._fetch_parse_revocation_list() - token_hash = cms.cms_hash_token(token, mode=hash_algorithm) - self.assertThat(token_hash, matchers.Equals(data['revoked'][0]['id'])) - - def test_fetch_revocation_list_sha256(self): - """Hash for tokens in revocation list and server config should match. - - If the server is configured for sha256, then the revocation list has - tokens hashed with SHA256. - """ - hash_algorithm = 'sha256' - self.config_fixture.config(group='token', - hash_algorithm=hash_algorithm) - - (data, token) = self._fetch_parse_revocation_list() - token_hash = cms.cms_hash_token(token, mode=hash_algorithm) - self.assertThat(token_hash, matchers.Equals(data['revoked'][0]['id'])) - def test_create_update_user_invalid_enabled_type(self): # Enforce usage of boolean for 'enabled' field token = self.get_scoped_token() @@ -1467,25 +1401,6 @@ class V2TestCaseFernet(V2TestCase, RestfulTestCase, CoreApiTests, self.skipTest('Revocation lists do not support Fernet') -class RevokeApiTestCase(V2TestCase, RestfulTestCase, CoreApiTests, - LegacyV2UsernameTests): - def config_overrides(self): - super(RevokeApiTestCase, self).config_overrides() - self.config_fixture.config( - group='token', - provider='pki', - revoke_by_id=False) - - def test_fetch_revocation_list_admin_200(self): - self.skip_test_overrides('Revoke API disables revocation_list.') - - def test_fetch_revocation_list_md5(self): - self.skip_test_overrides('Revoke API disables revocation_list.') - - def test_fetch_revocation_list_sha256(self): - self.skip_test_overrides('Revoke API disables revocation_list.') - - class TestFernetTokenProviderV2(RestfulTestCase): def setUp(self): diff --git a/keystone/tests/unit/test_v3_auth.py b/keystone/tests/unit/test_v3_auth.py index 4bcdb88821..2654fef43a 100644 --- a/keystone/tests/unit/test_v3_auth.py +++ b/keystone/tests/unit/test_v3_auth.py @@ -1409,8 +1409,6 @@ class TokenAPITests(object): v3_token_data['token']['expires_at']) def test_v3_v2_token_intermix(self): - # FIXME(gyee): PKI tokens are not interchangeable because token - # data is baked into the token itself. r = self.v3_create_token(self.build_authentication_request( user_id=self.default_domain_user['id'], password=self.default_domain_user['password'], @@ -2426,74 +2424,6 @@ class AllowRescopeScopedTokenDisabledTests(test_v3.RestfulTestCase): expected_status=http_client.FORBIDDEN) -class TestPKITokenAPIs(test_v3.RestfulTestCase, TokenAPITests, TokenDataTests): - def config_overrides(self): - super(TestPKITokenAPIs, self).config_overrides() - self.config_fixture.config(group='token', provider='pki') - - def setUp(self): - super(TestPKITokenAPIs, self).setUp() - self.doSetUp() - - def verify_token(self, *args, **kwargs): - return cms.verify_token(*args, **kwargs) - - def test_v3_token_id(self): - auth_data = self.build_authentication_request( - user_id=self.user['id'], - password=self.user['password']) - resp = self.v3_create_token(auth_data) - token_data = resp.result - token_id = resp.headers.get('X-Subject-Token') - self.assertIn('expires_at', token_data['token']) - - decoded_token = self.verify_token(token_id, CONF.signing.certfile, - CONF.signing.ca_certs) - - decoded_token_dict = json.loads(decoded_token) - token_resp_dict = json.loads(resp.body) - - self.assertEqual(decoded_token_dict, token_resp_dict) - # should be able to validate hash PKI token as well - hash_token_id = cms.cms_hash_token(token_id) - headers = {'X-Subject-Token': hash_token_id} - resp = self.get('/auth/tokens', headers=headers) - expected_token_data = resp.result - self.assertDictEqual(expected_token_data, token_data) - - def test_v3_v2_hashed_pki_token_intermix(self): - auth_data = self.build_authentication_request( - user_id=self.default_domain_user['id'], - password=self.default_domain_user['password'], - project_id=self.default_domain_project['id']) - resp = self.v3_create_token(auth_data) - token_data = resp.result - token = resp.headers.get('X-Subject-Token') - - # should be able to validate a hash PKI token in v2 too - token = cms.cms_hash_token(token) - path = '/v2.0/tokens/%s' % (token) - resp = self.admin_request(path=path, - token=self.get_admin_token(), - method='GET') - v2_token = resp.result - self.assertEqual(v2_token['access']['user']['id'], - token_data['token']['user']['id']) - self.assertTimestampEqual(v2_token['access']['token']['expires'], - token_data['token']['expires_at']) - self.assertEqual(v2_token['access']['user']['roles'][0]['name'], - token_data['token']['roles'][0]['name']) - - -class TestPKIZTokenAPIs(TestPKITokenAPIs): - def config_overrides(self): - super(TestPKIZTokenAPIs, self).config_overrides() - self.config_fixture.config(group='token', provider='pkiz') - - def verify_token(self, *args, **kwargs): - return cms.pkiz_verify(*args, **kwargs) - - class TestUUIDTokenAPIs(test_v3.RestfulTestCase, TokenAPITests, TokenDataTests): def config_overrides(self): @@ -2510,9 +2440,7 @@ class TestUUIDTokenAPIs(test_v3.RestfulTestCase, TokenAPITests, password=self.user['password']) resp = self.v3_create_token(auth_data) token_data = resp.result - token_id = resp.headers.get('X-Subject-Token') self.assertIn('expires_at', token_data['token']) - self.assertFalse(cms.is_asn1_token(token_id)) class TestFernetTokenAPIs(test_v3.RestfulTestCase, TokenAPITests, @@ -2761,8 +2689,15 @@ class TestTokenRevokeById(test_v3.RestfulTestCase): super(TestTokenRevokeById, self).config_overrides() self.config_fixture.config( group='token', - provider='pki', + provider='fernet', revoke_by_id=False) + self.useFixture( + ksfixtures.KeyRepository( + self.config_fixture, + 'fernet_tokens', + CONF.fernet_tokens.max_active_keys + ) + ) def setUp(self): """Setup for Token Revoking Test Cases. @@ -3507,8 +3442,15 @@ class TestTokenRevokeApi(TestTokenRevokeById): super(TestTokenRevokeApi, self).config_overrides() self.config_fixture.config( group='token', - provider='pki', + provider='fernet', revoke_by_id=False) + self.useFixture( + ksfixtures.KeyRepository( + self.config_fixture, + 'fernet_tokens', + CONF.fernet_tokens.max_active_keys + ) + ) def assertValidDeletedProjectResponse(self, events_response, project_id): events = events_response['events'] @@ -3772,24 +3714,6 @@ class TestAuthExternalDomainBehaviorWithUUID(AuthExternalDomainBehavior, self.config_fixture.config(group='token', provider='uuid') -class TestAuthExternalDomainBehaviorWithPKI(AuthExternalDomainBehavior, - test_v3.RestfulTestCase): - def config_overrides(self): - super(TestAuthExternalDomainBehaviorWithPKI, self).config_overrides() - self.kerberos = False - self.auth_plugin_config_override(external='Domain') - self.config_fixture.config(group='token', provider='pki') - - -class TestAuthExternalDomainBehaviorWithPKIZ(AuthExternalDomainBehavior, - test_v3.RestfulTestCase): - def config_overrides(self): - super(TestAuthExternalDomainBehaviorWithPKIZ, self).config_overrides() - self.kerberos = False - self.auth_plugin_config_override(external='Domain') - self.config_fixture.config(group='token', provider='pkiz') - - # NOTE(lbragstad): The Fernet token provider doesn't support bind # authentication so we don't inhereit TestAuthExternalDomain here to test it. @@ -3858,22 +3782,6 @@ class UUIDAuthExternalDefaultDomain(TestAuthExternalDefaultDomain, self.config_fixture.config(group='token', provider='uuid') -class PKIAuthExternalDefaultDomain(TestAuthExternalDefaultDomain, - test_v3.RestfulTestCase): - - def config_overrides(self): - super(PKIAuthExternalDefaultDomain, self).config_overrides() - self.config_fixture.config(group='token', provider='pki') - - -class PKIZAuthExternalDefaultDomain(TestAuthExternalDefaultDomain, - test_v3.RestfulTestCase): - - def config_overrides(self): - super(PKIZAuthExternalDefaultDomain, self).config_overrides() - self.config_fixture.config(group='token', provider='pkiz') - - class UUIDAuthKerberos(AuthExternalDomainBehavior, test_v3.RestfulTestCase): def config_overrides(self): @@ -3884,26 +3792,6 @@ class UUIDAuthKerberos(AuthExternalDomainBehavior, test_v3.RestfulTestCase): methods=['kerberos', 'password', 'token']) -class PKIAuthKerberos(AuthExternalDomainBehavior, test_v3.RestfulTestCase): - - def config_overrides(self): - super(PKIAuthKerberos, self).config_overrides() - self.kerberos = True - self.config_fixture.config(group='token', provider='pki') - self.auth_plugin_config_override( - methods=['kerberos', 'password', 'token']) - - -class PKIZAuthKerberos(AuthExternalDomainBehavior, test_v3.RestfulTestCase): - - def config_overrides(self): - super(PKIZAuthKerberos, self).config_overrides() - self.kerberos = True - self.config_fixture.config(group='token', provider='pkiz') - self.auth_plugin_config_override( - methods=['kerberos', 'password', 'token']) - - # NOTE(lbragstad): The Fernet token provider doesn't support bind # authentication so we don't inherit AuthExternalDomainBehavior here to test # it. @@ -4991,26 +4879,6 @@ class TestAuthSpecificData(test_v3.RestfulTestCase): self.assertValidDomainListResponse(r) -class TestTrustAuthPKITokenProvider(TrustAPIBehavior, TestTrustChain): - def config_overrides(self): - super(TestTrustAuthPKITokenProvider, self).config_overrides() - self.config_fixture.config(group='token', - provider='pki', - revoke_by_id=False) - self.config_fixture.config(group='trust', - enabled=True) - - -class TestTrustAuthPKIZTokenProvider(TrustAPIBehavior, TestTrustChain): - def config_overrides(self): - super(TestTrustAuthPKIZTokenProvider, self).config_overrides() - self.config_fixture.config(group='token', - provider='pkiz', - revoke_by_id=False) - self.config_fixture.config(group='trust', - enabled=True) - - class TestTrustAuthFernetTokenProvider(TrustAPIBehavior, TestTrustChain): def config_overrides(self): super(TestTrustAuthFernetTokenProvider, self).config_overrides() diff --git a/keystone/tests/unit/token/test_backends.py b/keystone/tests/unit/token/test_backends.py index aa2e83d5b5..c04ef79f4c 100644 --- a/keystone/tests/unit/token/test_backends.py +++ b/keystone/tests/unit/token/test_backends.py @@ -12,10 +12,8 @@ import copy import datetime -import hashlib import uuid -from keystoneclient.common import cms from oslo_utils import timeutils import six from six.moves import range @@ -32,13 +30,7 @@ NULL_OBJECT = object() class TokenTests(object): def _create_token_id(self): - # Use a token signed by the cms module - token_id = "" - for i in range(1, 20): - token_id += uuid.uuid4().hex - return cms.cms_sign_token(token_id, - CONF.signing.certfile, - CONF.signing.keyfile) + return uuid.uuid4().hex def _assert_revoked_token_list_matches_token_persistence( self, revoked_token_id_list): @@ -367,30 +359,6 @@ class TokenTests(object): self.assertIn(token_id, revoked_ids) self.assertIn(token2_id, revoked_ids) - def _test_predictable_revoked_pki_token_id(self, hash_fn): - token_id = self._create_token_id() - token_id_hash = hash_fn(token_id.encode('utf-8')).hexdigest() - token = {'user': {'id': uuid.uuid4().hex}, - 'token_data': {'token': {'audit_ids': [uuid.uuid4().hex]}}} - - self.token_provider_api._persistence.create_token(token_id, token) - self.token_provider_api._persistence.delete_token(token_id) - - revoked_ids = [x['id'] - for x in self.token_provider_api.list_revoked_tokens()] - self._assert_revoked_token_list_matches_token_persistence(revoked_ids) - self.assertIn(token_id_hash, revoked_ids) - self.assertNotIn(token_id, revoked_ids) - for t in self.token_provider_api._persistence.list_revoked_tokens(): - self.assertIn('expires', t) - - def test_predictable_revoked_pki_token_id_default(self): - self._test_predictable_revoked_pki_token_id(hashlib.md5) - - def test_predictable_revoked_pki_token_id_sha256(self): - self.config_fixture.config(group='token', hash_algorithm='sha256') - self._test_predictable_revoked_pki_token_id(hashlib.sha256) - def test_predictable_revoked_uuid_token_id(self): token_id = uuid.uuid4().hex token = {'user': {'id': uuid.uuid4().hex}, diff --git a/keystone/tests/unit/token/test_pki_provider.py b/keystone/tests/unit/token/test_pki_provider.py deleted file mode 100644 index b3ad4c2bb2..0000000000 --- a/keystone/tests/unit/token/test_pki_provider.py +++ /dev/null @@ -1,26 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from keystone.tests import unit -from keystone.token.providers import pki - - -class TestPkiTokenProvider(unit.TestCase): - def setUp(self): - super(TestPkiTokenProvider, self).setUp() - self.provider = pki.Provider() - - def test_supports_bind_authentication_returns_true(self): - self.assertTrue(self.provider._supports_bind_authentication) - - def test_need_persistence_return_true(self): - self.assertIs(True, self.provider.needs_persistence()) diff --git a/keystone/tests/unit/token/test_pkiz_provider.py b/keystone/tests/unit/token/test_pkiz_provider.py deleted file mode 100644 index 1ffe7cfc69..0000000000 --- a/keystone/tests/unit/token/test_pkiz_provider.py +++ /dev/null @@ -1,26 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from keystone.tests import unit -from keystone.token.providers import pkiz - - -class TestPkizTokenProvider(unit.TestCase): - def setUp(self): - super(TestPkizTokenProvider, self).setUp() - self.provider = pkiz.Provider() - - def test_supports_bind_authentication_returns_true(self): - self.assertTrue(self.provider._supports_bind_authentication) - - def test_need_persistence_return_true(self): - self.assertIs(True, self.provider.needs_persistence()) diff --git a/keystone/token/persistence/core.py b/keystone/token/persistence/core.py index e3e6be2ac5..33e0b86876 100644 --- a/keystone/token/persistence/core.py +++ b/keystone/token/persistence/core.py @@ -26,7 +26,6 @@ from keystone.common import manager import keystone.conf from keystone import exception from keystone.i18n import _LW -from keystone.token import utils CONF = keystone.conf.CONF @@ -52,7 +51,7 @@ class PersistenceManager(manager.Manager): super(PersistenceManager, self).__init__(CONF.token.driver) def get_token(self, token_id): - return self._get_token(utils.generate_unique_id(token_id)) + return self._get_token(token_id) @MEMOIZE def _get_token(self, token_id): @@ -60,23 +59,21 @@ class PersistenceManager(manager.Manager): return self.driver.get_token(token_id) def create_token(self, token_id, data): - unique_id = utils.generate_unique_id(token_id) data_copy = copy.deepcopy(data) - data_copy['id'] = unique_id - ret = self.driver.create_token(unique_id, data_copy) + data_copy['id'] = token_id + ret = self.driver.create_token(token_id, data_copy) if MEMOIZE.should_cache(ret): # NOTE(morganfainberg): when doing a cache set, you must pass the # same arguments through, the same as invalidate (this includes # "self"). First argument is always the value to be cached - self._get_token.set(ret, self, unique_id) + self._get_token.set(ret, self, token_id) return ret def delete_token(self, token_id): if not CONF.token.revoke_by_id: return - unique_id = utils.generate_unique_id(token_id) - self.driver.delete_token(unique_id) - self._invalidate_individual_token_cache(unique_id) + self.driver.delete_token(token_id) + self._invalidate_individual_token_cache(token_id) self.invalidate_revocation_list() def delete_tokens(self, user_id, tenant_id=None, trust_id=None, @@ -86,8 +83,7 @@ class PersistenceManager(manager.Manager): token_list = self.driver.delete_tokens(user_id, tenant_id, trust_id, consumer_id) for token_id in token_list: - unique_id = utils.generate_unique_id(token_id) - self._invalidate_individual_token_cache(unique_id) + self._invalidate_individual_token_cache(token_id) self.invalidate_revocation_list() @REVOCATION_MEMOIZE diff --git a/keystone/token/provider.py b/keystone/token/provider.py index 26a5691f60..7709826c68 100644 --- a/keystone/token/provider.py +++ b/keystone/token/provider.py @@ -29,7 +29,6 @@ from keystone.i18n import _, _LE from keystone.models import token_model from keystone import notifications from keystone.token import persistence -from keystone.token import utils CONF = keystone.conf.CONF @@ -166,10 +165,7 @@ class Manager(manager.Manager): # Otherwise the information about the token must be in the token # id. if self._needs_persistence: - unique_id = utils.generate_unique_id(token_id) - # NOTE(morganfainberg): Ensure we never use the long-form - # token_id (PKI) as part of the cache_key. - token_ref = self._persistence.get_token(unique_id) + token_ref = self._persistence.get_token(token_id) # Overload the token_id variable to be a token reference # instead. token_id = token_ref diff --git a/keystone/token/providers/pki.py b/keystone/token/providers/pki.py deleted file mode 100644 index a43861370d..0000000000 --- a/keystone/token/providers/pki.py +++ /dev/null @@ -1,67 +0,0 @@ -# Copyright 2013 OpenStack Foundation -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -"""Keystone PKI Token Provider.""" - -import subprocess # nosec : used to catch subprocess exceptions - -from keystoneclient.common import cms -from oslo_log import log -from oslo_log import versionutils -from oslo_serialization import jsonutils - -from keystone.common import utils -import keystone.conf -from keystone import exception -from keystone.i18n import _, _LE -from keystone.token.providers import common - - -CONF = keystone.conf.CONF - -LOG = log.getLogger(__name__) - - -@versionutils.deprecated( - as_of=versionutils.deprecated.MITAKA, - what='the PKI token provider', - in_favor_of='the Fernet or UUID token providers') -class Provider(common.BaseProvider): - def _get_token_id(self, token_data): - try: - # force conversion to a string as the keystone client cms code - # produces unicode. This can be removed if the client returns - # str() - # TODO(ayoung): Make to a byte_str for Python3 - token_json = jsonutils.dumps(token_data, cls=utils.PKIEncoder) - token_id = str(cms.cms_sign_token(token_json, - CONF.signing.certfile, - CONF.signing.keyfile)) - return token_id - except subprocess.CalledProcessError: - LOG.exception(_LE('Unable to sign token')) - raise exception.UnexpectedError(_( - 'Unable to sign token.')) - - @property - def _supports_bind_authentication(self): - """Return if the token provider supports bind authentication methods. - - :returns: True - """ - return True - - def needs_persistence(self): - """Should the token be written to a backend.""" - return True diff --git a/keystone/token/providers/pkiz.py b/keystone/token/providers/pkiz.py deleted file mode 100644 index 69ebd86acd..0000000000 --- a/keystone/token/providers/pkiz.py +++ /dev/null @@ -1,65 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -"""Keystone Compressed PKI Token Provider.""" - -import subprocess # nosec : used to catch subprocess exceptions - -from keystoneclient.common import cms -from oslo_log import log -from oslo_log import versionutils -from oslo_serialization import jsonutils - -from keystone.common import utils -import keystone.conf -from keystone import exception -from keystone.i18n import _ -from keystone.token.providers import common - - -CONF = keystone.conf.CONF - -LOG = log.getLogger(__name__) -ERROR_MESSAGE = _('Unable to sign token.') - - -@versionutils.deprecated( - as_of=versionutils.deprecated.MITAKA, - what='the PKIZ token provider', - in_favor_of='the Fernet or UUID token providers') -class Provider(common.BaseProvider): - def _get_token_id(self, token_data): - try: - # force conversion to a string as the keystone client cms code - # produces unicode. This can be removed if the client returns - # str() - # TODO(ayoung): Make to a byte_str for Python3 - token_json = jsonutils.dumps(token_data, cls=utils.PKIEncoder) - token_id = str(cms.pkiz_sign(token_json, - CONF.signing.certfile, - CONF.signing.keyfile)) - return token_id - except subprocess.CalledProcessError: - LOG.exception(ERROR_MESSAGE) - raise exception.UnexpectedError(ERROR_MESSAGE) - - @property - def _supports_bind_authentication(self): - """Return if the token provider supports bind authentication methods. - - :returns: True - """ - return True - - def needs_persistence(self): - """Should the token be written to a backend.""" - return True diff --git a/keystone/token/utils.py b/keystone/token/utils.py deleted file mode 100644 index 1243e4bc8c..0000000000 --- a/keystone/token/utils.py +++ /dev/null @@ -1,31 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from keystoneclient.common import cms - -import keystone.conf - - -CONF = keystone.conf.CONF - - -def generate_unique_id(token_id): - """Return a unique ID for a token. - - The returned value is useful as the primary key of a database table, - memcache store, or other lookup table. - - :returns: Given a PKI token, returns it's hashed value. Otherwise, - returns the passed-in value (such as a UUID token ID or an - existing hash). - """ - return cms.cms_hash_token(token_id, mode=CONF.token.hash_algorithm) diff --git a/setup.cfg b/setup.cfg index 90f66ec57c..4bd9072d64 100644 --- a/setup.cfg +++ b/setup.cfg @@ -163,8 +163,6 @@ keystone.token.persistence = keystone.token.provider = fernet = keystone.token.providers.fernet:Provider uuid = keystone.token.providers.uuid:Provider - pki = keystone.token.providers.pki:Provider - pkiz = keystone.token.providers.pkiz:Provider keystone.trust = sql = keystone.trust.backends.sql:Trust diff --git a/tox.ini b/tox.ini index 10508db0e1..fba55f47a8 100644 --- a/tox.ini +++ b/tox.ini @@ -32,7 +32,7 @@ commands = flake8 # Run bash8 during pep8 runs to ensure violations are caught by # the check and gate queues - bashate examples/pki/gen_pki.sh devstack/plugin.sh + bashate devstack/plugin.sh # Run security linter bandit -r keystone -x tests