Ask Your Question
1

Decode Keystone Token in Java [closed]

asked 2014-08-12 14:08:45 -0500

astone gravatar image

Hello,

We're evaluating using keystone as an identity service for our Java-based application in an enterprise environment. In doing so we'll need to decode and check the signed token provided by a user.

Here's where I am at:

  • I have user/tenant/roles in keystone
  • I can 'getToken', can query using token and perform actions against keystone through Java via KS API no problem
  • I have the CA and Signing certificates (/certifcate/signing, /certificate/ca) as a String in a variable

I've read that it is CMS encoded and signed with the certs, and i've been trying to use BouncyCastle libraries with no luck

Does anyone have examples on how I can decode the Token to get the original message, preferably in Java?

Any input would be much appreciated!

edit retag flag offensive reopen merge delete

Closed for the following reason the question is answered, right answer was accepted by astone
close date 2014-08-13 11:38:31.047725

2 answers

Sort by » oldest newest most voted
0

answered 2014-08-12 16:09:37 -0500

SamYaple gravatar image

updated 2014-08-12 16:10:35 -0500

Adam Young did a great writeup of how keystone is using tokens. The artical is specifically dealing with compressed tokens, but you should be able to pull the information about how it is encoded before compression.

The key points are:

  • Non-standard Base64 encoded
  • / replaced with -

That should be enough to get you moving. I provide an example below.

This token translates as follows:

