Class: OmniAuth::Atproto::KeyManager

Inherits:
Object
  • Object
show all
Defined in:
lib/omniauth-atproto/key_manager.rb

Constant Summary collapse

KEY_PATH =
'config/atproto_private_key.pem'
JWK_PATH =
'config/atproto_jwk.json'

Class Method Summary collapse

Class Method Details

.current_jwkObject



44
45
46
# File 'lib/omniauth-atproto/key_manager.rb', line 44

def current_jwk
  @current_jwk ||= load_or_generate_keys.last
end

.current_private_keyObject



40
41
42
# File 'lib/omniauth-atproto/key_manager.rb', line 40

def current_private_key
  @current_private_key ||= load_or_generate_keys.first
end

.generate_key_pairObject



12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/omniauth-atproto/key_manager.rb', line 12

def generate_key_pair
  key = OpenSSL::PKey::EC.generate('prime256v1')
  private_key = key
  public_key = key.public_key

  # Get the coordinates for JWK
  # (not easy with openssl 3)
  bn = public_key.to_bn(:uncompressed)
  raw_bytes = bn.to_s(2)
  coord_bytes = raw_bytes[1..]
  byte_length = coord_bytes.length / 2

  x_coord = coord_bytes[0, byte_length]
  y_coord = coord_bytes[byte_length, byte_length]

  jwk = {
    kty: 'EC',
    crv: 'P-256',
    x: Base64.urlsafe_encode64(x_coord, padding: false),
    y: Base64.urlsafe_encode64(y_coord, padding: false),
    use: 'sig',
    alg: 'ES256',
    kid: SecureRandom.uuid
  }.freeze

  [private_key, jwk]
end

.rotate_keysObject



48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/omniauth-atproto/key_manager.rb', line 48

def rotate_keys
  # Backup current keys if they exist
  if File.exist?(KEY_PATH)
    File.write(KEY_PATH, 'config/old_atproto_private_key.pem')
    FileUtils.rm(KEY_PATH)
  end
  if File.exist?(JWK_PATH)
    File.write(JWK_PATH, 'config/old_atproto_jwk.json')
    FileUtils.rm(JWK_PATH)
  end
  load_or_generate_keys
end