Class: RightScale::SecureSerializer
- Includes:
- ProtocolVersionMixin
- Defined in:
- lib/right_agent/serialize/secure_serializer.rb
Overview
Serializer implementation which secures messages by using X.509 certificate signing
Defined Under Namespace
Classes: InvalidSignature, MissingCertificate, MissingPrivateKey
Class Method Summary collapse
-
.dump(obj, encrypt = nil) ⇒ Object
See SecureSerializer#dump.
-
.init(serializer, identity, store, encrypt = true) ⇒ Object
Create the one and only SecureSerializer.
-
.initialized? ⇒ Boolean
Was serializer initialized?.
-
.load(msg, id = nil) ⇒ Object
See SecureSerializer#load.
Instance Method Summary collapse
-
#dump(obj, encrypt = nil) ⇒ Object
Serialize, sign, and encrypt message Sign and encrypt using X.509 certificate.
-
#initialize(serializer, identity, store, encrypt = true) ⇒ SecureSerializer
constructor
Initialize serializer, must be called prior to using it.
-
#load(msg, id = nil) ⇒ Object
Decrypt, authorize signature, and unserialize message Use x.509 certificate store for decrypting and validating signature.
Methods included from ProtocolVersionMixin
#can_always_handle_hash_payload?, #can_handle_http?, #can_handle_msgpack_result?, #can_handle_multicast_result?, #can_handle_non_delivery_result?, #can_handle_non_nanite_ids?, #can_handle_request_retries?, #can_put_version_in_packet?, #can_route_to_response_queue?, #can_use_router_query_tags?
Constructor Details
#initialize(serializer, identity, store, encrypt = true) ⇒ SecureSerializer
Initialize serializer, must be called prior to using it
Parameters
- serializer(Serializer)
-
Object serializer
- identity(String)
-
Serialized identity associated with serialized messages
- store(Object)
-
Credentials store exposing certificates used for
encryption (:get_target), signature validation (:get_signer), and
certificate(s)/key(s) used for decryption (:get_receiver)
- encrypt(Boolean)
-
true if data should be signed and encrypted, otherwise
just signed, true by default
68 69 70 71 72 73 74 75 76 77 78 |
# File 'lib/right_agent/serialize/secure_serializer.rb', line 68 def initialize(serializer, identity, store, encrypt = true) @identity = identity raise "Missing local agent identity" unless @identity @store = store raise "Missing credentials store" unless @store @cert, @key = @store.get_receiver(@identity) raise "Missing local agent public certificate" unless @cert raise "Missing local agent private key" unless @key @encrypt = encrypt @serializer = serializer end |
Class Method Details
.dump(obj, encrypt = nil) ⇒ Object
See SecureSerializer#dump
47 48 49 50 |
# File 'lib/right_agent/serialize/secure_serializer.rb', line 47 def self.dump(obj, encrypt = nil) raise "Secure serializer not initialized" unless initialized? @serializer.dump(obj, encrypt) end |
.init(serializer, identity, store, encrypt = true) ⇒ Object
Create the one and only SecureSerializer
36 37 38 39 |
# File 'lib/right_agent/serialize/secure_serializer.rb', line 36 def self.init(serializer, identity, store, encrypt = true) @serializer = SecureSerializer.new(serializer, identity, store, encrypt) true end |
.initialized? ⇒ Boolean
Was serializer initialized?
42 43 44 |
# File 'lib/right_agent/serialize/secure_serializer.rb', line 42 def self.initialized? !@serializer.nil? end |
.load(msg, id = nil) ⇒ Object
See SecureSerializer#load
53 54 55 56 |
# File 'lib/right_agent/serialize/secure_serializer.rb', line 53 def self.load(msg, id = nil) raise "Secure serializer not initialized" unless initialized? @serializer.load(msg, id) end |
Instance Method Details
#dump(obj, encrypt = nil) ⇒ Object
Serialize, sign, and encrypt message Sign and encrypt using X.509 certificate
Parameters
- obj(Object)
-
Object to be serialized and encrypted
- encrypt(Boolean|nil)
-
true if object should be signed and encrypted,
false if just signed, nil means use class setting
Return
- (String)
-
MessagePack serialized and optionally encrypted object
90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 |
# File 'lib/right_agent/serialize/secure_serializer.rb', line 90 def dump(obj, encrypt = nil) must_encrypt = encrypt || @encrypt serialize_format = if obj.respond_to?(:send_version) && can_handle_msgpack_result?(obj.send_version) @serializer.format else :json end encode_format = serialize_format == :json ? :pem : :der msg = @serializer.dump(obj, serialize_format) if must_encrypt certs = @store.get_target(obj) if certs msg = EncryptedDocument.new(msg, certs).encrypted_data(encode_format) else target = obj.target_for_encryption if obj.respond_to?(:target_for_encryption) ErrorTracker.log(self, "No certs available for object #{obj.class} being sent to #{target.inspect}") if target end end sig = Signature.new(msg, @cert, @key).data(encode_format) @serializer.dump({'id' => @identity, 'data' => msg, 'signature' => sig, 'encrypted' => !certs.nil?}, serialize_format) end |
#load(msg, id = nil) ⇒ Object
Decrypt, authorize signature, and unserialize message Use x.509 certificate store for decrypting and validating signature
Parameters
- msg(String)
-
Serialized and optionally encrypted object using MessagePack or JSON
- id(String|nil)
-
Optional identifier of source of data for use
in determining who is the receiver
Return
- (Object)
-
Unserialized object
Raise
- MissingCertificate
-
If could not find certificate for message signer or receiver
- MissingPrivateKey
-
If could not find private key for message receiver
- InvalidSignature
-
If message signature check failed for message
127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 |
# File 'lib/right_agent/serialize/secure_serializer.rb', line 127 def load(msg, id = nil) msg = @serializer.load(msg) sig = Signature.from_data(msg['signature']) certs = @store.get_signer(msg['id']) raise MissingCertificate.new("Could not find a certificate for signer #{msg['id']}") unless certs certs = [ certs ] unless certs.respond_to?(:any?) raise InvalidSignature.new("Failed signature check for signer #{msg['id']}") unless certs.any? { |c| sig.match?(c) } data = msg['data'] if data && msg['encrypted'] cert, key = @store.get_receiver(id) raise MissingCertificate.new("Could not find a certificate for #{id.inspect}") unless cert raise MissingPrivateKey.new("Could not find a private key for #{id.inspect}") unless key data = EncryptedDocument.from_data(data).decrypted_data(key, cert) end @serializer.load(data) if data end |