MIILYgYJKoZIhvcNAQcCoIILUzCCC08CAQExCTAHBgUrDgMCGjCCCbgGCSqGSIb3DQEHAaCCCakEggmleyJhY2Nlc3MiOiB7InRva2VuIjogeyJpc3N1ZWRfYXQiOiAiMjAxNC0wOC0wOFQxNToyMDowMi4zNzY0NTQiLCAiZXhwaXJlcyI6ICIyMDE0LTA4LTA4VDE2OjIwOjAyWiIsICJpZCI6ICJwbGFjZWhvbGRlciIsICJ0ZW5hbnQiOiB7ImRlc2NyaXB0aW9uIjogbnVsbCwgImVuYWJsZWQiOiB0cnVlLCAiaWQiOiAiMzU4ZGU0Y2UyNTExNGNkNDhjZWU5MWM1ODhjMTIyMWYiLCAibmFtZSI6ICJNeVByb2plY3QifX0sICJzZXJ2aWNlQ2F0YWxvZyI6IFt7ImVuZHBvaW50cyI6IFt7ImFkbWluVVJMIjogImh0dHA6Ly8xOTIuMTY4LjIuMTA6ODc3NC92Mi8zNThkZTRjZTI1MTE0Y2Q0OGNlZTkxYzU4OGMxMjIxZiIsICJyZWdpb24iOiAiUmVnaW9uT25lIiwgImludGVybmFsVVJMIjogImh0dHA6Ly8xOTIuMTY4LjIuMTA6ODc3NC92Mi8zNThkZTRjZTI1MTE0Y2Q0OGNlZTkxYzU4OGMxMjIxZiIsICJpZCI6ICIxYjA4Y2U4ZjJkNTM0M2VhYjMxMThkZDE1YmUyZTQ2NCIsICJwdWJsaWNVUkwiOiAiaHR0cDovLzE5Mi4xNjguMi4xMDo4Nzc0L3YyLzM1OGRlNGNlMjUxMTRjZDQ4Y2VlOTFjNTg4YzEyMjFmIn1dLCAiZW5kcG9pbnRzX2xpbmtzIjogW10sICJ0eXBlIjogImNvbXB1dGUiLCAibmFtZSI6ICJub3ZhIn0sIHsiZW5kcG9pbnRzIjogW3siYWRtaW5VUkwiOiAiaHR0cDovLzE5Mi4xNjguMi4xMDo5Njk2IiwgInJlZ2lvbiI6ICJSZWdpb25PbmUiLCAiaW50ZXJuYWxVUkwiOiAiaHR0cDovLzE5Mi4xNjguMi4xMDo5Njk2IiwgImlkIjogIjA5Nzc4NTA2NmYwNjQ0NTZhM2Q5MjM0ZjFlNWE2NTI3IiwgInB1YmxpY1VSTCI6ICJodHRwOi8vMTkyLjE2OC4yLjEwOjk2OTYifV0sICJlbmRwb2ludHNfbGlua3MiOiBbXSwgInR5cGUiOiAibmV0d29yayIsICJuYW1lIjogIm5ldXRyb24ifSwgeyJlbmRwb2ludHMiOiBbeyJhZG1pblVSTCI6ICJodHRwOi8vMTkyLjE2OC4yLjEwOjkyOTIvdjEiLCAicmVnaW9uIjogIlJlZ2lvbk9uZSIsICJpbnRlcm5hbFVSTCI6ICJodHRwOi8vMTkyLjE2OC4yLjEwOjkyOTIvdjEiLCAiaWQiOiAiMDE0YjRiZTNmYzBkNDNmYTk1YTI3MGY2OTBiOTdkYTUiLCAicHVibGljVVJMIjogImh0dHA6Ly8xOTIuMTY4LjIuMTA6OTI5Mi92MSJ9XSwgImVuZHBvaW50c19saW5rcyI6IFtdLCAidHlwZSI6ICJpbWFnZSIsICJuYW1lIjogImdsYW5jZSJ9LCB7ImVuZHBvaW50cyI6IFt7ImFkbWluVVJMIjogImh0dHA6Ly8xOTIuMTY4LjIuMTA6ODc3Ni92MS8zNThkZTRjZTI1MTE0Y2Q0OGNlZTkxYzU4OGMxMjIxZiIsICJyZWdpb24iOiAiUmVnaW9uT25lIiwgImludGVybmFsVVJMIjogImh0dHA6Ly8xOTIuMTY4LjIuMTA6ODc3Ni92MS8zNThkZTRjZTI1MTE0Y2Q0OGNlZTkxYzU4OGMxMjIxZiIsICJpZCI6ICIxMGVlNjQ4MTE1YmI0Yzk0OWZlZWI5NmMxZDlhMjA5OSIsICJwdWJsaWNVUkwiOiAiaHR0cDovLzE5Mi4xNjguMi4xMDo4Nzc2L3YxLzM1OGRlNGNlMjUxMTRjZDQ4Y2VlOTFjNTg4YzEyMjFmIn1dLCAiZW5kcG9pbnRzX2xpbmtzIjogW10sICJ0eXBlIjogInZvbHVtZSIsICJuYW1lIjogImNpbmRlciJ9LCB7ImVuZHBvaW50cyI6IFt7ImFkbWluVVJMIjogImh0dHA6Ly8xOTIuMTY4LjIuMTA6ODA4MC92MSIsICJyZWdpb24iOiAiUmVnaW9uT25lIiwgImludGVybmFsVVJMIjogImh0dHA6Ly8xOTIuMTY4LjIuMTA6ODA4MC92MS9BVVRIXzM1OGRlNGNlMjUxMTRjZDQ4Y2VlOTFjNTg4YzEyMjFmIiwgImlkIjogIjkwYmI0MWIyN2E0ZDRiZGNiM2FiYzM5MzMzODk2ZDZhIiwgInB1YmxpY1VSTCI6ICJodHRwOi8vMTkyLjE2OC4yLjEwOjgwODAvdjEvQVVUSF8zNThkZTRjZTI1MTE0Y2Q0OGNlZTkxYzU4OGMxMjIxZiJ9XSwgImVuZHBvaW50c19saW5rcyI6IFtdLCAidHlwZSI6ICJvYmplY3Qtc3RvcmUiLCAibmFtZSI6ICJzd2lmdCJ9LCB7ImVuZHBvaW50cyI6IFt7ImFkbWluVVJMIjogImh0dHA6Ly8xOTIuMTY4LjIuMTA6MzUzNTcvdjIuMCIsICJyZWdpb24iOiAiUmVnaW9uT25lIiwgImludGVybmFsVVJMIjogImh0dHA6Ly8xOTIuMTY4LjIuMTA6NTAwMC92Mi4wIiwgImlkIjogIjQzNWEwZGYzNjU3YzRmNmNhNmUwMmIxNjhjZGFmMWFhIiwgInB1YmxpY1VSTCI6ICJodHRwOi8vMTkyLjE2OC4yLjEwOjUwMDAvdjIuMCJ9XSwgImVuZHBvaW50c19saW5rcyI6IFtdLCAidHlwZSI6ICJpZGVudGl0eSIsICJuYW1lIjogImtleXN0b25lIn1dLCAidXNlciI6IHsidXNlcm5hbWUiOiAibXlhZG1pbiIsICJyb2xlc19saW5rcyI6IFtdLCAiaWQiOiAiNTQ4ZTY3MzllMjczNGI5ZWEyODViZDM0Y2EzZDkzZGMiLCAicm9sZXMiOiBbeyJuYW1lIjogIl9tZW1iZXJfIn0sIHsibmFtZSI6ICJhZG1pbiJ9XSwgIm5hbWUiOiAibXlhZG1pbiJ9LCAibWV0YWRhdGEiOiB7ImlzX2FkbWluIjogMCwgInJvbGVzIjogWyI5ZmUyZmY5ZWU0Mzg0YjE4OTRhOTA4NzhkM2U5MmJhYiIsICJkZmU4MmE1MTM3NmQ0NWU3OGNlYWM1OWZlNDgyY2VkNCJdfX19MYIBgTCCAX0CAQEwXDBXMQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVW5zZXQxDjAMBgNVBAcMBVVuc2V0MQ4wDAYDVQQKDAVVbnNldDEYMBYGA1UEAwwPd3d3LmV4YW1wbGUuY29tAgEBMAcGBSsOAwIaMA0GCSqGSIb3DQEBAQUABIIBAEEdef1ty0DuTn0DLnKzDVNTw4Oj2poh0v9+tdN-nP5-pc9OrG+3Z0GQb1pVMRKfalgwYWeCQJOuAFWPKq9suZTHdfDJDRBQKp8xgQQMT4712VSqMCbLKBjZ0Hu50j-303g8f3r0ZU6iG7NtCTNfFNCGoe5JSiw8e71OEPUzZRlwf5odUPNbRtK1aVNuleJZglB-5Tidg5f4JrSO-28h6MI4YB6zlV8JXKj7HGpg3j337bfE7pt73iK5qoDx-wOGZ+m9fj3u7pFTG3mVizH0Eej5C-t+9CrRDi+wynEKwvxPc9AD8Q-l1fE8gW1Xpt5Dlr-GBUJ2Bk5HzUXFQueWDf0=

Replace - with / to conform to base64

MIILYgYJKoZIhvcNAQcCoIILUzCCC08CAQExCTAHBgUrDgMCGjCCCbgGCSqGSIb3DQEHAaCCCakEggmleyJhY2Nlc3MiOiB7InRva2VuIjogeyJpc3N1ZWRfYXQiOiAiMjAxNC0wOC0wOFQxNToyMDowMi4zNzY0NTQiLCAiZXhwaXJlcyI6ICIyMDE0LTA4LTA4VDE2OjIwOjAyWiIsICJpZCI6ICJwbGFjZWhvbGRlciIsICJ0ZW5hbnQiOiB7ImRlc2NyaXB0aW9uIjogbnVsbCwgImVuYWJsZWQiOiB0cnVlLCAiaWQiOiAiMzU4ZGU0Y2UyNTExNGNkNDhjZWU5MWM1ODhjMTIyMWYiLCAibmFtZSI6ICJNeVByb2plY3QifX0sICJzZXJ2aWNlQ2F0YWxvZyI6IFt7ImVuZHBvaW50cyI6IFt7ImFkbWluVVJMIjogImh0dHA6Ly8xOTIuMTY4LjIuMTA6ODc3NC92Mi8zNThkZTRjZTI1MTE0Y2Q0OGNlZTkxYzU4OGMxMjIxZiIsICJyZWdpb24iOiAiUmVnaW9uT25lIiwgImludGVybmFsVVJMIjogImh0dHA6Ly8xOTIuMTY4LjIuMTA6ODc3NC92Mi8zNThkZTRjZTI1MTE0Y2Q0OGNlZTkxYzU4OGMxMjIxZiIsICJpZCI6ICIxYjA4Y2U4ZjJkNTM0M2VhYjMxMThkZDE1YmUyZTQ2NCIsICJwdWJsaWNVUkwiOiAiaHR0cDovLzE5Mi4xNjguMi4xMDo4Nzc0L3YyLzM1OGRlNGNlMjUxMTRjZDQ4Y2VlOTFjNTg4YzEyMjFmIn1dLCAiZW5kcG9pbnRzX2xpbmtzIjogW10sICJ0eXBlIjogImNvbXB1dGUiLCAibmFtZSI6ICJub3ZhIn0sIHsiZW5kcG9pbnRzIjogW3siYWRtaW5VUkwiOiAiaHR0cDovLzE5Mi4xNjguMi4xMDo5Njk2IiwgInJlZ2lvbiI6ICJSZWdpb25PbmUiLCAiaW50ZXJuYWxVUkwiOiAiaHR0cDovLzE5Mi4xNjguMi4xMDo5Njk2IiwgImlkIjogIjA5Nzc4NTA2NmYwNjQ0NTZhM2Q5MjM0ZjFlNWE2NTI3IiwgInB1YmxpY1VSTCI6ICJodHRwOi8vMTkyLjE2OC4yLjEwOjk2OTYifV0sICJlbmRwb2ludHNfbGlua3MiOiBbXSwgInR5cGUiOiAibmV0d29yayIsICJuYW1lIjogIm5ldXRyb24ifSwgeyJlbmRwb2ludHMiOiBbeyJhZG1pblVSTCI6ICJodHRwOi8vMTkyLjE2OC4yLjEwOjkyOTIvdjEiLCAicmVnaW9uIjogIlJlZ2lvbk9uZSIsICJpbnRlcm5hbFVSTCI6ICJodHRwOi8vMTkyLjE2OC4yLjEwOjkyOTIvdjEiLCAiaWQiOiAiMDE0YjRiZTNmYzBkNDNmYTk1YTI3MGY2OTBiOTdkYTUiLCAicHVibGljVVJMIjogImh0dHA6Ly8xOTIuMTY4LjIuMTA6OTI5Mi92MSJ9XSwgImVuZHBvaW50c19saW5rcyI6IFtdLCAidHlwZSI6ICJpbWFnZSIsICJuYW1lIjogImdsYW5jZSJ9LCB7ImVuZHBvaW50cyI6IFt7ImFkbWluVVJMIjogImh0dHA6Ly8xOTIuMTY4LjIuMTA6ODc3Ni92MS8zNThkZTRjZTI1MTE0Y2Q0OGNlZTkxYzU4OGMxMjIxZiIsICJyZWdpb24iOiAiUmVnaW9uT25lIiwgImludGVybmFsVVJMIjogImh0dHA6Ly8xOTIuMTY4LjIuMTA6ODc3Ni92MS8zNThkZTRjZTI1MTE0Y2Q0OGNlZTkxYzU4OGMxMjIxZiIsICJpZCI6ICIxMGVlNjQ4MTE1YmI0Yzk0OWZlZWI5NmMxZDlhMjA5OSIsICJwdWJsaWNVUkwiOiAiaHR0cDovLzE5Mi4xNjguMi4xMDo4Nzc2L3YxLzM1OGRlNGNlMjUxMTRjZDQ4Y2VlOTFjNTg4YzEyMjFmIn1dLCAiZW5kcG9pbnRzX2xpbmtzIjogW10sICJ0eXBlIjogInZvbHVtZSIsICJuYW1lIjogImNpbmRlciJ9LCB7ImVuZHBvaW50cyI6IFt7ImFkbWluVVJMIjogImh0dHA6Ly8xOTIuMTY4LjIuMTA6ODA4MC92MSIsICJyZWdpb24iOiAiUmVnaW9uT25lIiwgImludGVybmFsVVJMIjogImh0dHA6Ly8xOTIuMTY4LjIuMTA6ODA4MC92MS9BVVRIXzM1OGRlNGNlMjUxMTRjZDQ4Y2VlOTFjNTg4YzEyMjFmIiwgImlkIjogIjkwYmI0MWIyN2E0ZDRiZGNiM2FiYzM5MzMzODk2ZDZhIiwgInB1YmxpY1VSTCI6ICJodHRwOi8vMTkyLjE2OC4yLjEwOjgwODAvdjEvQVVUSF8zNThkZTRjZTI1MTE0Y2Q0OGNlZTkxYzU4OGMxMjIxZiJ9XSwgImVuZHBvaW50c19saW5rcyI6IFtdLCAidHlwZSI6ICJvYmplY3Qtc3RvcmUiLCAibmFtZSI6ICJzd2lmdCJ9LCB7ImVuZHBvaW50cyI6IFt7ImFkbWluVVJMIjogImh0dHA6Ly8xOTIuMTY4LjIuMTA6MzUzNTcvdjIuMCIsICJyZWdpb24iOiAiUmVnaW9uT25lIiwgImludGVybmFsVVJMIjogImh0dHA6Ly8xOTIuMTY4LjIuMTA6NTAwMC92Mi4wIiwgImlkIjogIjQzNWEwZGYzNjU3YzRmNmNhNmUwMmIxNjhjZGFmMWFhIiwgInB1YmxpY1VSTCI6ICJodHRwOi8vMTkyLjE2OC4yLjEwOjUwMDAvdjIuMCJ9XSwgImVuZHBvaW50c19saW5rcyI6IFtdLCAidHlwZSI6ICJpZGVudGl0eSIsICJuYW1lIjogImtleXN0b25lIn1dLCAidXNlciI6IHsidXNlcm5hbWUiOiAibXlhZG1pbiIsICJyb2xlc19saW5rcyI6IFtdLCAiaWQiOiAiNTQ4ZTY3MzllMjczNGI5ZWEyODViZDM0Y2EzZDkzZGMiLCAicm9sZXMiOiBbeyJuYW1lIjogIl9tZW1iZXJfIn0sIHsibmFtZSI6ICJhZG1pbiJ9XSwgIm5hbWUiOiAibXlhZG1pbiJ9LCAibWV0YWRhdGEiOiB7ImlzX2FkbWluIjogMCwgInJvbGVzIjogWyI5ZmUyZmY5ZWU0Mzg0YjE4OTRhOTA4NzhkM2U5MmJhYiIsICJkZmU4MmE1MTM3NmQ0NWU3OGNlYWM1OWZlNDgyY2VkNCJdfX19MYIBgTCCAX0CAQEwXDBXMQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVW5zZXQxDjAMBgNVBAcMBVVuc2V0MQ4wDAYDVQQKDAVVbnNldDEYMBYGA1UEAwwPd3d3LmV4YW1wbGUuY29tAgEBMAcGBSsOAwIaMA0GCSqGSIb3DQEBAQUABIIBAEEdef1ty0DuTn0DLnKzDVNTw4Oj2poh0v9+tdN/nP5/pc9OrG+3Z0GQb1pVMRKfalgwYWeCQJOuAFWPKq9suZTHdfDJDRBQKp8xgQQMT4712VSqMCbLKBjZ0Hu50j/303g8f3r0ZU6iG7NtCTNfFNCGoe5JSiw8e71OEPUzZRlwf5odUPNbRtK1aVNuleJZglB/5Tidg5f4JrSO/28h6MI4YB6zlV8JXKj7HGpg3j337bfE7pt73iK5qoDx/wOGZ+m9fj3u7pFTG3mVizH0Eej5C/t+9CrRDi+wynEKwvxPc9AD8Q/l1fE8gW1Xpt5Dlr/GBUJ2Bk5HzUXFQueWDf0=

Pipe through base64 decoding

0�
��b     *�H��
  S0�
��   O1 ��0�    �{"access": {"token": {"issued_at": "2014-08-08T15:20:02.376454", "expires": "2014-08-08T16:20:02Z", "id": "placeholder", "tenant": {"description": null, "enabled": true, "id": "358de4ce25114cd48cee91c588c1221f", "name": "MyProject"}}, "serviceCatalog": [{"endpoints": [{"adminURL": "http://192.168.2.10:8774/v2/358de4ce25114cd48cee91c588c1221f", "region": "RegionOne", "internalURL": "http://192.168.2.10:8774/v2/358de4ce25114cd48cee91c588c1221f", "id": "1b08ce8f2d5343eab3118dd15be2e464", "publicURL": "http://192.168.2.10:8774/v2/358de4ce25114cd48cee91c588c1221f"}], "endpoints_links": [], "type": "compute", "name": "nova"}, {"endpoints": [{"adminURL": "http://192.168.2.10:9696", "region": "RegionOne", "internalURL": "http://192.168.2.10:9696", "id": "097785066f064456a3d9234f1e5a6527", "publicURL": "http://192.168.2.10:9696"}], "endpoints_links": [], "type": "network", "name": "neutron"}, {"endpoints": [{"adminURL": "http://192.168.2.10:9292/v1", "region": "RegionOne", "internalURL": "http://192.168.2.10:9292/v1", "id": "014b4be3fc0d43fa95a270f690b97da5", "publicURL": "http://192.168.2.10:9292/v1"}], "endpoints_links": [], "type": "image", "name": "glance"}, {"endpoints": [{"adminURL": "http://192.168.2.10:8776/v1/358de4ce25114cd48cee91c588c1221f", "region": "RegionOne", "internalURL": "http://192.168.2.10:8776/v1/358de4ce25114cd48cee91c588c1221f", "id": "10ee648115bb4c949feeb96c1d9a2099", "publicURL": "http://192.168.2.10:8776/v1/358de4ce25114cd48cee91c588c1221f"}], "endpoints_links": [], "type": "volume", "name": "cinder"}, {"endpoints": [{"adminURL": "http://192.168.2.10:8080/v1", "region": "RegionOne", "internalURL": "http://192.168.2.10:8080/v1/AUTH_358de4ce25114cd48cee91c588c1221f", "id": "90bb41b27a4d4bdcb3abc39333896d6a", "publicURL": "http://192.168.2.10:8080/v1/AUTH_358de4ce25114cd48cee91c588c1221f"}], "endpoints_links": [], "type": "object-store", "name": "swift"}, {"endpoints": [{"adminURL": "http://192.168.2.10:35357/v2.0", "region": "RegionOne", "internalURL": "http://192.168.2.10:5000/v2.0", "id": "435a0df3657c4f6ca6e02b168cdaf1aa", "publicURL": "http://192.168.2.10:5000/v2.0"}], "endpoints_links": [], "type": "identity", "name": "keystone"}], "user": {"username": "myadmin", "roles_links": [], "id": "548e6739e2734b9ea285bd34ca3d93dc", "roles": [{"name": "_member_"}, {"name": "admin"}], "name": "myadmin"}, "metadata": {"is_admin": 0, "roles": ["9fe2ff9ee4384b1894a90878d3e92bab", "dfe82a51376d45e78ceac59fe482ced4"]}}}1��0�}0\0W1
                                                                                                                                                                                                                                                                         0      UUS10
                                                                                                                                                                                                                                                                                     U
                                                                                                                                                                                                                                                                                     Unset10
     U
      Unset10
             U

Unset10U
P*�1�!�~������N�o�gA�oZU1�jX0ag�@��U�*�l���u�
     O��T�0&�(�{��?�x<z�eN�m    3_І��IJ,<{�N�3ep�P�[FҵiSn��Y�P�8����&���o!�8`��_        \��j`�=����{�"�����g�~=��S��1��
                                                                                                                       �~�*�/��q
�
edit flag offensive delete link more
0

answered 2014-08-13 09:22:39 -0500

astone gravatar image

updated 2014-08-13 09:26:04 -0500

SamYaple gravatar image

Thank you for the quicky reply! that's exactly the kind of detail I was missing.

For anyone that stumbled on to this, here's some sample code. I'n using openstack4j as my communication library, I wrote a thin wrapper to request the certificates from OS as a String, and bouncy castle for the signature verification.

This code needs more cleanup / handle multiple certificates but it shows the workflow:


<dependency>
    <groupId>org.bouncycastle</groupId>
    <artifactId>bcpkix-jdk15on</artifactId>
    <version>1.51</version>
</dependency>

<dependency>
    <groupId>org.pacesys</groupId>
    <artifactId>openstack4j</artifactId>
    <version>1.0.1</version>
</dependency>

import org.apache.commons.codec.binary.Base64;
import org.bouncycastle.cert.X509CertificateHolder;
import org.bouncycastle.cms.CMSException;
import org.bouncycastle.cms.CMSSignedData;
import org.bouncycastle.cms.DefaultCMSSignatureAlgorithmNameGenerator;
import org.bouncycastle.cms.SignerInformation;
import org.bouncycastle.cms.SignerInformationStore;
import org.bouncycastle.cms.SignerInformationVerifier;
import org.bouncycastle.cms.bc.BcRSASignerInfoVerifierBuilder;
import org.bouncycastle.operator.DefaultDigestAlgorithmIdentifierFinder;
import org.bouncycastle.operator.DefaultSignatureAlgorithmIdentifierFinder;
import org.bouncycastle.operator.OperatorCreationException;
import org.bouncycastle.operator.bc.BcDigestCalculatorProvider;
import org.bouncycastle.util.io.pem.PemObject;
import org.bouncycastle.util.io.pem.PemReader;
import org.codehaus.jackson.map.DeserializationConfig;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.SerializationConfig;
import org.openstack4j.openstack.identity.domain.KeystoneAccess;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.Collection;
import java.util.Date;

    public static SignerInformationVerifier createTokenVerifier(String aInSigningCertificate) throws IOException, OperatorCreationException
{
    // The cert is PEM encoded - need to translate those bytes into a PEM object
    Reader lCertBufferedReader = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(aInSigningCertificate.getBytes())));
    PemObject lPemObj = new PemReader(lCertBufferedReader).readPemObject();

    // Create our verify builder - basically we need to make an object that will verify the cert
    BcRSASignerInfoVerifierBuilder signerInfoBuilder = new BcRSASignerInfoVerifierBuilder(
            new DefaultCMSSignatureAlgorithmNameGenerator(),
            new DefaultSignatureAlgorithmIdentifierFinder(),
            new DefaultDigestAlgorithmIdentifierFinder(),
            new BcDigestCalculatorProvider());

    // Using the PEM object, create a cert holder and a verifier for the cert
    SignerInformationVerifier lVerifier = signerInfoBuilder.build(new X509CertificateHolder(lPemObj.getContent()));

    return lVerifier;
}

    public static CMSSignedData getSignedDataFromRawToken(String lRawKeystoneToken) throws CMSException
{
    // Keystone takes all '/' characters and replaced them by '-' in order to
    // encode the token into base 64. Let's reverse that..
    String lRealTokenData = lRawKeystoneToken.replace("-", "/");
    byte[] lData = Base64.decodeBase64(lRealTokenData.getBytes());

    // Now that we have the raw encoded token we can make a CMSSigned data out of it
    CMSSignedData lSignedData = new CMSSignedData(lData);
    return lSignedData;
}

    public static String getTokenContentAsString(CMSSignedData aInSignedData)
{
    Object lObj = aInSignedData.getSignedContent().getContent();
    if (lObj instanceof byte[])
    {
        String lObjString = new String((byte[]) lObj);
        return lObjString;
    }
    return null;
}

    public static boolean isValidTokenSignature(CMSSignedData aInSignedData, SignerInformationVerifier aInVerifier) throws CMSException
{
    // The token contained the signer Info and has been parsed out
    // For each signer on the token, attempt to verify against the certificate
    SignerInformationStore lSignerInfo = aInSignedData.getSignerInfos();
    Collection lSigners = lSignerInfo.getSigners();
    for (Object lObj : lSigners)
    {
        if (lObj instanceof SignerInformation)
        {
            SignerInformation lSigner = (SignerInformation) lObj;
            boolean lIsValid = lSigner.verify(aInVerifier);
            if (lIsValid)
            {
                return true;
            }
        }
    }
    return false;
}


    // Pki client is a just a class that requests cert info from Keystone
    PkiClient lPki = new PkiClient(lConfig);
    String lCaCert = lPki.getCaCertificate();
    String lSigningCert ...
(more)
edit flag offensive delete link more

Comments

Great! I am glad it is working for you! Do you have more question? If not, you can mark the question as solve and to the interweb archives it will go!

SamYaple gravatar imageSamYaple ( 2014-08-13 09:27:13 -0500 )edit

Get to know Ask OpenStack

Resources for moderators

Question Tools

1 follower

Stats

Asked: 2014-08-12 14:08:09 -0500

Seen: 857 times

Last updated: Aug 13 '14