Class: DiasporaFederation::Salmon::EncryptedSlap Deprecated

Inherits:
Slap
  • Object
show all
Defined in:
lib/diaspora_federation/salmon/encrypted_slap.rb

Overview

Deprecated.

EncryptedSlap provides class methods for generating and parsing encrypted Slaps. (In principle the same as Slap, but with encryption.)

The basic encryption mechanism used here is based on the knowledge that asymmetrical encryption is slow and symmetrical encryption is fast. Keeping in mind that a message we want to de-/encrypt may greatly vary in length, performance considerations must play a part of this scheme.

A diaspora*-flavored encrypted magic-enveloped XML message looks like the following:

<?xml version="1.0" encoding="UTF-8"?>
<diaspora xmlns="https://joindiaspora.com/protocol" xmlns:me="http://salmon-protocol.org/ns/magic-env">
  <encrypted_header>{encrypted_header}</encrypted_header>
  {magic_envelope with encrypted data}
</diaspora>

The encrypted header is encoded in JSON like this (when in plain text):

{
  "aes_key"    => "...",
  "ciphertext" => "..."
}

aes_key is encrypted using the recipients public key, and contains the AES key and iv used to encrypt the ciphertext also encoded as JSON.

{
  "key" => "...",
  "iv"  => "..."
}

ciphertext, once decrypted, contains the author_id, aes_key and iv relevant to the decryption of the data in the magic_envelope and the verification of its signature.

The decrypted cyphertext has this XML structure:

<decrypted_header>
  <iv>{iv}</iv>
  <aes_key>{aes_key}</aes_key>
  <author_id>{author_id}</author_id>
</decrypted_header>

Finally, before decrypting the magic envelope payload, the signature should first be verified.

Examples:

Parsing a Salmon Slap

recipient_privkey = however_you_retrieve_the_recipients_private_key()
entity = EncryptedSlap.from_xml(slap_xml, recipient_privkey).payload

Constant Summary

Constants inherited from Slap

Slap::NS

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.from_xml(slap_xml, privkey) ⇒ MagicEnvelope

Creates a MagicEnvelope instance from the data within the given XML string containing an encrypted payload.

Parameters:

  • slap_xml (String)

    encrypted Salmon xml

  • privkey (OpenSSL::PKey::RSA)

    recipient private_key for decryption

Returns:

  • (MagicEnvelope)

    magic envelope instance with payload and sender

Raises:

  • (ArgumentError)

    if any of the arguments is of the wrong type

  • (MissingHeader)

    if the encrypted_header element is missing in the XML

  • (MissingMagicEnvelope)

    if the me:env element is missing in the XML



68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/diaspora_federation/salmon/encrypted_slap.rb', line 68

def self.from_xml(slap_xml, privkey)
  raise ArgumentError unless slap_xml.instance_of?(String) && privkey.instance_of?(OpenSSL::PKey::RSA)
  doc = Nokogiri::XML(slap_xml)

  header_elem = doc.at_xpath("d:diaspora/d:encrypted_header", Slap::NS)
  raise MissingHeader if header_elem.nil?
  header = header_data(header_elem.content, privkey)
  sender = header[:author_id]
  cipher_params = {key: Base64.decode64(header[:aes_key]), iv: Base64.decode64(header[:iv])}

  MagicEnvelope.unenvelop(magic_env_from_doc(doc), sender, cipher_params)
end

Instance Method Details

#selfNokogiri::XML::Element

Decrypts the xml header

Parameters:

  • data (String)

    base64 encoded, encrypted header data

  • privkey (OpenSSL::PKey::RSA)

    private key for decryption

Returns:

  • (Nokogiri::XML::Element)

    header xml document



85
86
87
88
89
90
91
92
93
94
# File 'lib/diaspora_federation/salmon/encrypted_slap.rb', line 85

private_class_method def self.header_data(data, privkey)
  header_elem = decrypt_header(data, privkey)
  raise InvalidHeader unless header_elem.name == "decrypted_header"

  iv = header_elem.at_xpath("iv").content
  key = header_elem.at_xpath("aes_key").content
  author_id = header_elem.at_xpath("author_id").content

  {iv: iv, aes_key: key, author_id: author_id}
end