The Crystal programming language | http://crystal-lang.org | Fund Crystal's development: http://is.gd/X7PRtI | Docs: http://crystal-lang.org/docs/ | API: http://crystal-lang.org/api/
I am trying to verify google/AWS jwts using their public keys but not succeeding. Would anyone know how to do so?
For eg.
the google sign ins key is at;
pp! pub_key_jwk = HTTP::Client.get "https://www.googleapis.com/oauth2/v3/certs"
pp! pub_key_pem = HTTP::Client.get "https://www.googleapis.com/oauth2/v1/certs"
and I would want to decode like this;payload, header = JWT.decode(token, pub_key_pem , JWT::Algorithm::HS256)
But I couldn't find a way to do this using https://github.com/crystal-community/jwt#usage
@jhass:m.aeshna.de , I did try to extract the keys and then use it in JWT decode, but that didn't work;
# Fetch the Google public key
pp! pub_key_jwk = HTTP::Client.get "https://www.googleapis.com/oauth2/v3/certs"
pp! pub_key_pem = HTTP::Client.get "https://www.googleapis.com/oauth2/v1/certs"
# pub_key.status_code # => 200
pp! parsed = JSON.parse(pub_key_jwk.body)
pp! key1 = parsed["keys"][0]["kid"].to_s
pp! key2 = parsed["keys"][1]["kid"].to_s
payload1, header1 = JWT.decode(id_token, key1, JWT::Algorithm::RS256)
pp! payload1
pp! header1
would throw;
2021-07-05T09:51:34.441087Z ERROR - Neither PUB or PRIV key: error:0D06B08E:asn1 encoding routines:asn1_d2i_read_bio:not enough data
Neither PUB or PRIV key: error:0D06B08E:asn1 encoding routines:asn1_d2i_read_bio:not enough data (OpenSSL::PKey::RsaError)
Is this bit of string
"-----BEGIN CERTIFICATE-----\nMIIDJjCCAg6gAwIBAgIIRAoQks63w4EwDQYJKoZIhvcNAQEFBQAwNjE0MDIGA1UE\nAxMrZmVkZXJhdGVkLXNpZ25vbi5zeXN0ZW0uZ3NlcnZpY2VhY2NvdW50LmNvbTAe\nFw0yMTA2MjAwNDI5NTdaFw0yMTA3MDYxNjQ0NTdaMDYxNDAyBgNVBAMTK2ZlZGVy\nYXRlZC1zaWdub24uc3lzdGVtLmdzZXJ2aWNlYWNjb3VudC5jb20wggEiMA0GCSqG\nSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCsf17gul45G1GRC6jm8ov5yws+cmbJZT+o\neI6pbJdWyg/KZQoiY2w+Vps5y+RhiU9+VYT6qa1AIf4AIOPHMKHIiS2v7nN4IRmJ\n2WfylYSYOr5H5peL+xCAlSv7sf9jr2EPxxHQrcvILzpBFumKDFbwXqFRT1qP/1Va\n5XCwy8uJCdtvNLgJa+L9bMhb2IbSA62GyyV99r/quqhCkdzQZ+wS7d73vVBlwnIz\nGvqm1j9u9PAhirBG/2m3G0pMyqi9XpgE3mf8uEIOaTWAEuZJ6PqZ8dJbaKjpNdlp\nXc9rIvZRO17qqu8CQX9FdS1V64PGbixxR7VF1/5N2wBcWbUo82rjAgMBAAGjODA2\nMAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgeAMBYGA1UdJQEB/wQMMAoGCCsG\nAQUFBwMCMA0GCSqGSIb3DQEBBQUAA4IBAQCGOTPITDKeIsTJhueXYtp9t3u0L8Id\nO58xb5dDbNGbi9E/C0cdDq8SfdFBHvOL8eJJSjzCRefRi1NhMlWaWsT471GgXdUV\nHR0CSV87Gj6BvMcAq9WFQu9k6LFtN2qp8CsFFEbjgPW3GFSXriy0W/VRzmb4aUbz\nVjo+EOTAiQP05qQ0bahaXWxXyftctMqpmM/EjFKZZwSH2fuFRNiq+0prIG8xRUYp\nakyr4D+GC0RrUpCa2SfGoojSYQPlQfkZGyeGLBi1UQImCKBJ8wYVaSIaVlLHYZik\nu/lQUGTPW3NLCn0id4AKAx3Ojf0t2jhsPy9u7kW5mPQA/CeRWjsPZ2uX\n-----END CERTIFICATE-----\n"
what I need in my JWT.decode(id_token, key_pem, JWT::Algorithm::RS256)
?
More with the raspberry pi compiling. So I'm clear: I need the current crystal version to compile the current crystal? I user the Portalier 0.33.0 and it compiled 0.33.0 but not 0.36.1. I got an error
In src/number.cr:147:67
147 | def step(*, to limit = nil, by step, exclusive : Bool = false, &) : Nil
^
Error: duplicated argument name:
make: *** [Makefile:122: .build/crystal] Error 1
The same happened when trying to compile 1.0.0.
Thanks
Unhandled exception in spawn: Error writing to socket: Broken pipe (IO::Error)
from /home/jonathan/.asdf/installs/crystal/1.0.0/share/crystal/src/io/evented.cr:82:13 in 'unbuffered_write'
from /home/jonathan/.asdf/installs/crystal/1.0.0/share/crystal/src/io/buffered.cr:217:5 in 'flush'
from /home/jonathan/.asdf/installs/crystal/1.0.0/share/crystal/src/http/web_socket/protocol.cr:106:5 in 'send'
from /home/jonathan/.asdf/installs/crystal/1.0.0/share/crystal/src/http/web_socket/protocol.cr:103:3 in 'send'
from /home/jonathan/.asdf/installs/crystal/1.0.0/share/crystal/src/http/web_socket/protocol.cr:90:5 in 'send'
from /home/jonathan/.asdf/installs/crystal/1.0.0/share/crystal/src/http/web_socket.cr:78:5 in 'send'
from lib/amber/src/amber/websockets/channel.cr:80:34 in 'rebroadcast!'
from src/channels/text_channel.cr:18:5 in 'handle_message'
from lib/amber/src/amber/websockets/channel.cr:49:9 in 'on_message'
from lib/amber/src/amber/websockets/channel.cr:88:13 in '->'
from /home/jonathan/.asdf/installs/crystal/1.0.0/share/crystal/src/primitives.cr:255:3 in '->'
from /home/jonathan/.asdf/installs/crystal/1.0.0/share/crystal/src/primitives.cr:255:3 in 'dispatch_received_message'
from lib/redis/src/redis/strategy/subscription_loop.cr:34:17 in 'enter_message_reception_loop'
from lib/redis/src/redis/strategy/subscription_loop.cr:19:7 in 'command'
from lib/redis/src/redis.cr:311:7 in 'command'
from lib/redis/src/redis/command_execution/value_oriented.cr:81:9 in 'void_command'
from lib/redis/src/redis/commands.cr:1675:7 in 'subscribe'
from lib/redis/src/redis/commands.cr:1665:7 in 'subscribe'
from lib/amber/src/amber/websockets/adapters/redis.cr:24:11 in '->'
from /home/jonathan/.asdf/installs/crystal/1.0.0/share/crystal/src/primitives.cr:255:3 in 'run'
from /home/jonathan/.asdf/installs/crystal/1.0.0/share/crystal/src/fiber.cr:92:34 in '->'
from ???
module Amber::WebSockets::Adapters
# Allows websocket connections through redis pub/sub.
class RedisAdapter
@subscriber : Redis
@publisher : Redis
@listener : Hash(String,Proc(String, JSON::Any, Nil)) = Hash(String, Proc(String, JSON::Any, Nil)).new
@subscribed : Bool = false
def self.instance
@@instance ||= new
end
# Establish subscribe and publish connections to Redis
def initialize
@subscriber = Redis.new(url: Amber.settings.redis_url)
@publisher = Redis.new(url: Amber.settings.redis_url)
if !@subscribed == true
spawn do
Fiber.yield
puts "subscribing to #{CHANNEL_TOPIC_PATHS}"
@subscribed = true
@subscriber.subscribe(CHANNEL_TOPIC_PATHS) do |on|
on.message do |_, m|
msg = JSON.parse(m)
sender_id = msg["sender"].as_s
message = msg["msg"]
topic = message["topic"].to_s.split(":").first
@listener[topic].call(sender_id, message)
end
on.subscribe do |_, _|
puts "subscribed to #{CHANNEL_TOPIC_PATHS}"
end
spawn do
Fiber.yield
to_subscribe = SUBSCRIBE_CHANNEL.receive
@subscriber.subscribe(to_subscribe)
end
end
end
end
end
# Publish the *message* to the redis publisher with topic *topic_path*
def publish(topic_path, client_socket, message)
@publisher.publish(topic_path, {sender: client_socket.id, msg: message}.to_json)
end
# Register listener with topic path after one-time subscribe on initialization
# So that it will be called when Redis pushes data to the subscription channel
def on_message(topic_path, listener)
@listener[topic_path] = listener
SUBSCRIBE_CHANNEL.send(topic_path)
end
end
end
Unhandled exception in spawn: Error writing to socket: Broken pipe (IO::Error)
from /home/jonathan/.asdf/installs/crystal/1.0.0/share/crystal/src/io/evented.cr:82:13 in 'unbuffered_write'
from /home/jonathan/.asdf/installs/crystal/1.0.0/share/crystal/src/io/buffered.cr:217:5 in 'flush'
from /home/jonathan/.asdf/installs/crystal/1.0.0/share/crystal/src/http/web_socket/protocol.cr:106:5 in 'send'
from /home/jonathan/.asdf/installs/crystal/1.0.0/share/crystal/src/http/web_socket/protocol.cr:103:3 in 'send'
from /home/jonathan/.asdf/installs/crystal/1.0.0/share/crystal/src/http/web_socket/protocol.cr:257:5 in 'close'
from /home/jonathan/.asdf/installs/crystal/1.0.0/share/crystal/src/http/web_socket.cr:111:5 in 'close'
from lib/amber/src/amber/websockets/client_socket.cr:111:9 in 'disconnect!'
from lib/amber/src/amber/websockets/client_socket.cr:102:9 in 'beat'
from lib/amber/src/amber/websockets/client_sockets.cr:17:13 in '->'
from /home/jonathan/.asdf/installs/crystal/1.0.0/share/crystal/src/primitives.cr:255:3 in 'run'
from /home/jonathan/.asdf/installs/crystal/1.0.0/share/crystal/src/fiber.cr:92:34 in '->'
from ???
Spec
that has equivalent functionality. Did I miss something, or is there a shard that does this?