rename 'pkey' to 'privkey' and 'pubkey'
This commit is contained in:
parent
d852144f3c
commit
c7f33d7cf4
13 changed files with 104 additions and 111 deletions
|
|
@ -59,10 +59,10 @@ module DiasporaFederation
|
||||||
# @param [Hash] data hash with data to verify
|
# @param [Hash] data hash with data to verify
|
||||||
# @raise [SignatureVerificationFailed] if the signature is not valid or no public key is found
|
# @raise [SignatureVerificationFailed] if the signature is not valid or no public key is found
|
||||||
def self.verify_signatures(data, klass)
|
def self.verify_signatures(data, klass)
|
||||||
pkey = DiasporaFederation.callbacks.trigger(:fetch_public_key_by_diaspora_id, data[:diaspora_id])
|
pubkey = DiasporaFederation.callbacks.trigger(:fetch_public_key_by_diaspora_id, data[:diaspora_id])
|
||||||
raise SignatureVerificationFailed, "failed to fetch public key for #{data[:diaspora_id]}" if pkey.nil?
|
raise SignatureVerificationFailed, "failed to fetch public key for #{data[:diaspora_id]}" if pubkey.nil?
|
||||||
raise SignatureVerificationFailed, "wrong author_signature" unless Signing.verify_signature(
|
raise SignatureVerificationFailed, "wrong author_signature" unless Signing.verify_signature(
|
||||||
data, data[:author_signature], pkey
|
data, data[:author_signature], pubkey
|
||||||
)
|
)
|
||||||
|
|
||||||
author_is_local = DiasporaFederation.callbacks.trigger(
|
author_is_local = DiasporaFederation.callbacks.trigger(
|
||||||
|
|
@ -76,15 +76,15 @@ module DiasporaFederation
|
||||||
# this happens only on downstream federation
|
# this happens only on downstream federation
|
||||||
# @param [Hash] data hash with data to verify
|
# @param [Hash] data hash with data to verify
|
||||||
def self.verify_parent_signature(data, klass)
|
def self.verify_parent_signature(data, klass)
|
||||||
pkey = DiasporaFederation.callbacks.trigger(
|
pubkey = DiasporaFederation.callbacks.trigger(
|
||||||
:fetch_author_public_key_by_entity_guid,
|
:fetch_author_public_key_by_entity_guid,
|
||||||
klass.get_target_entity_type(data),
|
klass.get_target_entity_type(data),
|
||||||
data[:parent_guid]
|
data[:parent_guid]
|
||||||
)
|
)
|
||||||
raise SignatureVerificationFailed,
|
raise SignatureVerificationFailed,
|
||||||
"failed to fetch public key for author of #{data[:parent_guid]}" if pkey.nil?
|
"failed to fetch public key for author of #{data[:parent_guid]}" if pubkey.nil?
|
||||||
raise SignatureVerificationFailed, "wrong parent_author_signature" unless Signing.verify_signature(
|
raise SignatureVerificationFailed, "wrong parent_author_signature" unless Signing.verify_signature(
|
||||||
data, data[:parent_author_signature], pkey
|
data, data[:parent_author_signature], pubkey
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
private_class_method :verify_parent_signature
|
private_class_method :verify_parent_signature
|
||||||
|
|
@ -95,17 +95,17 @@ module DiasporaFederation
|
||||||
# @param [Hash] data hash given for a signing
|
# @param [Hash] data hash given for a signing
|
||||||
def self.update_signatures!(data, klass)
|
def self.update_signatures!(data, klass)
|
||||||
if data[:author_signature].nil?
|
if data[:author_signature].nil?
|
||||||
pkey = DiasporaFederation.callbacks.trigger(:fetch_private_key_by_diaspora_id, data[:diaspora_id])
|
privkey = DiasporaFederation.callbacks.trigger(:fetch_private_key_by_diaspora_id, data[:diaspora_id])
|
||||||
data[:author_signature] = Signing.sign_with_key(data, pkey) unless pkey.nil?
|
data[:author_signature] = Signing.sign_with_key(data, privkey) unless privkey.nil?
|
||||||
end
|
end
|
||||||
|
|
||||||
if data[:parent_author_signature].nil?
|
if data[:parent_author_signature].nil?
|
||||||
pkey = DiasporaFederation.callbacks.trigger(
|
privkey = DiasporaFederation.callbacks.trigger(
|
||||||
:fetch_author_private_key_by_entity_guid,
|
:fetch_author_private_key_by_entity_guid,
|
||||||
klass.get_target_entity_type(data),
|
klass.get_target_entity_type(data),
|
||||||
data[:parent_guid]
|
data[:parent_guid]
|
||||||
)
|
)
|
||||||
data[:parent_author_signature] = Signing.sign_with_key(data, pkey) unless pkey.nil?
|
data[:parent_author_signature] = Signing.sign_with_key(data, privkey) unless privkey.nil?
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -75,18 +75,21 @@ module DiasporaFederation
|
||||||
hash[:target_type],
|
hash[:target_type],
|
||||||
hash[:target_guid]
|
hash[:target_guid]
|
||||||
)
|
)
|
||||||
pkey = DiasporaFederation.callbacks.trigger(:fetch_private_key_by_diaspora_id, hash[:diaspora_id])
|
privkey = DiasporaFederation.callbacks.trigger(:fetch_private_key_by_diaspora_id, hash[:diaspora_id])
|
||||||
|
|
||||||
fill_required_signature(target_author, pkey, hash) unless pkey.nil?
|
fill_required_signature(target_author, privkey, hash) unless privkey.nil?
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.fill_required_signature(target_author, pkey, hash)
|
# @param [String] target_author the author of the entity to retract
|
||||||
|
# @param [OpenSSL::PKey::RSA] privkey private key of sender
|
||||||
|
# @param [Hash] hash hash given for a signing
|
||||||
|
def self.fill_required_signature(target_author, privkey, hash)
|
||||||
if target_author == hash[:diaspora_id] && hash[:target_author_signature].nil?
|
if target_author == hash[:diaspora_id] && hash[:target_author_signature].nil?
|
||||||
hash[:target_author_signature] =
|
hash[:target_author_signature] =
|
||||||
Signing.sign_with_key(SignedRetraction.apply_signable_exceptions(hash), pkey)
|
Signing.sign_with_key(SignedRetraction.apply_signable_exceptions(hash), privkey)
|
||||||
elsif target_author != hash[:diaspora_id] && hash[:parent_author_signature].nil?
|
elsif target_author != hash[:diaspora_id] && hash[:parent_author_signature].nil?
|
||||||
hash[:parent_author_signature] =
|
hash[:parent_author_signature] =
|
||||||
Signing.sign_with_key(SignedRetraction.apply_signable_exceptions(hash), pkey)
|
Signing.sign_with_key(SignedRetraction.apply_signable_exceptions(hash), privkey)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
private_class_method :fill_required_signature
|
private_class_method :fill_required_signature
|
||||||
|
|
|
||||||
|
|
@ -48,8 +48,10 @@ module DiasporaFederation
|
||||||
# @param [Hash] data hash given for a signing
|
# @param [Hash] data hash given for a signing
|
||||||
def self.update_signatures!(data)
|
def self.update_signatures!(data)
|
||||||
if data[:target_author_signature].nil?
|
if data[:target_author_signature].nil?
|
||||||
pkey = DiasporaFederation.callbacks.trigger(:fetch_private_key_by_diaspora_id, data[:diaspora_id])
|
privkey = DiasporaFederation.callbacks.trigger(:fetch_private_key_by_diaspora_id, data[:diaspora_id])
|
||||||
data[:target_author_signature] = Signing.sign_with_key(apply_signable_exceptions(data), pkey) unless pkey.nil?
|
unless privkey.nil?
|
||||||
|
data[:target_author_signature] = Signing.sign_with_key(apply_signable_exceptions(data), privkey)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -68,21 +68,21 @@ module DiasporaFederation
|
||||||
# containing an encrypted payload.
|
# containing an encrypted payload.
|
||||||
#
|
#
|
||||||
# @param [String] slap_xml encrypted Salmon xml
|
# @param [String] slap_xml encrypted Salmon xml
|
||||||
# @param [OpenSSL::PKey::RSA] pkey recipient private_key for decryption
|
# @param [OpenSSL::PKey::RSA] privkey recipient private_key for decryption
|
||||||
#
|
#
|
||||||
# @return [Slap] new Slap instance
|
# @return [Slap] new Slap instance
|
||||||
#
|
#
|
||||||
# @raise [ArgumentError] if any of the arguments is of the wrong type
|
# @raise [ArgumentError] if any of the arguments is of the wrong type
|
||||||
# @raise [MissingHeader] if the +encrypted_header+ element is missing in the XML
|
# @raise [MissingHeader] if the +encrypted_header+ element is missing in the XML
|
||||||
# @raise [MissingMagicEnvelope] if the +me:env+ element is missing in the XML
|
# @raise [MissingMagicEnvelope] if the +me:env+ element is missing in the XML
|
||||||
def self.from_xml(slap_xml, pkey)
|
def self.from_xml(slap_xml, privkey)
|
||||||
raise ArgumentError unless slap_xml.instance_of?(String) && pkey.instance_of?(OpenSSL::PKey::RSA)
|
raise ArgumentError unless slap_xml.instance_of?(String) && privkey.instance_of?(OpenSSL::PKey::RSA)
|
||||||
doc = Nokogiri::XML::Document.parse(slap_xml)
|
doc = Nokogiri::XML::Document.parse(slap_xml)
|
||||||
|
|
||||||
Slap.new.tap do |slap|
|
Slap.new.tap do |slap|
|
||||||
header_elem = doc.at_xpath("d:diaspora/d:encrypted_header", Slap::NS)
|
header_elem = doc.at_xpath("d:diaspora/d:encrypted_header", Slap::NS)
|
||||||
raise MissingHeader if header_elem.nil?
|
raise MissingHeader if header_elem.nil?
|
||||||
header = header_data(header_elem.content, pkey)
|
header = header_data(header_elem.content, privkey)
|
||||||
slap.author_id = header[:author_id]
|
slap.author_id = header[:author_id]
|
||||||
slap.cipher_params = {key: Base64.decode64(header[:aes_key]), iv: Base64.decode64(header[:iv])}
|
slap.cipher_params = {key: Base64.decode64(header[:aes_key]), iv: Base64.decode64(header[:iv])}
|
||||||
|
|
||||||
|
|
@ -93,19 +93,19 @@ module DiasporaFederation
|
||||||
# Creates an encrypted Salmon Slap and returns the XML string.
|
# Creates an encrypted Salmon Slap and returns the XML string.
|
||||||
#
|
#
|
||||||
# @param [String] author_id Diaspora* handle of the author
|
# @param [String] author_id Diaspora* handle of the author
|
||||||
# @param [OpenSSL::PKey::RSA] pkey sender private key for signing the magic envelope
|
# @param [OpenSSL::PKey::RSA] privkey sender private key for signing the magic envelope
|
||||||
# @param [Entity] entity payload
|
# @param [Entity] entity payload
|
||||||
# @param [OpenSSL::PKey::RSA] pubkey recipient public key for encrypting the AES key
|
# @param [OpenSSL::PKey::RSA] pubkey recipient public key for encrypting the AES key
|
||||||
# @return [String] Salmon XML string
|
# @return [String] Salmon XML string
|
||||||
# @raise [ArgumentError] if any of the arguments is of the wrong type
|
# @raise [ArgumentError] if any of the arguments is of the wrong type
|
||||||
def self.generate_xml(author_id, pkey, entity, pubkey)
|
def self.generate_xml(author_id, privkey, entity, pubkey)
|
||||||
raise ArgumentError unless author_id.instance_of?(String) &&
|
raise ArgumentError unless author_id.instance_of?(String) &&
|
||||||
pkey.instance_of?(OpenSSL::PKey::RSA) &&
|
privkey.instance_of?(OpenSSL::PKey::RSA) &&
|
||||||
entity.is_a?(Entity) &&
|
entity.is_a?(Entity) &&
|
||||||
pubkey.instance_of?(OpenSSL::PKey::RSA)
|
pubkey.instance_of?(OpenSSL::PKey::RSA)
|
||||||
|
|
||||||
Slap.build_xml do |xml|
|
Slap.build_xml do |xml|
|
||||||
magic_envelope = MagicEnvelope.new(pkey, entity)
|
magic_envelope = MagicEnvelope.new(privkey, entity)
|
||||||
envelope_key = magic_envelope.encrypt!
|
envelope_key = magic_envelope.encrypt!
|
||||||
|
|
||||||
encrypted_header(author_id, envelope_key, pubkey, xml)
|
encrypted_header(author_id, envelope_key, pubkey, xml)
|
||||||
|
|
@ -115,10 +115,10 @@ module DiasporaFederation
|
||||||
|
|
||||||
# decrypts and reads the data from the encrypted XML header
|
# decrypts and reads the data from the encrypted XML header
|
||||||
# @param [String] data base64 encoded, encrypted header data
|
# @param [String] data base64 encoded, encrypted header data
|
||||||
# @param [OpenSSL::PKey::RSA] pkey private key for decryption
|
# @param [OpenSSL::PKey::RSA] privkey private key for decryption
|
||||||
# @return [Hash] { iv: "...", aes_key: "...", author_id: "..." }
|
# @return [Hash] { iv: "...", aes_key: "...", author_id: "..." }
|
||||||
def self.header_data(data, pkey)
|
def self.header_data(data, privkey)
|
||||||
header_elem = decrypt_header(data, pkey)
|
header_elem = decrypt_header(data, privkey)
|
||||||
raise InvalidHeader unless header_elem.name == "decrypted_header"
|
raise InvalidHeader unless header_elem.name == "decrypted_header"
|
||||||
|
|
||||||
iv = header_elem.at_xpath("iv").content
|
iv = header_elem.at_xpath("iv").content
|
||||||
|
|
@ -131,11 +131,11 @@ module DiasporaFederation
|
||||||
|
|
||||||
# decrypts the xml header
|
# decrypts the xml header
|
||||||
# @param [String] data base64 encoded, encrypted header data
|
# @param [String] data base64 encoded, encrypted header data
|
||||||
# @param [OpenSSL::PKey::RSA] pkey private key for decryption
|
# @param [OpenSSL::PKey::RSA] privkey private key for decryption
|
||||||
# @return [Nokogiri::XML::Element] header xml document
|
# @return [Nokogiri::XML::Element] header xml document
|
||||||
def self.decrypt_header(data, pkey)
|
def self.decrypt_header(data, privkey)
|
||||||
cipher_header = JSON.parse(Base64.decode64(data))
|
cipher_header = JSON.parse(Base64.decode64(data))
|
||||||
key = JSON.parse(pkey.private_decrypt(Base64.decode64(cipher_header["aes_key"])))
|
key = JSON.parse(privkey.private_decrypt(Base64.decode64(cipher_header["aes_key"])))
|
||||||
|
|
||||||
xml = AES.decrypt(cipher_header["ciphertext"], Base64.decode64(key["key"]), Base64.decode64(key["iv"]))
|
xml = AES.decrypt(cipher_header["ciphertext"], Base64.decode64(key["key"]), Base64.decode64(key["iv"]))
|
||||||
Nokogiri::XML::Document.parse(xml).root
|
Nokogiri::XML::Document.parse(xml).root
|
||||||
|
|
|
||||||
|
|
@ -41,14 +41,14 @@ module DiasporaFederation
|
||||||
|
|
||||||
# Creates a new instance of MagicEnvelope.
|
# Creates a new instance of MagicEnvelope.
|
||||||
#
|
#
|
||||||
# @param [OpenSSL::PKey::RSA] rsa_pkey private key used for signing
|
# @param [OpenSSL::PKey::RSA] rsa_privkey private key used for signing
|
||||||
# @param [Entity] payload Entity instance
|
# @param [Entity] payload Entity instance
|
||||||
# @raise [ArgumentError] if either argument is not of the right type
|
# @raise [ArgumentError] if either argument is not of the right type
|
||||||
def initialize(rsa_pkey, payload)
|
def initialize(rsa_privkey, payload)
|
||||||
raise ArgumentError unless rsa_pkey.instance_of?(OpenSSL::PKey::RSA) &&
|
raise ArgumentError unless rsa_privkey.instance_of?(OpenSSL::PKey::RSA) &&
|
||||||
payload.is_a?(Entity)
|
payload.is_a?(Entity)
|
||||||
|
|
||||||
@rsa_pkey = rsa_pkey
|
@rsa_privkey = rsa_privkey
|
||||||
@payload = XmlPayload.pack(payload).to_xml.strip
|
@payload = XmlPayload.pack(payload).to_xml.strip
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -126,7 +126,7 @@ module DiasporaFederation
|
||||||
DATA_TYPE,
|
DATA_TYPE,
|
||||||
ENCODING,
|
ENCODING,
|
||||||
ALGORITHM])
|
ALGORITHM])
|
||||||
@rsa_pkey.sign(DIGEST, subject)
|
@rsa_privkey.sign(DIGEST, subject)
|
||||||
end
|
end
|
||||||
|
|
||||||
# @param [Nokogiri::XML::Element] env magic envelope XML
|
# @param [Nokogiri::XML::Element] env magic envelope XML
|
||||||
|
|
@ -141,16 +141,16 @@ module DiasporaFederation
|
||||||
private_class_method :envelope_valid?
|
private_class_method :envelope_valid?
|
||||||
|
|
||||||
# @param [Nokogiri::XML::Element] env magic envelope XML
|
# @param [Nokogiri::XML::Element] env magic envelope XML
|
||||||
# @param [OpenSSL::PKey::RSA] pkey public key
|
# @param [OpenSSL::PKey::RSA] pubkey public key
|
||||||
# @return [Boolean]
|
# @return [Boolean]
|
||||||
def self.signature_valid?(env, pkey)
|
def self.signature_valid?(env, pubkey)
|
||||||
subject = sig_subject([Base64.urlsafe_decode64(env.at_xpath("me:data").content),
|
subject = sig_subject([Base64.urlsafe_decode64(env.at_xpath("me:data").content),
|
||||||
env.at_xpath("me:data")["type"],
|
env.at_xpath("me:data")["type"],
|
||||||
env.at_xpath("me:encoding").content,
|
env.at_xpath("me:encoding").content,
|
||||||
env.at_xpath("me:alg").content])
|
env.at_xpath("me:alg").content])
|
||||||
|
|
||||||
sig = Base64.urlsafe_decode64(env.at_xpath("me:sig").content)
|
sig = Base64.urlsafe_decode64(env.at_xpath("me:sig").content)
|
||||||
pkey.verify(DIGEST, sig, subject)
|
pubkey.verify(DIGEST, sig, subject)
|
||||||
end
|
end
|
||||||
private_class_method :signature_valid?
|
private_class_method :signature_valid?
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -51,12 +51,9 @@ module DiasporaFederation
|
||||||
# @param [OpenSSL::PKey::RSA] pubkey public key for validating the signature
|
# @param [OpenSSL::PKey::RSA] pubkey public key for validating the signature
|
||||||
# @return [Entity] entity instance from the XML
|
# @return [Entity] entity instance from the XML
|
||||||
# @raise [ArgumentError] if the public key is of the wrong type
|
# @raise [ArgumentError] if the public key is of the wrong type
|
||||||
def entity(pubkey=nil)
|
def entity(pubkey)
|
||||||
return @entity unless @entity.nil?
|
|
||||||
|
|
||||||
raise ArgumentError unless pubkey.instance_of?(OpenSSL::PKey::RSA)
|
raise ArgumentError unless pubkey.instance_of?(OpenSSL::PKey::RSA)
|
||||||
@entity = MagicEnvelope.unenvelop(@magic_envelope, pubkey, @cipher_params)
|
MagicEnvelope.unenvelop(@magic_envelope, pubkey, @cipher_params)
|
||||||
@entity
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Parses an unencrypted Salmon XML string and returns a new instance of
|
# Parses an unencrypted Salmon XML string and returns a new instance of
|
||||||
|
|
@ -83,13 +80,13 @@ module DiasporaFederation
|
||||||
# Creates an unencrypted Salmon Slap and returns the XML string.
|
# Creates an unencrypted Salmon Slap and returns the XML string.
|
||||||
#
|
#
|
||||||
# @param [String] author_id Diaspora* handle of the author
|
# @param [String] author_id Diaspora* handle of the author
|
||||||
# @param [OpenSSL::PKey::RSA] pkey sender private_key for signing the magic envelope
|
# @param [OpenSSL::PKey::RSA] privkey sender private_key for signing the magic envelope
|
||||||
# @param [Entity] entity payload
|
# @param [Entity] entity payload
|
||||||
# @return [String] Salmon XML string
|
# @return [String] Salmon XML string
|
||||||
# @raise [ArgumentError] if any of the arguments is not the correct type
|
# @raise [ArgumentError] if any of the arguments is not the correct type
|
||||||
def self.generate_xml(author_id, pkey, entity)
|
def self.generate_xml(author_id, privkey, entity)
|
||||||
raise ArgumentError unless author_id.instance_of?(String) &&
|
raise ArgumentError unless author_id.instance_of?(String) &&
|
||||||
pkey.instance_of?(OpenSSL::PKey::RSA) &&
|
privkey.instance_of?(OpenSSL::PKey::RSA) &&
|
||||||
entity.is_a?(Entity)
|
entity.is_a?(Entity)
|
||||||
|
|
||||||
build_xml do |xml|
|
build_xml do |xml|
|
||||||
|
|
@ -97,7 +94,7 @@ module DiasporaFederation
|
||||||
xml.author_id(author_id)
|
xml.author_id(author_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
MagicEnvelope.new(pkey, entity).envelop(xml)
|
MagicEnvelope.new(privkey, entity).envelop(xml)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,11 +6,11 @@ module DiasporaFederation
|
||||||
# Sign the data with the key
|
# Sign the data with the key
|
||||||
#
|
#
|
||||||
# @param [Hash] hash data to sign
|
# @param [Hash] hash data to sign
|
||||||
# @param [OpenSSL::PKey::RSA] key An RSA key
|
# @param [OpenSSL::PKey::RSA] privkey An RSA key
|
||||||
# @return [String] A Base64 encoded signature of #signable_string with key
|
# @return [String] A Base64 encoded signature of #signable_string with key
|
||||||
def self.sign_with_key(hash, key)
|
def self.sign_with_key(hash, privkey)
|
||||||
sig = Base64.strict_encode64(
|
sig = Base64.strict_encode64(
|
||||||
key.sign(
|
privkey.sign(
|
||||||
OpenSSL::Digest::SHA256.new,
|
OpenSSL::Digest::SHA256.new,
|
||||||
signable_string(hash)
|
signable_string(hash)
|
||||||
)
|
)
|
||||||
|
|
@ -23,10 +23,10 @@ module DiasporaFederation
|
||||||
#
|
#
|
||||||
# @param [Hash] hash data to verify
|
# @param [Hash] hash data to verify
|
||||||
# @param [String] signature The signature to be verified.
|
# @param [String] signature The signature to be verified.
|
||||||
# @param [OpenSSL::PKey::RSA] key An RSA key
|
# @param [OpenSSL::PKey::RSA] pubkey An RSA key
|
||||||
# @return [Boolean]
|
# @return [Boolean]
|
||||||
def self.verify_signature(hash, signature, key)
|
def self.verify_signature(hash, signature, pubkey)
|
||||||
if key.nil?
|
if pubkey.nil?
|
||||||
logger.warn "event=verify_signature status=abort reason=no_key guid=#{hash[:guid]}"
|
logger.warn "event=verify_signature status=abort reason=no_key guid=#{hash[:guid]}"
|
||||||
return false
|
return false
|
||||||
elsif signature.nil?
|
elsif signature.nil?
|
||||||
|
|
@ -34,7 +34,7 @@ module DiasporaFederation
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
validity = key.verify(
|
validity = pubkey.verify(
|
||||||
OpenSSL::Digest::SHA256.new,
|
OpenSSL::Digest::SHA256.new,
|
||||||
Base64.decode64(signature),
|
Base64.decode64(signature),
|
||||||
signable_string(hash)
|
signable_string(hash)
|
||||||
|
|
|
||||||
|
|
@ -1,22 +1,22 @@
|
||||||
module DiasporaFederation
|
module DiasporaFederation
|
||||||
describe Salmon::EncryptedSlap do
|
describe Salmon::EncryptedSlap do
|
||||||
let(:author_id) { "user_test@diaspora.example.tld" }
|
let(:author_id) { "user_test@diaspora.example.tld" }
|
||||||
let(:pkey) { OpenSSL::PKey::RSA.generate(512) } # use small key for speedy specs
|
let(:privkey) { OpenSSL::PKey::RSA.generate(512) } # use small key for speedy specs
|
||||||
let(:okey) { OpenSSL::PKey::RSA.generate(1024) } # use small key for speedy specs
|
let(:recipient_key) { OpenSSL::PKey::RSA.generate(1024) } # use small key for speedy specs
|
||||||
let(:entity) { Entities::TestEntity.new(test: "qwertzuiop") }
|
let(:entity) { Entities::TestEntity.new(test: "qwertzuiop") }
|
||||||
let(:slap_xml) { Salmon::EncryptedSlap.generate_xml(author_id, pkey, entity, okey.public_key) }
|
let(:slap_xml) { Salmon::EncryptedSlap.generate_xml(author_id, privkey, entity, recipient_key.public_key) }
|
||||||
let(:ns) { {d: Salmon::XMLNS, me: Salmon::MagicEnvelope::XMLNS} }
|
let(:ns) { {d: Salmon::XMLNS, me: Salmon::MagicEnvelope::XMLNS} }
|
||||||
|
|
||||||
describe ".generate_xml" do
|
describe ".generate_xml" do
|
||||||
context "sanity" do
|
context "sanity" do
|
||||||
it "accepts correct params" do
|
it "accepts correct params" do
|
||||||
expect {
|
expect {
|
||||||
Salmon::EncryptedSlap.generate_xml(author_id, pkey, entity, okey.public_key)
|
Salmon::EncryptedSlap.generate_xml(author_id, privkey, entity, recipient_key.public_key)
|
||||||
}.not_to raise_error
|
}.not_to raise_error
|
||||||
end
|
end
|
||||||
|
|
||||||
it "raises an error when the params are the wrong type" do
|
it "raises an error when the params are the wrong type" do
|
||||||
["asdf", 1234, true, :symbol, entity, pkey].each do |val|
|
["asdf", 1234, true, :symbol, entity, privkey].each do |val|
|
||||||
expect {
|
expect {
|
||||||
Salmon::EncryptedSlap.generate_xml(val, val, val, val)
|
Salmon::EncryptedSlap.generate_xml(val, val, val, val)
|
||||||
}.to raise_error ArgumentError
|
}.to raise_error ArgumentError
|
||||||
|
|
@ -38,7 +38,7 @@ module DiasporaFederation
|
||||||
}
|
}
|
||||||
let(:cipher_header) { JSON.parse(Base64.decode64(subject)) }
|
let(:cipher_header) { JSON.parse(Base64.decode64(subject)) }
|
||||||
let(:header_key) {
|
let(:header_key) {
|
||||||
JSON.parse(okey.private_decrypt(Base64.decode64(cipher_header["aes_key"])))
|
JSON.parse(recipient_key.private_decrypt(Base64.decode64(cipher_header["aes_key"])))
|
||||||
}
|
}
|
||||||
|
|
||||||
it "encodes the header correctly" do
|
it "encodes the header correctly" do
|
||||||
|
|
@ -52,7 +52,7 @@ module DiasporaFederation
|
||||||
it "encrypts the public_key encrypted header correctly" do
|
it "encrypts the public_key encrypted header correctly" do
|
||||||
key = {}
|
key = {}
|
||||||
expect {
|
expect {
|
||||||
key = JSON.parse(okey.private_decrypt(Base64.decode64(cipher_header["aes_key"])))
|
key = JSON.parse(recipient_key.private_decrypt(Base64.decode64(cipher_header["aes_key"])))
|
||||||
}.not_to raise_error
|
}.not_to raise_error
|
||||||
expect(key).to include("key", "iv")
|
expect(key).to include("key", "iv")
|
||||||
end
|
end
|
||||||
|
|
@ -78,12 +78,12 @@ module DiasporaFederation
|
||||||
context "sanity" do
|
context "sanity" do
|
||||||
it "accepts correct params" do
|
it "accepts correct params" do
|
||||||
expect {
|
expect {
|
||||||
Salmon::EncryptedSlap.from_xml(slap_xml, okey)
|
Salmon::EncryptedSlap.from_xml(slap_xml, recipient_key)
|
||||||
}.not_to raise_error
|
}.not_to raise_error
|
||||||
end
|
end
|
||||||
|
|
||||||
it "raises an error when the params have a wrong type" do
|
it "raises an error when the params have a wrong type" do
|
||||||
[1234, false, :symbol, entity, pkey].each do |val|
|
[1234, false, :symbol, entity, privkey].each do |val|
|
||||||
expect {
|
expect {
|
||||||
Salmon::EncryptedSlap.from_xml(val, val)
|
Salmon::EncryptedSlap.from_xml(val, val)
|
||||||
}.to raise_error ArgumentError
|
}.to raise_error ArgumentError
|
||||||
|
|
@ -96,7 +96,7 @@ module DiasporaFederation
|
||||||
</diaspora>
|
</diaspora>
|
||||||
XML
|
XML
|
||||||
expect {
|
expect {
|
||||||
Salmon::EncryptedSlap.from_xml(faulty_xml, okey)
|
Salmon::EncryptedSlap.from_xml(faulty_xml, recipient_key)
|
||||||
}.to raise_error Salmon::MissingHeader
|
}.to raise_error Salmon::MissingHeader
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -108,14 +108,14 @@ XML
|
||||||
XML
|
XML
|
||||||
expect(Salmon::EncryptedSlap).to receive(:header_data).and_return(aes_key: "", iv: "", author_id: "")
|
expect(Salmon::EncryptedSlap).to receive(:header_data).and_return(aes_key: "", iv: "", author_id: "")
|
||||||
expect {
|
expect {
|
||||||
Salmon::EncryptedSlap.from_xml(faulty_xml, okey)
|
Salmon::EncryptedSlap.from_xml(faulty_xml, recipient_key)
|
||||||
}.to raise_error Salmon::MissingMagicEnvelope
|
}.to raise_error Salmon::MissingMagicEnvelope
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context "generated instance" do
|
context "generated instance" do
|
||||||
subject { Salmon::EncryptedSlap.from_xml(slap_xml, okey) }
|
subject { Salmon::EncryptedSlap.from_xml(slap_xml, recipient_key) }
|
||||||
|
|
||||||
it "should have cipher params set" do
|
it "should have cipher params set" do
|
||||||
expect(subject.instance_variable_get(:@cipher_params)).to_not be_nil
|
expect(subject.instance_variable_get(:@cipher_params)).to_not be_nil
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
module DiasporaFederation
|
module DiasporaFederation
|
||||||
describe Salmon::MagicEnvelope do
|
describe Salmon::MagicEnvelope do
|
||||||
let(:payload) { Entities::TestEntity.new(test: "asdf") }
|
let(:payload) { Entities::TestEntity.new(test: "asdf") }
|
||||||
let(:pkey) { OpenSSL::PKey::RSA.generate(512) } # use small key for speedy specs
|
let(:privkey) { OpenSSL::PKey::RSA.generate(512) } # use small key for speedy specs
|
||||||
let(:envelope) { envelop_xml(Salmon::MagicEnvelope.new(pkey, payload)) }
|
let(:envelope) { envelop_xml(Salmon::MagicEnvelope.new(privkey, payload)) }
|
||||||
|
|
||||||
def envelop_xml(magic_env)
|
def envelop_xml(magic_env)
|
||||||
builder = Nokogiri::XML::Builder.new(encoding: "UTF-8") do |xml|
|
builder = Nokogiri::XML::Builder.new(encoding: "UTF-8") do |xml|
|
||||||
|
|
@ -30,7 +30,7 @@ module DiasporaFederation
|
||||||
context "sanity" do
|
context "sanity" do
|
||||||
it "constructs an instance" do
|
it "constructs an instance" do
|
||||||
expect {
|
expect {
|
||||||
Salmon::MagicEnvelope.new(pkey, payload)
|
Salmon::MagicEnvelope.new(privkey, payload)
|
||||||
}.not_to raise_error
|
}.not_to raise_error
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -44,7 +44,7 @@ module DiasporaFederation
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "#envelop" do
|
describe "#envelop" do
|
||||||
subject { Salmon::MagicEnvelope.new(pkey, payload) }
|
subject { Salmon::MagicEnvelope.new(privkey, payload) }
|
||||||
|
|
||||||
it "should be an instance of Nokogiri::XML::Element" do
|
it "should be an instance of Nokogiri::XML::Element" do
|
||||||
expect(envelop_xml(subject)).to be_an_instance_of Nokogiri::XML::Element
|
expect(envelop_xml(subject)).to be_an_instance_of Nokogiri::XML::Element
|
||||||
|
|
@ -69,12 +69,12 @@ module DiasporaFederation
|
||||||
subj = sig_subj(env)
|
subj = sig_subj(env)
|
||||||
sig = Base64.urlsafe_decode64(env.at_xpath("me:sig").content)
|
sig = Base64.urlsafe_decode64(env.at_xpath("me:sig").content)
|
||||||
|
|
||||||
expect(pkey.public_key.verify(OpenSSL::Digest::SHA256.new, sig, subj)).to be_truthy
|
expect(privkey.public_key.verify(OpenSSL::Digest::SHA256.new, sig, subj)).to be_truthy
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "#encrypt!" do
|
describe "#encrypt!" do
|
||||||
subject { Salmon::MagicEnvelope.new(pkey, payload) }
|
subject { Salmon::MagicEnvelope.new(privkey, payload) }
|
||||||
|
|
||||||
it "encrypts the payload, returning cipher params" do
|
it "encrypts the payload, returning cipher params" do
|
||||||
params = subject.encrypt!
|
params = subject.encrypt!
|
||||||
|
|
@ -101,7 +101,7 @@ module DiasporaFederation
|
||||||
context "sanity" do
|
context "sanity" do
|
||||||
it "works with sane input" do
|
it "works with sane input" do
|
||||||
expect {
|
expect {
|
||||||
Salmon::MagicEnvelope.unenvelop(envelope, pkey.public_key)
|
Salmon::MagicEnvelope.unenvelop(envelope, privkey.public_key)
|
||||||
}.not_to raise_error
|
}.not_to raise_error
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -115,7 +115,7 @@ module DiasporaFederation
|
||||||
|
|
||||||
it "verifies the envelope structure" do
|
it "verifies the envelope structure" do
|
||||||
expect {
|
expect {
|
||||||
Salmon::MagicEnvelope.unenvelop(Nokogiri::XML::Document.parse("<asdf/>").root, pkey.public_key)
|
Salmon::MagicEnvelope.unenvelop(Nokogiri::XML::Document.parse("<asdf/>").root, privkey.public_key)
|
||||||
}.to raise_error Salmon::InvalidEnvelope
|
}.to raise_error Salmon::InvalidEnvelope
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -127,39 +127,39 @@ module DiasporaFederation
|
||||||
end
|
end
|
||||||
|
|
||||||
it "verifies the encoding" do
|
it "verifies the encoding" do
|
||||||
bad_env = envelop_xml(Salmon::MagicEnvelope.new(pkey, payload))
|
bad_env = envelop_xml(Salmon::MagicEnvelope.new(privkey, payload))
|
||||||
elem = bad_env.at_xpath("me:encoding")
|
elem = bad_env.at_xpath("me:encoding")
|
||||||
elem.content = "invalid_enc"
|
elem.content = "invalid_enc"
|
||||||
re_sign(bad_env, pkey)
|
re_sign(bad_env, privkey)
|
||||||
expect {
|
expect {
|
||||||
Salmon::MagicEnvelope.unenvelop(bad_env, pkey.public_key)
|
Salmon::MagicEnvelope.unenvelop(bad_env, privkey.public_key)
|
||||||
}.to raise_error Salmon::InvalidEncoding
|
}.to raise_error Salmon::InvalidEncoding
|
||||||
end
|
end
|
||||||
|
|
||||||
it "verifies the algorithm" do
|
it "verifies the algorithm" do
|
||||||
bad_env = envelop_xml(Salmon::MagicEnvelope.new(pkey, payload))
|
bad_env = envelop_xml(Salmon::MagicEnvelope.new(privkey, payload))
|
||||||
elem = bad_env.at_xpath("me:alg")
|
elem = bad_env.at_xpath("me:alg")
|
||||||
elem.content = "invalid_alg"
|
elem.content = "invalid_alg"
|
||||||
re_sign(bad_env, pkey)
|
re_sign(bad_env, privkey)
|
||||||
expect {
|
expect {
|
||||||
Salmon::MagicEnvelope.unenvelop(bad_env, pkey.public_key)
|
Salmon::MagicEnvelope.unenvelop(bad_env, privkey.public_key)
|
||||||
}.to raise_error Salmon::InvalidAlgorithm
|
}.to raise_error Salmon::InvalidAlgorithm
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
it "returns the original entity" do
|
it "returns the original entity" do
|
||||||
entity = Salmon::MagicEnvelope.unenvelop(envelope, pkey.public_key)
|
entity = Salmon::MagicEnvelope.unenvelop(envelope, privkey.public_key)
|
||||||
expect(entity).to be_an_instance_of Entities::TestEntity
|
expect(entity).to be_an_instance_of Entities::TestEntity
|
||||||
expect(entity.test).to eq("asdf")
|
expect(entity.test).to eq("asdf")
|
||||||
end
|
end
|
||||||
|
|
||||||
it "decrypts on the fly, when cipher params are present" do
|
it "decrypts on the fly, when cipher params are present" do
|
||||||
env = Salmon::MagicEnvelope.new(pkey, payload)
|
env = Salmon::MagicEnvelope.new(privkey, payload)
|
||||||
params = env.encrypt!
|
params = env.encrypt!
|
||||||
|
|
||||||
envelope = envelop_xml(env)
|
envelope = envelop_xml(env)
|
||||||
|
|
||||||
entity = Salmon::MagicEnvelope.unenvelop(envelope, pkey.public_key, params)
|
entity = Salmon::MagicEnvelope.unenvelop(envelope, privkey.public_key, params)
|
||||||
expect(entity).to be_an_instance_of Entities::TestEntity
|
expect(entity).to be_an_instance_of Entities::TestEntity
|
||||||
expect(entity.test).to eq("asdf")
|
expect(entity.test).to eq("asdf")
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -1,20 +1,20 @@
|
||||||
module DiasporaFederation
|
module DiasporaFederation
|
||||||
describe Salmon::Slap do
|
describe Salmon::Slap do
|
||||||
let(:author_id) { "test_user@pod.somedomain.tld" }
|
let(:author_id) { "test_user@pod.somedomain.tld" }
|
||||||
let(:pkey) { OpenSSL::PKey::RSA.generate(512) } # use small key for speedy specs
|
let(:privkey) { OpenSSL::PKey::RSA.generate(512) } # use small key for speedy specs
|
||||||
let(:entity) { Entities::TestEntity.new(test: "qwertzuiop") }
|
let(:entity) { Entities::TestEntity.new(test: "qwertzuiop") }
|
||||||
let(:slap) { Salmon::Slap.generate_xml(author_id, pkey, entity) }
|
let(:slap) { Salmon::Slap.generate_xml(author_id, privkey, entity) }
|
||||||
|
|
||||||
describe ".generate_xml" do
|
describe ".generate_xml" do
|
||||||
context "sanity" do
|
context "sanity" do
|
||||||
it "accepts correct params" do
|
it "accepts correct params" do
|
||||||
expect {
|
expect {
|
||||||
Salmon::Slap.generate_xml(author_id, pkey, entity)
|
Salmon::Slap.generate_xml(author_id, privkey, entity)
|
||||||
}.not_to raise_error
|
}.not_to raise_error
|
||||||
end
|
end
|
||||||
|
|
||||||
it "raises an error when the params are the wrong type" do
|
it "raises an error when the params are the wrong type" do
|
||||||
["asdf", 1234, true, :symbol, entity, pkey].each do |val|
|
["asdf", 1234, true, :symbol, entity, privkey].each do |val|
|
||||||
expect {
|
expect {
|
||||||
Salmon::Slap.generate_xml(val, val, val)
|
Salmon::Slap.generate_xml(val, val, val)
|
||||||
}.to raise_error ArgumentError
|
}.to raise_error ArgumentError
|
||||||
|
|
@ -40,7 +40,7 @@ module DiasporaFederation
|
||||||
end
|
end
|
||||||
|
|
||||||
it "raises an error when the param has a wrong type" do
|
it "raises an error when the param has a wrong type" do
|
||||||
[1234, false, :symbol, entity, pkey].each do |val|
|
[1234, false, :symbol, entity, privkey].each do |val|
|
||||||
expect {
|
expect {
|
||||||
Salmon::Slap.from_xml(val)
|
Salmon::Slap.from_xml(val)
|
||||||
}.to raise_error ArgumentError
|
}.to raise_error ArgumentError
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
module DiasporaFederation
|
module DiasporaFederation
|
||||||
describe Signing do
|
describe Signing do
|
||||||
let(:pkey) {
|
let(:privkey) {
|
||||||
OpenSSL::PKey::RSA.new <<-RSA
|
OpenSSL::PKey::RSA.new <<-RSA
|
||||||
-----BEGIN RSA PRIVATE KEY-----
|
-----BEGIN RSA PRIVATE KEY-----
|
||||||
MIICXAIBAAKBgQDT7vBTAl0Z55bPcBjM9dvSOTuVtBxsgfrw2W0hTAYpd1H5032C
|
MIICXAIBAAKBgQDT7vBTAl0Z55bPcBjM9dvSOTuVtBxsgfrw2W0hTAYpd1H5032C
|
||||||
|
|
@ -43,21 +43,21 @@ RSA
|
||||||
|
|
||||||
describe ".sign_with_key" do
|
describe ".sign_with_key" do
|
||||||
it "produces correct signature" do
|
it "produces correct signature" do
|
||||||
expect(Signing.sign_with_key(hash, pkey)).to eq(signature)
|
expect(Signing.sign_with_key(hash, privkey)).to eq(signature)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe ".verify_signature" do
|
describe ".verify_signature" do
|
||||||
it "verifies correct signature" do
|
it "verifies correct signature" do
|
||||||
expect(Signing.verify_signature(hash, signature, pkey.public_key)).to be_truthy
|
expect(Signing.verify_signature(hash, signature, privkey.public_key)).to be_truthy
|
||||||
end
|
end
|
||||||
|
|
||||||
it "doesn't verify wrong signature" do
|
it "doesn't verify wrong signature" do
|
||||||
expect(Signing.verify_signature(hash, "false signature==", pkey.public_key)).to be_falsy
|
expect(Signing.verify_signature(hash, "false signature==", privkey.public_key)).to be_falsy
|
||||||
end
|
end
|
||||||
|
|
||||||
it "doesn't verify when signature is missing" do
|
it "doesn't verify when signature is missing" do
|
||||||
expect(Signing.verify_signature(hash, nil, pkey.public_key)).to be_falsy
|
expect(Signing.verify_signature(hash, nil, privkey.public_key)).to be_falsy
|
||||||
end
|
end
|
||||||
|
|
||||||
it "doesn't verify when public key is missing" do
|
it "doesn't verify when public key is missing" do
|
||||||
|
|
|
||||||
|
|
@ -10,23 +10,14 @@ shared_examples "a Slap instance" do
|
||||||
|
|
||||||
it "works when the pubkey is given" do
|
it "works when the pubkey is given" do
|
||||||
expect {
|
expect {
|
||||||
subject.entity(pkey.public_key)
|
subject.entity(privkey.public_key)
|
||||||
}.not_to raise_error
|
}.not_to raise_error
|
||||||
end
|
end
|
||||||
|
|
||||||
it "returns the entity" do
|
it "returns the entity" do
|
||||||
entity = subject.entity(pkey.public_key)
|
entity = subject.entity(privkey.public_key)
|
||||||
expect(entity).to be_an_instance_of DiasporaFederation::Entities::TestEntity
|
expect(entity).to be_an_instance_of DiasporaFederation::Entities::TestEntity
|
||||||
expect(entity.test).to eq("qwertzuiop")
|
expect(entity.test).to eq("qwertzuiop")
|
||||||
end
|
end
|
||||||
|
|
||||||
it "does not require the pubkey in consecutive calls" do
|
|
||||||
e1, e2 = nil
|
|
||||||
expect {
|
|
||||||
e1 = subject.entity(pkey.public_key)
|
|
||||||
e2 = subject.entity
|
|
||||||
}.not_to raise_error
|
|
||||||
expect(e1).to eq(e2)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -60,24 +60,24 @@ DiasporaFederation.configure do |config|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def pkey
|
def privkey
|
||||||
@test_pkey ||= OpenSSL::PKey::RSA.generate(1024)
|
@test_privkey ||= OpenSSL::PKey::RSA.generate(1024)
|
||||||
end
|
end
|
||||||
|
|
||||||
on :fetch_private_key_by_diaspora_id do
|
on :fetch_private_key_by_diaspora_id do
|
||||||
pkey
|
privkey
|
||||||
end
|
end
|
||||||
|
|
||||||
on :fetch_author_private_key_by_entity_guid do
|
on :fetch_author_private_key_by_entity_guid do
|
||||||
pkey
|
privkey
|
||||||
end
|
end
|
||||||
|
|
||||||
on :fetch_public_key_by_diaspora_id do
|
on :fetch_public_key_by_diaspora_id do
|
||||||
pkey.public_key
|
privkey.public_key
|
||||||
end
|
end
|
||||||
|
|
||||||
on :fetch_author_public_key_by_entity_guid do
|
on :fetch_author_public_key_by_entity_guid do
|
||||||
pkey.public_key
|
privkey.public_key
|
||||||
end
|
end
|
||||||
|
|
||||||
on :entity_author_is_local? do
|
on :entity_author_is_local? do
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue