Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

encrypted base64-encoded #54

Closed
brianereynolds opened this issue Aug 21, 2018 · 7 comments
Closed

encrypted base64-encoded #54

brianereynolds opened this issue Aug 21, 2018 · 7 comments
Assignees

Comments

@brianereynolds
Copy link

hi, I'm not sure if this is an issue or a misunderstanding on my part.

I've created a signed and encrypted AS/2 request message with openssl (pem files manually extracted from the certs.p12 keystore)

  1. Create signed s/mime message:
    openssl smime -sign -in GETMSG.msg -out GETMSG_SIGNED.msg -signer openas2a_private.pem

  2. Encrypt s/mime message
    openssl smime -encrypt -in GETMSG_SIGNED.msg -out GETMSG_ENC.msg -des3 openas2b_public.pem

  3. The GETMSG_ENC.msg now contains HTTP headers and signed base64 content - manually remove the headers.

  4. Send with cURL

curl -i -X POST \
     -H "Content-Type: application/pkcs7-mime; smime-type=enveloped-data; name=\"smime.p7m\"" \
         -H "Content-Disposition: attachment; filename=\"smime.p7m\""  \
         -H "Content-Transfer-Encoding: base64" \
         -H "MIME-Version: 1.0" \
         -H "AS2-TO: openas2a_alias"  \
         -H "AS2-FROM: openas2b_alias" \
         -H "AS2-VERSION: 1.1" \
         -H "MESSAGE-ID: <OpenPEPPOL-20102017154649+0200-9154@openas2a_alias_openas2b_alias>" \
         -H "Disposition-Notification-To: dummy" \
         -H "DISPOSITION-NOTIFICATION-OPTIONS: signed-receipt-protocol=required, pkcs7-signature; signed-receipt-micalg=required, sha1" \
         --data-binary @GETMSG_ENC.msg \
         http://localhost:8080/as2ReaderService-1.0-SNAPSHOT/as2

The result hits a problem in BCCryptoHelper.decrypt(...) , when creating the new SMIMEEnveloped

org.bouncycastle.cms.CMSException: Malformed content.
        at org.bouncycastle.cms.CMSUtils.readContentInfo(Unknown Source)
        at org.bouncycastle.cms.CMSUtils.readContentInfo(Unknown Source)
        at org.bouncycastle.cms.CMSEnvelopedData.<init>(Unknown Source)
        at org.bouncycastle.mail.smime.SMIMEEnveloped.<init>(Unknown Source)
        at com.helger.as2lib.crypto.BCCryptoHelper.decrypt(BCCryptoHelper.java:413)
        at com.helger.as2lib.processor.receiver.net.AS2ReceiverHandler.decrypt(AS2ReceiverHandler.java:168)
        at com.helger.as2lib.processor.receiver.net.AS2ReceiverHandler.handleIncomingMessage(AS2ReceiverHandler.java:476)
        at com.helger.as2servlet.AbstractAS2ReceiveXServletHandler.handeIncomingMessage(AbstractAS2ReceiveXServletHandler.java:180)
        at com.helger.as2servlet.AbstractAS2ReceiveXServletHandler.onRequest(AbstractAS2ReceiveXServletHandler.java:217)
        at com.helger.xservlet.AbstractXServlet._invokeHandler(AbstractXServlet.java:344)
        at com.helger.xservlet.AbstractXServlet.service(AbstractXServlet.java:524)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:742)
        at com.helger.xservlet.AbstractXServlet.service(AbstractXServlet.java:579)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
        at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
        at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:493)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81)
        at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:650)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
        at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:800)
        at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
        at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:800)
        at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1471)
        at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
        at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
        at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.IllegalArgumentException: unknown object in getInstance: org.bouncycastle.asn1.DERApplicationSpecific
        at org.bouncycastle.asn1.ASN1Sequence.getInstance(Unknown Source)
        at org.bouncycastle.asn1.cms.ContentInfo.getInstance(Unknown Source)
        ... 35 more
