Class: WebPush::VapidKey

Inherits:
Object
  • Object
show all
Defined in:
lib/web_push/vapid_key.rb

Overview

Class for abstracting the generation and encoding of elliptic curve public and private keys for use with the VAPID protocol

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(pkey = nil) ⇒ VapidKey

Returns a new instance of VapidKey.



26
27
28
29
# File 'lib/web_push/vapid_key.rb', line 26

def initialize(pkey = nil)
  @curve = pkey
  @curve = OpenSSL::PKey::EC.generate('prime256v1') if @curve.nil?
end

Instance Attribute Details

#:curveOpenSSL::PKey::EC (readonly)

the OpenSSL elliptic curve instance

Returns:

  • (OpenSSL::PKey::EC)

    the current value of :curve



7
8
9
# File 'lib/web_push/vapid_key.rb', line 7

def :curve
  @:curve
end

#curveObject (readonly)

Returns the value of attribute curve.



24
25
26
# File 'lib/web_push/vapid_key.rb', line 24

def curve
  @curve
end

Class Method Details

.from_keys(public_key, private_key) ⇒ WebPush::VapidKey

Create a VapidKey instance from encoded elliptic curve public and private keys

Returns:



11
12
13
14
15
# File 'lib/web_push/vapid_key.rb', line 11

def self.from_keys(public_key, private_key)
  key = new
  key.set_keys! public_key, private_key
  key
end

.from_pem(pem) ⇒ WebPush::VapidKey

Create a VapidKey instance from pem encoded elliptic curve public and private keys

Returns:



20
21
22
# File 'lib/web_push/vapid_key.rb', line 20

def self.from_pem(pem)
  new(OpenSSL::PKey.read(pem))
end

Instance Method Details

#curve_nameObject



86
87
88
# File 'lib/web_push/vapid_key.rb', line 86

def curve_name
  group.curve_name
end

#groupObject



90
91
92
# File 'lib/web_push/vapid_key.rb', line 90

def group
  curve.group
end

#inspectObject



111
112
113
# File 'lib/web_push/vapid_key.rb', line 111

def inspect
  "#<#{self.class}:#{object_id.to_s(16)} #{to_h.map { |k, v| ":#{k}=#{v}" }.join(' ')}>"
end

#private_keyString

Retrive the encoded elliptic curve private key for VAPID protocol

Returns:

  • (String)

    base64 urlsafe-encoded binary representation of 32-byte VAPID private key



48
49
50
# File 'lib/web_push/vapid_key.rb', line 48

def private_key
  encode64(curve.private_key.to_s(2))
end

#private_key=(key) ⇒ Object



56
57
58
# File 'lib/web_push/vapid_key.rb', line 56

def private_key=(key)
  set_keys! nil, key
end

#private_key_to_pemObject



103
104
105
# File 'lib/web_push/vapid_key.rb', line 103

def private_key_to_pem
  curve.to_pem
end

#public_keyString

Retrieve the encoded elliptic curve public key for VAPID protocol

Returns:

  • (String)

    encoded binary representation of 65-byte VAPID public key



34
35
36
# File 'lib/web_push/vapid_key.rb', line 34

def public_key
  encode64(curve.public_key.to_bn.to_s(2))
end

#public_key=(key) ⇒ Object



52
53
54
# File 'lib/web_push/vapid_key.rb', line 52

def public_key=(key)
  set_keys! key, nil
end

#public_key_for_push_headerString

Retrieve the encoded elliptic curve public key suitable for the Web Push request

Returns:

  • (String)

    the encoded VAPID public key for us in ‘Encryption’ header



41
42
43
# File 'lib/web_push/vapid_key.rb', line 41

def public_key_for_push_header
  trim_encode64(curve.public_key.to_bn.to_s(2))
end

#public_key_to_pemObject



107
108
109
# File 'lib/web_push/vapid_key.rb', line 107

def public_key_to_pem
  curve.public_to_pem
end

#set_keys!(public_key = nil, private_key = nil) ⇒ Object



60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/web_push/vapid_key.rb', line 60

def set_keys!(public_key = nil, private_key = nil)
  if public_key.nil?
    public_key = curve.public_key
  else
    public_key = OpenSSL::PKey::EC::Point.new(group, to_big_num(public_key))
  end

  if private_key.nil?
    private_key = curve.private_key
  else
    private_key = to_big_num(private_key)
  end

  asn1 = OpenSSL::ASN1::Sequence([
    OpenSSL::ASN1::Integer.new(1),
    # Not properly padded but OpenSSL doesn't mind
    OpenSSL::ASN1::OctetString(private_key.to_s(2)),
    OpenSSL::ASN1::ObjectId('prime256v1', 0, :EXPLICIT),
    OpenSSL::ASN1::BitString(public_key.to_octet_string(:uncompressed), 1, :EXPLICIT),
  ])

  der = asn1.to_der

  @curve = OpenSSL::PKey::EC.new(der)
end

#to_hObject Also known as: to_hash



94
95
96
# File 'lib/web_push/vapid_key.rb', line 94

def to_h
  { public_key: public_key, private_key: private_key }
end

#to_pemObject



99
100
101
# File 'lib/web_push/vapid_key.rb', line 99

def to_pem
  private_key_to_pem + public_key_to_pem
end