Class: Salmon::SalmonSlap
- Inherits:
-
Object
- Object
- Salmon::SalmonSlap
- Defined in:
- lib/salmon/salmon.rb
Instance Attribute Summary (collapse)
-
- (Object) aes_key
Returns the value of attribute aes_key.
-
- (Object) author
Returns the value of attribute author.
-
- (Object) author_email
Returns the value of attribute author_email.
-
- (Object) data_type
Returns the value of attribute data_type.
-
- (Object) iv
Returns the value of attribute iv.
-
- (Object) magic_sig
Returns the value of attribute magic_sig.
-
- (Object) parsed_data
Returns the value of attribute parsed_data.
-
- (Object) sig
Returns the value of attribute sig.
Class Method Summary (collapse)
-
+ (Object) b64_to_n(str)
Decode a string containing URL safe Base64 into an integer Example:.
-
+ (Object) build_key(n, e)
Take two integers e, n and create a new OpenSSL::PKey::RSA key with them Example:.
- + (Object) create(user, activity)
-
+ (Object) decode64url(str)
Decode URL-safe-Base64.
- + (Object) parse(xml, user)
-
+ (Object) parse_key(str)
Parse a string containing a magic-public-key into an OpenSSL::PKey::RSA key.
Instance Method Summary (collapse)
- - (Object) decrypted_header
-
- (Boolean) verified_for_key?(public_key)
Check whether this envelope’s signature can be verified with the provided OpenSSL::PKey::RSA public_key.
- - (Object) xml_for(person)
Instance Attribute Details
- (Object) aes_key
Returns the value of attribute aes_key
44 45 46 |
# File 'lib/salmon/salmon.rb', line 44 def aes_key @aes_key end |
- (Object) author
Returns the value of attribute author
44 45 46 47 48 49 50 |
# File 'lib/salmon/salmon.rb', line 44 def if .nil? ||= Person.by_account_identifier raise "did you remember to async webfinger?" if .nil? end end |
- (Object) author_email
Returns the value of attribute author_email
44 45 46 |
# File 'lib/salmon/salmon.rb', line 44 def end |
- (Object) data_type
Returns the value of attribute data_type
44 45 46 |
# File 'lib/salmon/salmon.rb', line 44 def data_type @data_type end |
- (Object) iv
Returns the value of attribute iv
44 45 46 |
# File 'lib/salmon/salmon.rb', line 44 def iv @iv end |
- (Object) magic_sig
Returns the value of attribute magic_sig
44 45 46 |
# File 'lib/salmon/salmon.rb', line 44 def magic_sig @magic_sig end |
- (Object) parsed_data
Returns the value of attribute parsed_data
44 45 46 |
# File 'lib/salmon/salmon.rb', line 44 def parsed_data @parsed_data end |
- (Object) sig
Returns the value of attribute sig
44 45 46 |
# File 'lib/salmon/salmon.rb', line 44 def sig @sig end |
Class Method Details
+ (Object) b64_to_n(str)
Decode a string containing URL safe Base64 into an integer Example:
MagicSig.b64_to_n('AQAB') # -> 645537
153 154 155 156 |
# File 'lib/salmon/salmon.rb', line 153 def self.b64_to_n(str) packed = decode64url(str) packed.unpack('B*')[0].to_i(2) end |
+ (Object) build_key(n, e)
Take two integers e, n and create a new OpenSSL::PKey::RSA key with them Example:
n = 9487834027867356975347184933768917275269369900665861930617802608089634337052392076689226301419587057117740995382286148368168197915234368486155306558161867 e = 65537 key = MagicSig.build_key(n,e) key.public_encrypt(...) # for sending to strangers key.public_decrypt(...) # very rarely used key.verify(...) # for verifying signatures
180 181 182 183 184 185 |
# File 'lib/salmon/salmon.rb', line 180 def self.build_key(n,e) key = OpenSSL::PKey::RSA.new key.n = n key.e = e key end |
+ (Object) create(user, activity)
47 48 49 50 51 52 53 54 55 |
# File 'lib/salmon/salmon.rb', line 47 def self.create(user, activity) salmon = self.new salmon. = user.person aes_key_hash = user.person.gen_aes_key salmon.aes_key = aes_key_hash['key'] salmon.iv = aes_key_hash['iv'] salmon.magic_sig = MagicSigEnvelope.create(user , user.person.aes_encrypt(activity, aes_key_hash)) salmon end |
+ (Object) decode64url(str)
Decode URL-safe-Base64. This implements
123 124 125 126 127 128 129 130 131 132 133 |
# File 'lib/salmon/salmon.rb', line 123 def self.decode64url(str) # remove whitespace sans_whitespace = str.gsub(/\s/, '') # pad to a multiple of 4 string = sans_whitespace + '=' * ((4 - sans_whitespace.size) % 4) # convert to standard Base64 # string = padded.tr('-','+').tr('_','/') # Base64.decode64(string) Base64.urlsafe_decode64 string end |
+ (Object) parse(xml, user)
57 58 59 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 85 86 |
# File 'lib/salmon/salmon.rb', line 57 def self.parse(xml, user) slap = self.new doc = Nokogiri::XML(xml) sig_doc = doc.search('entry') ### Header ## decrypted_header = user.decrypt(doc.search('encrypted_header').text) header_doc = Nokogiri::XML(decrypted_header) slap.= header_doc.search('uri').text.split("acct:").last slap.aes_key = header_doc.search('aes_key').text slap.iv = header_doc.search('iv').text slap.magic_sig = MagicSigEnvelope.parse sig_doc if 'base64url' == slap.magic_sig.encoding key_hash = {'key' => slap.aes_key, 'iv' => slap.iv} slap.parsed_data = user.aes_decrypt(decode64url(slap.magic_sig.data), key_hash) slap.sig = slap.magic_sig.sig else raise ArgumentError, "Magic Signature data must be encoded with base64url, was #{slap.magic_sig.encoding}" end slap.data_type = slap.magic_sig.data_type raise ArgumentError, "Magic Signature data must be signed with RSA-SHA256, was #{slap.magic_sig.alg}" unless 'RSA-SHA256' == slap.magic_sig.alg slap end |
+ (Object) parse_key(str)
Parse a string containing a magic-public-key into an OpenSSL::PKey::RSA key. Example:
key = MagicSig.parse_key('RSA.mVgY8RN6URBTstndvmUUPb4UZTdwvwmddSKE5z_jvKUEK6yk1u3rrC9yN8k6FilGj9K0eeUPe2hf4Pj-5CmHww.AQAB') key.n # -> 8031283789075196565022891546563591368344944062154100509645398892293433370859891943306439907454883747534493461257620351548796452092307094036643522661681091 key.e # -> 65537
166 167 168 169 |
# File 'lib/salmon/salmon.rb', line 166 def self.parse_key(str) n,e = str.match(/^RSA.([^.]*).([^.]*)$/)[1..2] build_key(b64_to_n(n),b64_to_n(e)) end |
Instance Method Details
- (Object) decrypted_header
100 101 102 |
# File 'lib/salmon/salmon.rb', line 100 def decrypted_header header =" <decrypted_header>\n <iv>\#{iv}</iv>\n <aes_key>\#{aes_key}</aes_key>\n <author>\n <name>\#{@author.name}</name>\n <uri>acct:\#{@author.diaspora_handle}</uri>\n </author>\n </decrypted_header>\n" end |
- (Boolean) verified_for_key?(public_key)
Check whether this envelope’s signature can be verified with the provided OpenSSL::PKey::RSA public_key. Example:
env.verified_for_key? OpenSSL::PKey::RSA.new(File.open('public_key.pem')) # -> true
141 142 143 144 145 146 |
# File 'lib/salmon/salmon.rb', line 141 def verified_for_key?(public_key) signature = Base64.urlsafe_decode64(self.magic_sig.sig) signed_data = self.magic_sig.signable_string# Base64.urlsafe_decode64(self.magic_sig.signable_string) public_key.verify(OpenSSL::Digest::SHA256.new, signature, signed_data ) end |
- (Object) xml_for(person)
88 89 90 91 |
# File 'lib/salmon/salmon.rb', line 88 def xml_for person xml =" <?xml version='1.0' encoding='UTF-8'?>\n <entry xmlns='http://www.w3.org/2005/Atom'>\n <encrypted_header>\#{person.encrypt(decrypted_header)}</encrypted_header>\n \#{@magic_sig.to_xml}\n </entry>\n" end |