Exception in SMIMEEnveloped:Malformed content.
cause:java.lang.IllegalArgumentException: unknown object in getInstance: org.bouncycastle.asn1.DERApplicationSpecific

It seems that the code has passed the base64-encoded content directly into the SMIMEEnveloped method, while it expect the content to already base64-decoded.

Is there an extra HTTP header that I need to provide on the cURL call to ensure the content is decoded before sending to SMIMEEnveloped ?

@phax phax self-assigned this Aug 21, 2018
@phax
Copy link
Owner

phax commented Aug 21, 2018

When sending something to the Mendelson test server, I'm sending these overall headers:

content-type: application/pkcs7-mime; name="smime.p7m"; smime-type=enveloped-data
subject: AS2 test message from as2-lib
message-id: <github-phax-as2-lib-21082018191418+0200-8636@mycompanyAS2_mendelsontestAS2>
content-transfer-encoding: binary
connection: close, TE
user-agent: ph-OpenAS2/AS2Sender
date: Di, 21 Aug 2018 19:14:19 +0200
mime-version: 1.0
as2-version: 1.1
recipient-address: http://testas2.mendelson-e-c.com:8080/as2/HttpReceiver
as2-from: mycompanyAS2
as2-to: mendelsontestAS2
from: phax.as2-lib@github.com
disposition-notification-to: phax.as2-lib@github.com
disposition-notification-options: signed-receipt-protocol=required, pkcs7-signature; signed-receipt-micalg=required, sha-384

so I don't see an issue here.

@phax phax added the question label Aug 21, 2018
@phax
Copy link
Owner

phax commented Aug 21, 2018

Can you please check, if you're payload MIME part also has that Content-Transfer-Encoding. See the following unencrypted example:

content-type: multipart/signed; protocol="application/pkcs7-signature"; micalg=sha-384;    boundary="----=_Part_1_197449185.1534872320450"
subject: AS2 test message from as2-lib
message-id: <github-phax-as2-lib-21082018192519+0200-9539@mycompanyAS2_mendelsontestAS2>
connection: close, TE
user-agent: ph-OpenAS2/AS2Sender
date: Di, 21 Aug 2018 19:25:20 +0200
mime-version: 1.0
as2-version: 1.1
recipient-address: http://testas2.mendelson-e-c.com:8080/as2/HttpReceiver
as2-from: mycompanyAS2
as2-to: mendelsontestAS2
from: phax.as2-lib@github.com
disposition-notification-to: phax.as2-lib@github.com
disposition-notification-options: signed-receipt-protocol=required, pkcs7-signature; signed-receipt-micalg=required, sha-384

------=_Part_1_197449185.1534872320450
Content-Type: application/octet-stream
Content-Transfer-Encoding: base64

VGhpcyBpcyBhIHNpbXBsZSB0ZXN0IG1lc3NhZ2UNCkNoZWNrIG91dCBodHRwOi8vZ2l0aHViLmNv
bS9waGF4L2FzMi1saWINCltFT0Zd
------=_Part_1_197449185.1534872320450
Content-Type: application/pkcs7-signature; name=smime.p7s; smime-type=signed-data
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="smime.p7s"
Content-Description: S/MIME Cryptographic Signature

MIAGCSqGSIb3DQEHAqCAMIACAQExDzANBglghkgBZQMEAgIFADCABgkqhkiG9w0BBwEAAKCAMIIC
....
U/8tOAH8vJUd5Vizg3eMtIAigH7UQ6BZotM05+iGKEbnufnidBb6ZetrkPKNBJzEAE3WSR6ZM2Vu
wJzvkEq9eMvrtWQBpvL6gmOUvzGbjhsaNu+87QAAAAAAAA==
------=_Part_1_197449185.1534872320450--

@brianereynolds
Copy link
Author

When I use openssl to generate the encrypted file, it automatically adds HTTP headers. E.g.

MIME-Version: 1.0
Content-Disposition: attachment; filename="smime.p7m"
Content-Type: application/x-pkcs7-mime; smime-type=enveloped-data; name="smime.p7m"
Content-Transfer-Encoding: base64

MIJt5wYJKoZIhvcNAQcDoIJt2DCCbdQCAQAxggFEMIIBQAIBADAoMCAxCzAJBgNV
BAYTAkFUMREwDwYDVQQDDAhPcGVuQVMyQQIEUYpVwTANBgkqhkiG9w0BAQEFAASC
.... 

Note this is not a multi-part message, it is the set of HTTP Headers you see above with the remainder a B64 string.

I've tried to send the above message as-is, and tried removing the HTTP headers before sending, but the result is the same - "Malformed Content" on the new SMIMEEnveloped(aPart).

The only way I can get the SMIMEEnveloped to accept the payload is to

  • Remove the HTTP headers from the openssl-generated file
  • Manually b64-decode it before sending

Note the curl command is always the same.

Trying out the same with the mendelson server, the signed+encrypted message that is sent is actually a multipart message, so this is probably where the difference lies. For S/MIME enveloped-data, Openssl generates a self-contained base64 encoded string, mendelson generates a multi-part message.

I think this difference is referenced in the RFC 2633, section 3.5.

@phax
Copy link
Owner

phax commented Aug 22, 2018

I think that AS2 is only about multipart messaging.
The title of RFC 4130 is:

MIME-Based Secure Peer-to-Peer Business Data Interchange Using HTTP, Applicability Statement 2 (AS2)

See the variations from RFC 4130 section 4.2

 No encryption, no signature
      -RFC2616/2045
         -RFC1767/RFC3023 (application/EDIxxxx or /xml)

   No encryption, signature
      -RFC2616/2045
        -RFC1847 (multipart/signed)
          -RFC1767/RFC3023 (application/EDIxxxx or /xml)
          -RFC3851 (application/pkcs7-signature)

   Encryption, no signature
      -RFC2616/2045
        -RFC3851 (application/pkcs7-mime)
          -RFC1767/RFC3023  (application/EDIxxxx or /xml)(encrypted)

   Encryption, signature
      -RFC2616/2045
        -RFC3851 (application/pkcs7-mime)
          -RFC1847 (multipart/signed)(encrypted)
            -RFC1767/RFC3023  (application/EDIxxxx or /xml)(encrypted)
            -RFC3851 (application/pkcs7-signature)(encrypted)

   MDN over HTTP, no signature
      -RFC2616/2045
        -RFC3798 (message/disposition-notification)

   MDN over HTTP, signature
      -RFC2616/2045
        -RFC1847 (multipart/signed)
         -RFC3798 (message/disposition-notification)
         -RFC3851 (application/pkcs7-signature)

So I see no variation without MIME

@brianereynolds
Copy link
Author

OK, the items listed in section 4.2 seem pretty clear.

But in practical usage, using the BC SMIMEEnvelopedGenerator along with JceCMSContentEncryptorBuilder to encrypt a MIME message will generate same as what openssl does (example)

I see AS2SenderModule.encrypt uses this code. In truth, I haven't tried to use the AS2SenderModule at all (I'm just interested in receiving messages), but I would expect that if the partnership includes an encryption algorithm => AS2Sender encrypts a message (thus using BC SMIMEEnvelopedGenerator).

@phax
Copy link
Owner

phax commented Aug 22, 2018

The example code you are mentioning does it exactly as it is done in as2-lib.
If I however use the Content-Transfer-Encoding base64 I'm getting a MIC mismatch from Mendelson.
Can you please try to use the CTE binary instead?

@stale
Copy link

stale bot commented May 14, 2019

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the wontfix label May 14, 2019
@phax phax closed this as completed May 15, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants