omf_common 6.0.0 → 6.0.2.pre.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. data/Gemfile +4 -0
  2. data/bin/file_broadcaster.rb +56 -0
  3. data/bin/file_receiver.rb +62 -0
  4. data/bin/omf_keygen +21 -0
  5. data/bin/{monitor_topic.rb → omf_monitor_topic} +21 -8
  6. data/bin/omf_send_create +118 -0
  7. data/bin/{send_request.rb → omf_send_request} +12 -7
  8. data/example/engine_alt.rb +23 -24
  9. data/example/ls_app.yaml +21 -0
  10. data/lib/omf_common.rb +73 -12
  11. data/lib/omf_common/auth.rb +15 -0
  12. data/lib/omf_common/auth/certificate.rb +174 -0
  13. data/lib/omf_common/auth/certificate_store.rb +72 -0
  14. data/lib/omf_common/auth/ssh_pub_key_convert.rb +80 -0
  15. data/lib/omf_common/comm.rb +66 -9
  16. data/lib/omf_common/comm/amqp/amqp_communicator.rb +40 -13
  17. data/lib/omf_common/comm/amqp/amqp_file_transfer.rb +259 -0
  18. data/lib/omf_common/comm/amqp/amqp_topic.rb +14 -21
  19. data/lib/omf_common/comm/local/local_communicator.rb +31 -2
  20. data/lib/omf_common/comm/local/local_topic.rb +19 -3
  21. data/lib/omf_common/comm/topic.rb +48 -34
  22. data/lib/omf_common/comm/xmpp/communicator.rb +19 -10
  23. data/lib/omf_common/comm/xmpp/topic.rb +22 -81
  24. data/lib/omf_common/default_logging.rb +11 -0
  25. data/lib/omf_common/eventloop.rb +14 -0
  26. data/lib/omf_common/eventloop/em.rb +39 -6
  27. data/lib/omf_common/eventloop/local_evl.rb +15 -0
  28. data/lib/omf_common/exec_app.rb +29 -15
  29. data/lib/omf_common/message.rb +53 -5
  30. data/lib/omf_common/message/json/json_message.rb +149 -39
  31. data/lib/omf_common/message/xml/message.rb +112 -39
  32. data/lib/omf_common/protocol/6.0.rnc +5 -1
  33. data/lib/omf_common/protocol/6.0.rng +12 -0
  34. data/lib/omf_common/version.rb +1 -1
  35. data/omf_common.gemspec +7 -2
  36. data/test/fixture/omf_test.cert.pem +15 -0
  37. data/test/fixture/omf_test.pem +15 -0
  38. data/test/fixture/omf_test.pub +1 -0
  39. data/test/fixture/omf_test.pub.pem +6 -0
  40. data/test/omf_common/auth/certificate_spec.rb +113 -0
  41. data/test/omf_common/auth/ssh_pub_key_convert_spec.rb +13 -0
  42. data/test/omf_common/comm/topic_spec.rb +175 -0
  43. data/test/omf_common/comm/xmpp/communicator_spec.rb +15 -16
  44. data/test/omf_common/comm/xmpp/topic_spec.rb +63 -10
  45. data/test/omf_common/comm_spec.rb +66 -9
  46. data/test/omf_common/message/xml/message_spec.rb +43 -13
  47. data/test/omf_common/message_spec.rb +14 -0
  48. data/test/test_helper.rb +25 -0
  49. metadata +78 -15
  50. data/bin/send_create.rb +0 -94
@@ -9,7 +9,6 @@ require 'omf_common/message/xml/relaxng_schema'
9
9
  module OmfCommon
10
10
  class Message
11
11
  class XML
12
-
13
12
  # @example To create a valid omf message, e.g. a 'create' message:
14
13
  #
15
14
  # Message.create(:create,
@@ -47,12 +46,46 @@ class XML
47
46
  new(content)
48
47
  end
49
48
 
50
- def parse(xml)
49
+ def parse(xml, content_type = "text/xml", &block)
50
+ raise ArgumentError, 'Need message handling block' unless block
51
+
52
+ content_type ||= "text/xml" # Since by default parent class pass in nil object
53
+ raise ArgumentError, "Unknown content type: #{content_type}" unless content_type =~ /xml/
51
54
  raise ArgumentError, 'Can not parse an empty XML into OMF message' if xml.nil? || xml.empty?
52
55
 
53
56
  xml_node = Nokogiri::XML(xml).root
54
57
 
55
- self.create(xml_node.name.to_sym).tap do |message|
58
+ if xml_node.name.to_sym == :env # envelope
59
+ cert = xml_node.element_children.find { |v| v.element_name == 'cert' }.content
60
+ sig = xml_node.element_children.find { |v| v.element_name == 'sig' }.content
61
+ iss = xml_node.element_children.find { |v| v.element_name == 'iss' }.content
62
+ xml_node = xml_node.element_children.find { |v| v.element_name =~ /create|request|configure|release|inform/ }
63
+
64
+ if self.authenticate?
65
+ existing_cert = OmfCommon::Auth::CertificateStore.instance.cert_for(iss)
66
+
67
+ if existing_cert
68
+ cert = existing_cert
69
+ else
70
+ OmfCommon::Auth::CertificateStore.instance.register_x509(cert, iss)
71
+ cert = OmfCommon::Auth::CertificateStore.instance.cert_for(iss)
72
+ end
73
+
74
+ unless cert.verify_cert
75
+ warn "Invalid certificate '#{cert.to_s}', NOT signed by root certificate."
76
+ return nil
77
+ end
78
+
79
+ canonicalised_xml_node = fix_canonicalised_xml(xml_node.canonicalize)
80
+
81
+ unless cert.to_x509.public_key.verify(OpenSSL::Digest::SHA256.new(canonicalised_xml_node), Base64.decode64(sig), canonicalised_xml_node)
82
+ warn "Verfication failed #{canonicalised_xml_node} #{OpenSSL::Digest::SHA256.new(canonicalised_xml_node)}"
83
+ return nil
84
+ end
85
+ end
86
+ end
87
+
88
+ parsed_msg = self.create(xml_node.name.to_sym).tap do |message|
56
89
  message.xml = xml_node
57
90
 
58
91
  message.send(:_set_core, :mid, message.xml.attr('mid'))
@@ -82,6 +115,8 @@ class XML
82
115
  MPMessage.inject(Time.now.to_f, message.operation.to_s, message.mid, message.cid, message.to_s.gsub("\n",''))
83
116
  end
84
117
  end
118
+ block.call(parsed_msg)
119
+ parsed_msg
85
120
  end
86
121
  end
87
122
 
@@ -90,17 +125,50 @@ class XML
90
125
  OmfCommon::Comm::XMPP::Topic.create(r_id)
91
126
  end
92
127
 
93
- def itype
94
- @content.itype.to_s.upcase.gsub(/_/, '.') unless @content.itype.nil?
95
- end
96
-
97
128
  def marshall
98
129
  build_xml
99
- @xml.to_xml
130
+
131
+ if self.class.authenticate?
132
+ src = @content[:src]
133
+ src = src.address if src.is_a?(OmfCommon::Comm::Topic)
134
+ cert = OmfCommon::Auth::CertificateStore.instance.cert_for(src)
135
+ if cert && cert.can_sign?
136
+ debug "Found cert for '#{src} - #{cert}"
137
+ signature_node = Niceogiri::XML::Node.new(:sig)
138
+
139
+ canonicalised_xml = self.class.fix_canonicalised_xml(@xml.canonicalize)
140
+
141
+ signature = Base64.encode64(cert.key.sign(OpenSSL::Digest::SHA256.new(canonicalised_xml), canonicalised_xml)).encode('utf-8')
142
+ signature_node.add_child(signature)
143
+
144
+ @envelope = Niceogiri::XML::Node.new(:env, nil, OMF_NAMESPACE)
145
+ @envelope.add_child(@xml)
146
+ @envelope.add_child(signature_node)
147
+
148
+ iss_node = Niceogiri::XML::Node.new(:iss)
149
+ iss_node.add_child(src)
150
+ @envelope.add_child(iss_node)
151
+
152
+ #unless @certOnTopic[k = [topic, src]]
153
+ # first time for this src on this topic, so let's send the cert along
154
+ cert_node = Niceogiri::XML::Node.new(:cert)
155
+ cert_node.add_child(cert.to_pem_compact)
156
+ @envelope.add_child(cert_node)
157
+ #ALWAYS ADD CERT @certOnTopic[k] = Time.now
158
+ #end
159
+ ['text/xml', @envelope]
160
+ else
161
+ error "Missing cert for #{src}"
162
+ ['text/xml', nil]
163
+ end
164
+ else
165
+ ['text/xml', @xml]
166
+ end
100
167
  end
101
168
 
102
- alias_method :to_xml, :marshall
103
- alias_method :to_s, :marshall
169
+ def to_s
170
+ @content
171
+ end
104
172
 
105
173
  def build_xml
106
174
  @xml = Niceogiri::XML::Node.new(self.operation.to_s, nil, OMF_NAMESPACE)
@@ -118,25 +186,30 @@ class XML
118
186
  @xml.add_child(guard_node) if _get_core(:guard)
119
187
 
120
188
  (OMF_CORE_READ - [:mid, :guard, :operation]).each do |attr|
121
- attr_value = self.send(attr)
189
+ attr_value = case attr
190
+ when :itype
191
+ self.itype(:frcp)
192
+ when :src
193
+ self.src.is_a?(OmfCommon::Comm::Topic) ? self.src.address : self.src
194
+ else
195
+ self.send(attr)
196
+ end
122
197
 
123
198
  next unless attr_value
124
199
 
125
200
  add_element(attr, attr_value) unless (self.operation != :release && attr == :res_id)
126
201
  end
127
202
 
128
- self.properties.each { |k, v| add_property(k, v) }
203
+ self.properties.each { |k, v| add_property(k, v) unless k == 'certificate'}
129
204
  self.guard.each { |k, v| add_property(k, v, :guard) } if _get_core(:guard)
130
205
 
131
- #digest = OpenSSL::Digest::SHA512.new(@xml.canonicalize)
132
-
133
- #add_element(:digest, digest)
134
206
  @xml
135
207
  end
136
208
 
137
209
  # Construct a property xml node
138
210
  #
139
211
  def add_property(key, value = nil, add_to = :props)
212
+ key = escape_key(key)
140
213
  if !default_props_ns.empty? && add_to == :props
141
214
  key_node = Niceogiri::XML::Node.new(key, nil, default_props_ns)
142
215
  else
@@ -162,6 +235,7 @@ class XML
162
235
  when Hash
163
236
  [].tap do |array|
164
237
  value.each_pair do |k, v|
238
+ k = escape_key(k)
165
239
  n = Niceogiri::XML::Node.new(k, nil, OMF_NAMESPACE)
166
240
  n.write_attr('type', ruby_type_2_prop_type(v.class))
167
241
 
@@ -191,33 +265,13 @@ class XML
191
265
  if key.nil?
192
266
  string_value(value)
193
267
  else
268
+ key = escape_key(key)
194
269
  n = Niceogiri::XML::Node.new(key, nil, OMF_NAMESPACE)
195
270
  n.add_child(string_value(value))
196
271
  end
197
272
  end
198
273
  end
199
274
 
200
- # Generate SHA1 of canonicalised xml and write into the ID attribute of the message
201
- #
202
- def sign
203
- write_attr('mid', SecureRandom.uuid)
204
- write_attr('ts', Time.now.utc.to_i)
205
- canonical_msg = self.canonicalize
206
-
207
- #priv_key = OmfCommon::Key.instance.private_key
208
- #digest = OpenSSL::Digest::SHA512.new(canonical_msg)
209
-
210
- #signature = Base64.encode64(priv_key.sign(digest, canonical_msg)).encode('utf-8') if priv_key
211
- #write_attr('digest', digest)
212
- #write_attr('signature', signature) if signature
213
-
214
- if OmfCommon::Measure.enabled?
215
- MPMessage.inject(Time.now.to_f, operation.to_s, mid, cid, self.to_s.gsub("\n",''))
216
- @@mid_list << mid
217
- end
218
- self
219
- end
220
-
221
275
  # Validate against relaxng schema
222
276
  #
223
277
  def valid?
@@ -236,6 +290,7 @@ class XML
236
290
  # Short cut for adding xml node
237
291
  #
238
292
  def add_element(key, value = nil, &block)
293
+ key = escape_key(key)
239
294
  key_node = Niceogiri::XML::Node.new(key)
240
295
  @xml.add_child(key_node)
241
296
  if block
@@ -310,7 +365,7 @@ class XML
310
365
  end
311
366
 
312
367
  def has_properties?
313
- @content.properties.empty?
368
+ !@content.properties.empty?
314
369
  end
315
370
 
316
371
  def guard?
@@ -350,9 +405,8 @@ class XML
350
405
  # end
351
406
  #end
352
407
 
353
- alias_method :read_property, :[]
354
-
355
408
  alias_method :write_property, :[]=
409
+ alias_method :read_property, :[]
356
410
 
357
411
  private
358
412
 
@@ -360,6 +414,11 @@ class XML
360
414
  @content = content
361
415
  @content.mid = SecureRandom.uuid
362
416
  @content.ts = Time.now.utc.to_i
417
+ if (src = content[:src])
418
+ @content.src = OmfCommon.comm.create_topic(src)
419
+ end
420
+ # keep track if we sent local certs on a topic. Should do this the first time
421
+ @certOnTopic = {}
363
422
  end
364
423
 
365
424
  def _set_core(key, value)
@@ -394,6 +453,16 @@ class XML
394
453
  end
395
454
  end
396
455
 
456
+ def escape_key(key)
457
+ key = key.to_s
458
+ if key =~ /\W+/
459
+ warn "Due to the limitation of XML messages, please only use word character (a-z A-Z 0-9 _) in your property names. Offending characters will be replaced with underscore(_)."
460
+ key = key.gsub(/\W+/, '_')
461
+ else
462
+ key
463
+ end
464
+ end
465
+
397
466
  # Get string of a value object, escape if object is string
398
467
  def string_value(value)
399
468
  if value.kind_of? String
@@ -403,6 +472,10 @@ class XML
403
472
  end
404
473
  value
405
474
  end
475
+
476
+ def self.fix_canonicalised_xml(str)
477
+ str.gsub(/\n +/, '').gsub(/ xmlns=\"\"/, '')
478
+ end
406
479
  end
407
480
  end
408
481
  end
@@ -1,6 +1,6 @@
1
1
  default namespace = "http://schema.mytestbed.net/omf/6.0/protocol"
2
2
 
3
- start = (create | configure | request | release | inform)
3
+ start = (create | configure | request | release | inform | env)
4
4
 
5
5
  common_elements = attribute mid { text }?
6
6
  & element ts { text }
@@ -36,3 +36,7 @@ inform = element inform {
36
36
  & element cid { text }?
37
37
  & element itype { "CREATION.OK" | "CREATION.FAILED" | "STATUS" | "RELEASED" | "ERROR" | "WARN" }
38
38
  }
39
+
40
+ env = element env {
41
+ create | configure | request | release | inform
42
+ }
@@ -7,6 +7,7 @@
7
7
  <ref name="request"/>
8
8
  <ref name="release"/>
9
9
  <ref name="inform"/>
10
+ <ref name="env"/>
10
11
  </choice>
11
12
  </start>
12
13
  <define name="common_elements">
@@ -125,4 +126,15 @@
125
126
  </interleave>
126
127
  </element>
127
128
  </define>
129
+ <define name="env">
130
+ <element name="env">
131
+ <choice>
132
+ <ref name="create"/>
133
+ <ref name="configure"/>
134
+ <ref name="request"/>
135
+ <ref name="release"/>
136
+ <ref name="inform"/>
137
+ </choice>
138
+ </element>
139
+ </define>
128
140
  </grammar>
@@ -1,4 +1,4 @@
1
1
  module OmfCommon
2
- VERSION = "6.0.0"
2
+ VERSION = "6.0.2.pre.1"
3
3
  PROTOCOL_VERSION = "6.0"
4
4
  end
data/omf_common.gemspec CHANGED
@@ -17,16 +17,21 @@ Gem::Specification.new do |s|
17
17
 
18
18
  s.files = `git ls-files`.split("\n")
19
19
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
20
- s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
+ s.executables = ["omf_monitor_topic","omf_send_request", "omf_send_create"]
21
21
  s.require_paths = ["lib"]
22
22
 
23
23
  # specify any dependencies here; for example:
24
24
  s.add_development_dependency "minitest", "~> 3.2"
25
25
  s.add_development_dependency "em-minitest-spec", "~> 1.1.1"
26
26
  s.add_development_dependency "simplecov"
27
+ s.add_development_dependency "pry"
28
+ s.add_development_dependency "mocha"
29
+
27
30
  s.add_runtime_dependency "eventmachine", "~> 0.12.10"
28
31
  s.add_runtime_dependency "blather", "= 0.8.1"
29
32
  s.add_runtime_dependency "logging", "~> 1.7.1"
30
33
  s.add_runtime_dependency "hashie", "~> 1.2.0"
31
- s.add_runtime_dependency "oml4r", "~> 2.8.0"
34
+ s.add_runtime_dependency "oml4r", "~> 2.9.1"
35
+ #s.add_runtime_dependency "json-jwt", "~> 0.5.2"
36
+ #s.add_runtime_dependency "amqp", "~> 1.0.1"
32
37
  end
@@ -0,0 +1,15 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIICWDCCAcGgAwIBAgIJAIZg2YXVVvPIMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV
3
+ BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX
4
+ aWRnaXRzIFB0eSBMdGQwHhcNMTMwNDIzMDQyOTE5WhcNMjMwNDIxMDQyOTE5WjBF
5
+ MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50
6
+ ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB
7
+ gQC24IfY2Kat2C35gw+X1fM8NI7CJ5DvT19BoDjQviXy8RhBl4fCTNVBvYYzgZXC
8
+ zVcTi4nAgJFbxvHMBeORmSWih5s3E/zllPWVmRstxGqscqoshjSnnU32p6HBXHEB
9
+ 0zuZsO/8Ff2+L0Q1QX9XhFntrJsyeiOk2fstz5AXovL6iQIDAQABo1AwTjAdBgNV
10
+ HQ4EFgQUeXgde/SzFMMdPj0Sv7nGKlE0LoEwHwYDVR0jBBgwFoAUeXgde/SzFMMd
11
+ Pj0Sv7nGKlE0LoEwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOBgQAgLs56
12
+ W7MpT9gc+/QGPt1FEIHqGGGwS/FuxQJEJnrnI0MpCf+2dqAlOwTKQDh+QB8558YO
13
+ cdGqgrFKPJSVvIaqow9OStOqn+PpyhBgfrDMkKMCdmN3yW4JeytAM+z5pV44YtTw
14
+ GBlr4kQzF0y3V1oo1+Ck1F1n+CARt2knmi3zAQ==
15
+ -----END CERTIFICATE-----
@@ -0,0 +1,15 @@
1
+ -----BEGIN RSA PRIVATE KEY-----
2
+ MIICXQIBAAKBgQC24IfY2Kat2C35gw+X1fM8NI7CJ5DvT19BoDjQviXy8RhBl4fC
3
+ TNVBvYYzgZXCzVcTi4nAgJFbxvHMBeORmSWih5s3E/zllPWVmRstxGqscqoshjSn
4
+ nU32p6HBXHEB0zuZsO/8Ff2+L0Q1QX9XhFntrJsyeiOk2fstz5AXovL6iQIDAQAB
5
+ AoGBALJb/mJBux6mTwChEJ43rskzQWCfEj40nWT2DTOZoI13Ev81+NRJ91vsqmyl
6
+ oBikCJ8pYqp7OknWmJEx1Sd1xDs/jsb6AUfNsfJALtE54Cq2iEWBU3Q4BTuT1meE
7
+ Fyvqww9YoFZIaYHvyDWYTH2B8eYrswSt4nCpKmr9eb/cBplhAkEA42Fl+aYUv2A6
8
+ 7EGFe+1OT9ctLZeEGPBIWuWIma6vj4+iM6Zn1rmsoqx3qsrjsIVUxpmmH5RvrJOY
9
+ Vq0WvqDwxQJBAM3lJ3lzs5fLEjzk/obiU6PJFq6BCFUTVtbjaRe8uN450fBEm+0M
10
+ pOacio2jDhA21ayHE+yAfZ2h0V+WXSvHNvUCQDV2JBTjoMMybAg6i5kMvbn1/NBY
11
+ bJ20eT6t80U3Fl4pxlhgis+ozlddN7G3jHtnjfw4CiAotW0dMtdGUS+3BYUCQD3a
12
+ YYly4LjxIIF6qZwL0eSaPF4gFUi5jpTvrFqdL0xTQmZTtiP4cHF3BYiXO1pTns09
13
+ pxadYx8/xY5ZtZO5PSECQQCwGIGrXQnT6FVpuJFRIl1m0rglbXEHy1x8xRYaQNJX
14
+ 7cUKcQaIXoroQ43TQnkIcIK7Q11EFomrJBTTL7icpgfU
15
+ -----END RSA PRIVATE KEY-----
@@ -0,0 +1 @@
1
+ ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQC24IfY2Kat2C35gw+X1fM8NI7CJ5DvT19BoDjQviXy8RhBl4fCTNVBvYYzgZXCzVcTi4nAgJFbxvHMBeORmSWih5s3E/zllPWVmRstxGqscqoshjSnnU32p6HBXHEB0zuZsO/8Ff2+L0Q1QX9XhFntrJsyeiOk2fstz5AXovL6iQ==
@@ -0,0 +1,6 @@
1
+ -----BEGIN PUBLIC KEY-----
2
+ MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC24IfY2Kat2C35gw+X1fM8NI7C
3
+ J5DvT19BoDjQviXy8RhBl4fCTNVBvYYzgZXCzVcTi4nAgJFbxvHMBeORmSWih5s3
4
+ E/zllPWVmRstxGqscqoshjSnnU32p6HBXHEB0zuZsO/8Ff2+L0Q1QX9XhFntrJsy
5
+ eiOk2fstz5AXovL6iQIDAQAB
6
+ -----END PUBLIC KEY-----
@@ -0,0 +1,113 @@
1
+ require 'test_helper'
2
+
3
+ describe OmfCommon::Auth::Certificate do
4
+ before do
5
+ OmfCommon::Auth::CertificateStore.init
6
+
7
+ @root = OmfCommon::Auth::Certificate.create(nil, 'omf_ca', 'ca', 'omf')
8
+
9
+ OmfCommon::Auth::CertificateStore.instance.register(@root)
10
+ end
11
+
12
+ after do
13
+ OmfCommon::Auth::CertificateStore.reset
14
+ end
15
+
16
+ it "must create a self-signed root CA cert" do
17
+ @root.must_be_kind_of OmfCommon::Auth::Certificate
18
+ @root.address.must_be_nil
19
+ @root.subject.must_be_kind_of OpenSSL::X509::Name
20
+ @root.subject.to_s(OpenSSL::X509::Name::RFC2253).must_equal "CN=frcp//omf//frcp.ca.omf_ca"
21
+ @root.key.must_be_kind_of OpenSSL::PKey::RSA
22
+ @root.digest.must_be_kind_of OpenSSL::Digest::SHA1
23
+
24
+ cert = @root.to_x509
25
+ cert.must_be_kind_of OpenSSL::X509::Certificate
26
+
27
+ # It is self signed
28
+ cert.issuer.must_equal @root.subject
29
+ cert.verify(cert.public_key).must_equal true
30
+ end
31
+
32
+ it "must create an end-entity cert using root cert" do
33
+ lambda { @root.create_for }.must_raise ArgumentError
34
+
35
+ @entity = @root.create_for('my_addr', 'bob', 'my_resource', 'omf')
36
+ cert = @entity.to_x509
37
+
38
+ cert.issuer.must_equal @root.subject
39
+ cert.issuer.wont_equal cert.subject
40
+
41
+ cert.issuer.to_s(OpenSSL::X509::Name::RFC2253).must_equal "CN=frcp//omf//frcp.ca.omf_ca"
42
+ cert.subject.to_s(OpenSSL::X509::Name::RFC2253).must_equal "CN=frcp//omf//frcp.my_resource.bob"
43
+
44
+ cert.verify(@root.to_x509.public_key).must_equal true
45
+
46
+ @entity.verify_cert.must_equal true
47
+ end
48
+
49
+ it "must verify cert validity" do
50
+ @root.verify_cert.must_equal true
51
+ @root.create_for('my_addr', 'bob', 'my_resource', 'omf').verify_cert.must_equal true
52
+ end
53
+
54
+ describe "when init from an exisitng cert in pem format" do
55
+ before do
56
+ @private_folder = "#{File.dirname(__FILE__)}/../../fixture"
57
+ @cert = OmfCommon::Auth::Certificate.create_from_x509(File.read("#{@private_folder}/omf_test.cert.pem"))
58
+ @key = OpenSSL::PKey::RSA.new(File.read("#{@private_folder}/omf_test.pem"))
59
+ @pub_key = OpenSSL::PKey::RSA.new(File.read("#{@private_folder}/omf_test.pub.pem"))
60
+ end
61
+
62
+ it "must verify itself" do
63
+ # It is a self signed cert
64
+ @cert.subject.to_s(OpenSSL::X509::Name::RFC2253).must_equal "O=Internet Widgits Pty Ltd,ST=Some-State,C=AU"
65
+ @cert.to_x509.issuer.to_s(OpenSSL::X509::Name::RFC2253).must_equal "O=Internet Widgits Pty Ltd,ST=Some-State,C=AU"
66
+ @cert.verify_cert.must_equal true
67
+ end
68
+
69
+ it "must not have pirivate key initialised" do
70
+ @cert.can_sign?.must_equal false
71
+ end
72
+
73
+ it "must have a correct public key" do
74
+ @pub_key.public?.must_equal true
75
+ @pub_key.private?.must_equal false
76
+ @cert.to_x509.public_key.to_s.must_equal @pub_key.to_s
77
+ end
78
+
79
+ it "must have a correct private key associated" do
80
+ @key.public?.must_equal true
81
+ @key.private?.must_equal true
82
+ @cert.to_x509.check_private_key(@key).must_equal true
83
+ end
84
+ end
85
+
86
+ describe "when provided an existing public key" do
87
+ it "must generate a cert contains a converted public key" do
88
+ private_folder = "#{File.dirname(__FILE__)}/../../fixture"
89
+ pub_key = OpenSSL::PKey::RSA.new(File.read("#{private_folder}/omf_test.pub.pem"))
90
+
91
+ test_entity = @root.create_for('my_addr', 'bob', 'my_resource', 'omf', 365, pub_key)
92
+ test_entity.to_x509.public_key.to_s.must_equal pub_key.to_s
93
+ test_entity.can_sign?.must_equal false
94
+ test_entity.verify_cert.must_equal true
95
+ end
96
+ end
97
+
98
+ describe "when provided an existing public cert and I have a private key associated" do
99
+ it "must attach the private key into instance so it could sign messages" do
100
+ private_folder = "#{File.dirname(__FILE__)}/../../fixture"
101
+ key = OpenSSL::PKey::RSA.new(File.read("#{private_folder}/omf_test.pem"))
102
+ pub_key = OpenSSL::PKey::RSA.new(File.read("#{private_folder}/omf_test.pub.pem"))
103
+
104
+ x509_cert = @root.create_for('my_addr', 'bob', 'my_resource', 'omf', 365, pub_key).to_x509.to_s
105
+
106
+ # Now create an instance using this cert
107
+ test_entity = OmfCommon::Auth::Certificate.create_from_x509(x509_cert, key)
108
+ test_entity.to_x509.public_key.to_s.must_equal pub_key.to_s
109
+ test_entity.can_sign?.must_equal true
110
+ test_entity.to_x509.check_private_key(key).must_equal true
111
+ end
112
+ end
113
+ end