as2 0.9.0 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e5d44130a76edfd15f3938df800fd0b82a0a14446ed064844250c33f0ba28c0c
4
- data.tar.gz: b2436bd0539cefe5387e08042ba5bf1798282515c17d6c884eda08c7e9abd913
3
+ metadata.gz: 7e21a1d3326b7db528a205964fb6c5e99656ea20e4ad7dcba0877088fdd86104
4
+ data.tar.gz: c46538361b3cdb28f6b97a602465adea7dea2f348dbdc54fd18c33ca7a496801
5
5
  SHA512:
6
- metadata.gz: c7ec66eff025813c21849d375933cef2e06c70ae658363ffce640d22ea72be73650908862307380e70da03510765016b99bf60a65f6f56f432d4e3381eab8ee4
7
- data.tar.gz: 5f9747317e5675e292ea80f02b01de73a0d14e78c60236970f81a8a68a3cefb0535b2bd9c4d2b6fee7e95399746fd773f40de5481db2975fe2f21c9ce5c7178e
6
+ metadata.gz: 52189a26063743097ea72abfe0b12e21866417ab60af8633b581eab7c1902ebb32bf904538daf4301f5320c0cbfd730d94c1aa14f6a365d0ea270158f649565c
7
+ data.tar.gz: ec40485fcd9e7f7f38cbc3649c3b7c84986ebc1be2242a3208c9563d42bea239fb8d4f38a73bd0ce580e54e2371890a45689d138b55c5eccc0c489b6c7526a45
data/CHANGELOG.md CHANGED
@@ -1,3 +1,16 @@
1
+ ## 0.10.0 September 13, 2023
2
+
3
+ support for separate signing & encryption certificates for partners. [#34](https://github.com/alexdean/as2/pull/34)
4
+
5
+ BREAKING CHANGES:
6
+
7
+ * `As2::Config::Partner`
8
+ * Added `signing_certificate` and `encryption_certificate`
9
+ * Removed `certificate`.
10
+ * `certificate=` is still supported, and assigns the same certificate to both.
11
+ * `As2::Client#parse_signed_mdn`: requires `signing_certificate:` rather than `certificate:`.
12
+ * `As2::Message.verify`: requires `signing_certificate:` rather than `certificate:`.
13
+
1
14
  ## 0.9.0, August 28, 2023
2
15
 
3
16
  * Bugfix for quoting AS2-From/AS2-To identifiers
data/lib/as2/client.rb CHANGED
@@ -83,7 +83,7 @@ module As2
83
83
  )
84
84
 
85
85
  cipher = OpenSSL::Cipher::AES256.new(:CBC) # default, but we might have to make this configurable
86
- encrypted = OpenSSL::PKCS7.encrypt([@partner.certificate], request_body, cipher)
86
+ encrypted = OpenSSL::PKCS7.encrypt([@partner.encryption_certificate], request_body, cipher)
87
87
 
88
88
  # > HTTP can handle binary data and so there is no need to use the
89
89
  # > content transfer encodings of MIME
@@ -257,7 +257,7 @@ module As2
257
257
  if mdn_content_type.start_with?('multipart/signed')
258
258
  result = parse_signed_mdn(
259
259
  multipart_signed_message: response_content,
260
- certificate: @partner.certificate
260
+ signing_certificate: @partner.signing_certificate
261
261
  )
262
262
  mdn_report = result[:mdn_report]
263
263
  report[:signature_verification_error] = result[:signature_verification_error]
@@ -314,7 +314,7 @@ module As2
314
314
  # * :mdn_mime_body [Mail::Message] The 'inner' MDN body, with signature removed
315
315
  # * :signature_verification_error [String] Any error which resulted when checking the
316
316
  # signature. If this is empty it means the signature was valid.
317
- def parse_signed_mdn(multipart_signed_message:, certificate:)
317
+ def parse_signed_mdn(multipart_signed_message:, signing_certificate:)
318
318
  smime = nil
319
319
 
320
320
  begin
@@ -347,7 +347,7 @@ module As2
347
347
  # based on As2::Message version
348
348
  # TODO: test cases based on valid/invalid responses. (response signed with wrong certificate, etc.)
349
349
  # See notes in As2::Message.verify for reasoning on flag usage
350
- smime.verify [certificate], OpenSSL::X509::Store.new, nil, OpenSSL::PKCS7::NOVERIFY | OpenSSL::PKCS7::NOINTERN
350
+ smime.verify [signing_certificate], OpenSSL::X509::Store.new, nil, OpenSSL::PKCS7::NOVERIFY | OpenSSL::PKCS7::NOINTERN
351
351
 
352
352
  signature_verification_error = smime.error_string
353
353
  else
@@ -383,7 +383,7 @@ module As2
383
383
  result = As2::Message.verify(
384
384
  content: content,
385
385
  signature_text: signature_text,
386
- certificate: @partner.certificate
386
+ signing_certificate: signing_certificate
387
387
  )
388
388
 
389
389
  signature_verification_error = result[:error]
data/lib/as2/config.rb CHANGED
@@ -12,7 +12,7 @@ module As2
12
12
  end
13
13
  end
14
14
 
15
- class Partner < Struct.new :name, :url, :certificate, :tls_verify_mode, :mdn_format, :outbound_format
15
+ class Partner < Struct.new :name, :url, :encryption_certificate, :signing_certificate, :tls_verify_mode, :mdn_format, :outbound_format
16
16
  def url=(url)
17
17
  if url.kind_of? String
18
18
  self['url'] = URI.parse url
@@ -40,7 +40,17 @@ module As2
40
40
  end
41
41
 
42
42
  def certificate=(certificate)
43
- self['certificate'] = As2::Config.build_certificate(certificate)
43
+ cert = As2::Config.build_certificate(certificate)
44
+ self['encryption_certificate'] = cert
45
+ self['signing_certificate'] = cert
46
+ end
47
+
48
+ def encryption_certificate=(certificate)
49
+ self['encryption_certificate'] = As2::Config.build_certificate(certificate)
50
+ end
51
+
52
+ def signing_certificate=(certificate)
53
+ self['signing_certificate'] = As2::Config.build_certificate(certificate)
44
54
  end
45
55
 
46
56
  # if set, will be used for SSL transmissions.
@@ -87,14 +97,18 @@ module As2
87
97
  unless partner.name
88
98
  raise 'Partner name is required'
89
99
  end
90
- unless partner.certificate
91
- raise 'Partner certificate is required'
100
+ unless partner.signing_certificate
101
+ raise 'Partner signing certificate is required'
102
+ end
103
+ unless partner.encryption_certificate
104
+ raise 'Partner encryption certificate is required'
92
105
  end
93
106
  unless partner.url
94
107
  raise 'Partner URL is required'
95
108
  end
96
109
  Config.partners[partner.name] = partner
97
- Config.store.add_cert partner.certificate
110
+ Config.store.add_cert partner.signing_certificate
111
+ Config.store.add_cert partner.encryption_certificate
98
112
  end
99
113
  end
100
114
 
@@ -123,6 +137,7 @@ module As2
123
137
  @partners ||= {}
124
138
  end
125
139
 
140
+ # TODO: deprecate this.
126
141
  def store
127
142
  @store ||= OpenSSL::X509::Store.new
128
143
  end
data/lib/as2/message.rb CHANGED
@@ -53,7 +53,7 @@ module As2
53
53
  # * :valid [boolean] was the verification successful or not?
54
54
  # * :error [String, nil] a verification error message.
55
55
  # will be empty when `valid` is true.
56
- def self.verify(content:, signature_text:, certificate:)
56
+ def self.verify(content:, signature_text:, signing_certificate:)
57
57
  begin
58
58
  signature = OpenSSL::PKCS7.new(signature_text)
59
59
 
@@ -76,9 +76,9 @@ module As2
76
76
  #
77
77
  # https://www.openssl.org/docs/manmaster/man3/PKCS7_verify.html
78
78
  #
79
- # we want this so we can be sure that the `partner_certificate` we supply
79
+ # we want this so we can be sure that the `signing_certificate` we supply
80
80
  # was actually used to sign the message. otherwise we could get a positive
81
- # verification even if `partner_certificate` didn't sign the message
81
+ # verification even if `signing_certificate` didn't sign the message
82
82
  # we're checking.
83
83
  #
84
84
  # ## NOVERIFY
@@ -87,9 +87,9 @@ module As2
87
87
  #
88
88
  # ie: we won't attempt to connect signer (in the first param) to a root
89
89
  # CA (in `store`, which is empty). alternately, we could instead remove
90
- # this flag, and add `partner_certificate` to `store`. but what's the point?
91
- # we'd only be verifying that `partner_certificate` is connected to `partner_certificate`.
92
- valid = signature.verify([certificate], store, content, OpenSSL::PKCS7::NOVERIFY | OpenSSL::PKCS7::NOINTERN)
90
+ # this flag, and add `signing_certificate` to `store`. but what's the point?
91
+ # we'd only be verifying that `signing_certificate` is connected to `signing_certificate`.
92
+ valid = signature.verify([signing_certificate], store, content, OpenSSL::PKCS7::NOVERIFY | OpenSSL::PKCS7::NOINTERN)
93
93
 
94
94
  # when `signature.verify` fails, signature.error_string will be populated.
95
95
  error = signature.error_string
@@ -121,7 +121,7 @@ module As2
121
121
  @decrypted_message ||= @pkcs7.decrypt @private_key, @public_certificate
122
122
  end
123
123
 
124
- def valid_signature?(partner_certificate)
124
+ def valid_signature?(partner_signing_certificate)
125
125
  content_type = mail.header_fields.find { |h| h.name == 'Content-Type' }.content_type
126
126
  # TODO: substantial overlap between this code & the fallback/rescue code in
127
127
  # As2::Client#verify_mdn_signature
@@ -149,7 +149,7 @@ module As2
149
149
  result = self.class.verify(
150
150
  content: content,
151
151
  signature_text: signature_text,
152
- certificate: partner_certificate
152
+ signing_certificate: partner_signing_certificate
153
153
  )
154
154
 
155
155
  output = result[:valid]
@@ -186,7 +186,7 @@ module As2
186
186
  retry_output = self.class.verify(
187
187
  content: content,
188
188
  signature_text: signature_text,
189
- certificate: partner_certificate
189
+ signing_certificate: partner_signing_certificate
190
190
  )
191
191
 
192
192
  if retry_output[:valid]
data/lib/as2/server.rb CHANGED
@@ -40,7 +40,7 @@ module As2
40
40
  request = Rack::Request.new(env)
41
41
  message = Message.new(request.body.read, @server_info.pkey, @server_info.certificate)
42
42
 
43
- unless message.valid_signature?(partner.certificate)
43
+ unless message.valid_signature?(partner.signing_certificate)
44
44
  if @signature_failure_handler
45
45
  @signature_failure_handler.call({
46
46
  env: env,
@@ -48,7 +48,7 @@ module As2
48
48
  verification_error: message.verification_error
49
49
  })
50
50
  else
51
- raise "Could not verify signature"
51
+ raise "Could not verify signature. #{message.verification_error}"
52
52
  end
53
53
  end
54
54
 
data/lib/as2/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module As2
2
- VERSION = "0.9.0"
2
+ VERSION = "0.10.0"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: as2
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.0
4
+ version: 0.10.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - OfficeLuv
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2023-08-28 00:00:00.000000000 Z
12
+ date: 2023-09-13 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: mail