Mimekit causing bad data when decrypting an email - c#

I have an email application that creates encrypted emails. It works fine in outlook and all the email counterparties I send the email to reports no issues.
However when I try to decrypt them with Mimekit I get a "Bad data" exception.
Some of the stack trace:
at System.Security.Cryptography.Pkcs.EnvelopedCms.DecryptContent(RecipientInfoCollection recipientInfos, X509Certificate2Collection extraStore)
at System.Security.Cryptography.Pkcs.EnvelopedCms.Decrypt()
at MimeKit.Cryptography.WindowsSecure...
My email mime looks like this:
Received: from Dx ([x]) by
x ([x]) with mapi id
x; Fri, 7 Mar 2014 14:48:49 +0100
From: x <x#x.com>
To: x <x2#x.com>
Subject:
xxxxxxxx
07-03-2014 14:48:46
Thread-Topic:
xxxxxxx
07-03-2014 14:48:46
Thread-Index: AQHPOgv3JHiUE6wuJk+EQu4eAA1oDA==
Date: Fri, 7 Mar 2014 14:48:48 +0100
Message-ID: <x>
Accept-Language: da-DK, en-US
Content-Language: en-US
X-MS-Exchange-Organization-AuthAs: x
X-MS-Exchange-Organization-AuthMechanism: x
X-MS-Exchange-Organization-AuthSource: x
X-MS-Has-Attach: yes
X-MS-Exchange-Organization-SCL: -1
X-MS-TNEF-Correlator:
Content-Type: application/pkcs7-mime; name="smime.p7m";
smime-type=enveloped-data
Content-Disposition: attachment; filename="smime.p7m"
Content-Transfer-Encoding: base64
MIME-Version: 1.0
MIIeOgYJKoZIhvcNAQcDoIIeKzCCHicCAQAxggLnMIIC4wIBADCByjCBxDEfMB0GA1UEChMWRGFu
c2tlIENvbW1vZGl0aWVzIEEvUzEaMBgGA1UECxMRQnVzaW5lc3MgU29mdHdhcmUxNTAzBgkqhkiG
9w0BCQEWJmJ1c2luZXNzY2xlYXJpbmdAZGFuc2tlY29tbW9kaXRpZXMuY29tMQ8wDQYDVQQHEwZB
YXJodXMxEDAOBgNVBAgTB0Rlbm1hcmsxCzAJBgNVBAYTAkRLMR4wHAYDVQQDExVkYW5za2Vjb21t
b2RpdGllcy5jb20CAQEwDQYJKoZIhvcNAQEBBQAEggIAVUeGP1IwgqbTvu6w6bIUkhmCjCRhOTqp
tuzSd/ZMfyI95Y/8cxsYf3ivd6AeLld+cn9cyVtnTp6upZNAmetA8QWD2GbCprMDNZpCApuc8Hwc
+nwaa1UN2KJXRf/ecSl+94G/fIxbZ5/53O8KL5RHGkT0AOTWv1Ly8VNWSAzt+QMXkR70OwrWy4Tl
vmPsblCEhz5ViM3hfW1Huz7xJ/I5e1uKLYzDF54OiESR2mAINifgZcP3GR5euP5+iYUaA8aTcKJP
EwsQ6KK2kgSjhcwf2pdfFMJSRloyBLOAVsBbEBMFTFsu4/HPyevDTPYEcoGDVtbUPgmDZLKbqRF+
ZDEIdpHzFj1CvpZBldY4T/4g8uIwyKYBuN/yRIDLbOuGuOHUcS36XzRXNbXvovEP833kUhi1mdeW
hCvYPraF4NdTsEQPvx4wj0mbiREGwUi79iiI8jpR5h75fvbVxS5ACjRtYKq5sNWo/HUBhFElXK1W
AyPQA0QwJyiozKBLuhSwmXQxN12vwH5urXYndST8F2J77t086rX8AEmsoh+DsC3DspqWc1XtUb34
9ag05w0qtLzcmHkt4523LTc339F3bOza2hcNzsOHI0IhJ1VG422i0MswVlpu9lId0aBQcOIy491C
4bR4UQaheqxk+hl4hE05PjR+wgkpU0jFOefLFGrW6SYwghs1BgkqhkiG9w0BBwEwFAYIKoZIhvcN
AwcECDSbIG3hg45PgIIbEJgys8BL0sdAJ9rKjuEPNJqGTgEvF3xdAZWBNhkMFgG35jR1RPOrnGaj
q0TSk7hWHZAMwNlWbyHeRxUpW79fO3e49R2tzQNza25zUI+pViEgPv99IydeSG/on/xdGW25O5V1
kkYeMGqLU/J8cbSo2cRV8u6yiYVQkVaUQ+SKPYMbQ+CK+iIMs09APz5IZO56fx2gozHyBviH9R7x
j1fOz3rJO5CrYMZCPIwYKcNP5kFVtwW8j2DMWhFKNhmRP8eCGillPAEGaY7WjvWHokzxhwf2ptLg
w85zyUcMC5J1B1dfDWu7S6OkhrcjKTw56S/SSkx7tu4bRF7x0TUJk4WgBPhXXhqCcc9de55QHA9J
qslYusogbh7s5GKAWQOTaPI1eUP67SUpR2OxwSCahgoFKAUi1TKQTJlEIsS+juT3VHoo1/1MTxxt
VJJxEE7cxQMRbJG08SILkwRfTveM6YZvJKRe0e6QaWHtSTtmykpIhQWvDq0/HI0XNPc+85rDTLg8
ZSARzD/lMqVqnGxML9Ursvl1ovCJn4LSBuF1Aig+ZsWQcF4iAARBOZEqfM1QXRANCfjYhearfJRS
zJCBgBpiAv40ZKB+FiKDhXG2Wrv+rmGUo8m+u9cOyHUVK7JInQDvDKKZempJ+1KLWElzfp3BivQm
PKJa2bE57BFoEVduyw8S2FEEFhdUMrmOBvTCmapCIUhaj/EUxOjUS55kDh9D3GP+kt638ZsZVUj1
WbqnoOWp0cRWjZbWUiI1IIM/s3XnF890akMg47G3dytKntEvKUQWQFxiTWBrMP4isHmoIhYkGEGA
K16v4jtFRQtlUOkP52CmB6u5F1WnpUueiU+IbVQX8U8yaM8EmIhe6FumDIRkGQTp+LlW0W1fTsnn
lRPwFktm7G0YDZPQoKDsTKqBhfQc4W2ffZxR16RD7C0qgbpRSfuiYqKkVml5LzIQ8F7MyguyIjcH
JpqqYq8HkvuSgy/3mAQkjc1WF4wwmiT5a1/sDZcROBS3u+ASNpdHG43fuXrfhGLg4h/Z3++q+hxZ
L0nuPn77f9FHVWcYYXwhw6pCpBtMbDS7Z5tQ6SI+HlRNjBlBPqcYTGRV2En77IRp40o2kqAG/nbd
YzGMjw37/3p+2ibgeu8pfzgdi5ohMDj59zTCTw+fWc0UhldJzB/NnqJHX6HGXQegaDDLMdRh9BCO
0yyxC2xx5r4Go2BNQye+dler8ZlJbhzyMK3d+Z1y4SdiDe6WyL7+eF3fRg+g3bQ31jvDckug3n1P
UW0i8BUZVfFUacRoDiZRCrsXxL+B3QLpKzh0i5YRyrcivDHAB57+tAhH3KBGhu1oJIbl1HXWXDbt
CAD9ITygKTXJklGlSG8Xxg3l/CKgnH+YO712jPHitYEr/MhM22Rx1IhT/n1qKjbw1iNbo58f1uZK
xyX3H28r0wOM1kEluOb9eCF5jT/FFqkoI5HwHhptzd//xVqC7zA4qxCcr0fmGWbt8XJQxh/FTRWA
1ObpmDy4nLi8P3koDZEfjZ0sb9SRtOJiMdF/4XEP2+TYBLKIbrInX1UoKN/GC0GfRApOCd6KFT+r
ZmLBTKxleJnkvN7CMrVyL05e5WS2kTb20kFHjmdTOzxuvmQDjb797suFCnzJ45XsoaDwJTx/YFGn
1izTlZ6OgHZ5VktiTdmNiWKQ3FS48lJxqn6/KjWV8vVZwtWFb73GQsIuDf/j6P1qDTKkJd+TAlRq
Npa86VElN7YC1xGzp7rbi2AnqjyAVzwKLezTanxJmR9b5htqqPnTWGgKzWtuvptSbS5SYVSnKZAu
UeusmioyhzEL+h1hRzCsg67V6rCtTAd74Wao62piHsnES7Yp1bRVTsQjQj9vj1Jh1KJZFE9o9YQk
2PbQc1Gdtll3ttBeWNe0gt4lj6j5rssLSJibCchfJWzIpYNRGHMPSurg9Z4/yJzlGwEJ8QAhbi3P
EgpMAWc0fWI8MAhWTkEMmLExdeFKrHPK4V8y4fq8cSlpi5xFhnBcjX+GE8zJjZo/HBJIrdDrflGi
dpfSAq1v0dqBCrV4sq8lE4GKThNuCMQokoGFhYqv8sLtsSDbdb0Pjyd/arH7+roTtEii5g3YkoLJ
JWlSQTAvajNQ4gzegGXVZ337ez+QUJ+Oost9BT6AvQmz0HH7LR1nremg/2ujXtipmu5VQG2/59r+
jMY3gOwYJS/r3ya2Py31OtFprtPnupvlq+8KjX82E5sqRBJ9OeE129O7AisT9gxAyvYhopRBr3HV
uz2zNOxudKSBZIy5rbf93ForgqVfN1474NvQCt8OvrjhKyzbwSq95fSV5A2khYz/l4WVujxiqoAf
W4Z+crLJbGKUZKwTgRV79R/3j4MIpuIxcM9GOj8qcQ+RFnOdOUm6dAU/azPXMD1cqVkItEfFoqX3
jvZbCqy9Q3VMEZ/6/Aeg5CBV3DzkOwRGzcbVi/XCPYTQMBn2SSumraKFw1vJsvZK5SdKkN5ayoFj
Xx7rbLDvyjye7MzBgPBvREPrB30BW6gf5Hhtkkw1ZrhfLnp65lAiZhYsyaEkKNmrSAqCx0O5lFwH
8PaullNVqr0jlpcSTarG7fLdfSTl+U0/t+oTM9rEqKDRFpnp2Do8B7m6ZgLo/MjEjnTTA4GpcY/4
c3qI5DN5Cw9RsA6f4t6V865+fblYU8+ibdOifWMm/l+Qd6V9FHIizFDPx0WWK9zgTHFwSVZobFgy
5eQ5ze1ner5oP3EF4qzseQ3XrHs8GvDcSs6/XtGPlOEr+8TW2d86qtQkCSpVFIXz+g+MJcKO7XZk
RDdeNv3AAgxjhMaRE45R/E+Hyum0WEuY1uyEOIKkFdFsn7EaK2fTKbA5NseOsHVchrvdIwK2Q/ym
dOh5KizuU2HPViy34w5jnviEqWnra8yXARZyHc4A4bBCmYWXddzwwwsvOXDqoIYNf71XxCCuE1E8
BZnIRXQ0ZHc173BGOsKsZAWdDeE0c7CyB3w0Q7WqFIw7VHrBvTZtnC5kaPx7eyJoMBlm+FB39Qg3
ycDjPXKkEzalPMtaYlzT8rJIU7LDJ4dS2/ouw4NyphlGycj2qtflpMCpVu/B3PkEAMptWw/iQ9dC
Fm8sfdldFYaPuUVTEogRIrQtM4OTMittrQOvGh9HiJ4oJKnBTMv6xaTR3FND6i1henc4RAcY0qN+
m7RNLhExAebmf1Wi3Rr+o5DI54SD2tmWLXq82GtTxT6rQo6KpCrsSbTgbaOuZ67t8LTrUk+wvpOP
XmANYfRr93m7gBDeEKU0Tr1HUuATD5nwwffjvlzo2ohbUXUZzyQJ+tiUDvvCroT+TuwL6xXu/Cgv
LT8LAnX17ORPuNJrtKrzGRfd/+HAhBi/DNB4wcSlEIjziybH9RcJqEuzmeknpbR9B/60ETTNpogZ
FJ9anY9zaG8vJl9lJW73lMzRabXu0+sB2kScZySFA+NaBWRRI0gxF7D0NMYbfOeo+v5QY4ZOCe+2
Af3o9wAPQNw+iSwreDFXnAhaM+LH3O9XApmQHDTupqqWOeN+oj4Q+k4Z7Wa/k62uRMbjkhMYOa+4
z5YIEcuZIVHNOoGaa65b7ktu6ZBikIIne3jFflCrQON1REHWjhDna4VT344Mh/LjVahl4KHNRIXo
DHE/8BAhRIIfRDWHdWLPR2dOVuoY/FC/OE7bo4byih629BXIxqcx0d/wR2/AJqJWh6gewY0fHWyG
mJzUMkdSAIbP8ufvomCkG89EGzv0TNPckn9hI7Z03umk9PAHIE6LW4Mr+w3bovtZdzE5XRctbgvz
Fxyz7EP/8TlSHfxPjCzAEG1ji2a1Ou4RcexP3yB20u2Z7hNVQoOBfliwrUAIalAw1UfP8eb4GcRT
5qiSDfQF64DLy90CjqG0YFWVbT0XqD2jm98zOyPU/sFUdxYT/xQ6PeSLcHPrs3DxRkIIPMSD/ETb
68lLuh8gOCIHEicX5UUsVknhTxlDqEwNYbmoDoxue3epAWbS1uYrT9qgW6eqz/1cz4MsbBkCPH13
qU9kQjDNIkE5QzBWxGz8s/hv72I2JAq1/e9XvALkAtJutqEZtOaAF+LUv021c74qgjVEPrDNl68t
31AqYp0n8U2oOeFQ1Mwr/W+RHmeMvVgTsn5J3p20vtcshL+di7kGKOVUxoL+m2fiyE6tSzm0Ykgk
OZe6EoecxLbLwDj2s28rJG8KzcQn0vtGL3uc5pNdKz4CHWbpBxoXo5BSKwIfPqIr9LP2BsSqluMc
1EOr9V2qrasnpC/j+vi+wi4gz+3niIb7ZwTgetd+0AuqKrHeBbmr86zMghyKbRdtFj63xjHSoX9k
mBZg7YHDeYXTK5bLWu+MHLn3gTsculxysE/ie3zVnTHTsN8m99WBLPR4ExQ/EHg1e7uMPKHH7MNn
5ZrzXDHzgB++k/nQTTllpJCn0OqieByPmWnnnr6+7xJahdK+vVPLqC4EPb3k4NttLC6GLZSpLbN5
3taVfzUu9ep66jHiQoG131V3t5cwXXgOkmGNs21cQF6pBNM0wp+Jx7DleMeOqSJPbSorjkRIRuZy
j8O1s+DG2V2CvSfDSh08pVQSJYmRrtPYadPMmFckjzbmJaKjfvGqzNjaEYQMAK3jFk3jtCo5/gvh
yp/E3htGh+3wYHZQHDqnXAGycV726TwDELczhd4bp/k6k4c2iGQ2OP7Cp6LeJcWSQDP5VGP24VH0
oDEUwgfm3XuhX7PDtKhxfhKFbomSQL7+og2xFOyb6SXnBnN2obUUjJXNIkGGLGAwRhg2Do2Fwnyn
tEht1DUOpOWKKqDnhRvqSjAK5EIQV7pK3ZxnzbHHsxz3nyqIOwcdPe65kBOhmsKIJCOowPgIxTB0
uTJwRRlCaLN2cKtPAd7k4ynzDOKQaAzHrXCpzmClFeBev4w8T2B8wUH2gSuwlBTLIDsixP2Pom0t
at7ZO5/mNCDtfrg4nCAU+J5pUjhWkiZoGYU3da6AvfjlseqND1UP3ZDw1zWybVbEGuFzsWvqxbOZ
JMhf4jdzAs3dty/rKAkYhldqc7usXIcLm1p++jlEUw4J2Veo0OjWJwMe04UtiEoF4M7KVYVSi9qT
VhqgnxmlRxQDgzAnPOz9rOcK+5ikqs4Zzvh1HfXbTvtyP4wkihV5RViSRSLi9z0x7jBGY8Pt8Fb4
VnEORPbEVjfTEj59BLYdZE4YHzG5+Ug44mQ77mrdKBX3Rr0ms3nY5iZvMu7PqW/cFeG8X+zLrLzx
dT607gtaF9UN+/zWpW77mHR4kQPTLfHYen2QXLD0DXZtJn3YbONrIyTYVbPtynCAqgW424tAWCah
GLQMQP3RzKpnoZtc3D7pIcXuOsfpjcmgjwlklnetzHwTfYIpV8hv9HJvE5khunLxLatEZ/kRq0TD
19EdPJh9hBzXmvkhmvm1mSBLf1FKO/o0nZ8DEh+O0UX8W2g+r88rf1y/G0GC/J60R1Tutm7kzjuQ
Wn5LT4Me6fvSA8P8zlFgbU9Z0Hm0U8RJLOs1VVm5itdz6uXq4e5lL8nOnNg5wD3Vf4PvRTnZCWo5
1bQhnU+3Z7JEGqlS+Ahy3e3paiBKXk5bHF1D688VM4vy095P4cQoo7mqji4xCc5Miy3Wv0sb/ZQT
LbyF0p+ibDn6sHWhvlppQCTtaeaeDtyMQUecWYNvxeux8vHep+9tgPIZ3FU7B9EqrU/8fClPFIDQ
W62644VAJSTlih5/peKdOHTDouyR17ukSM1S2AF/r6WoQ58tKmNyOReLXp1yIIs5ktk3/23tT2ws
DSFBkvWqdv7c6xQp406WGk4i8gCWUXNwn203V9TDNPq/tj5g6bNzs0jSoUv/jNdpOTlmdq5L91f3
xqfZR9nZrUo8CNLIV6aZ4KPBLBg3XNncL6NNvt4FQAar3ktLd7oDjkCAce/oOD7qFKLKRtDTLSJw
TThvUvsXcOuisd8J/4ABfq/fpIg1ds44KCtVisg3zuIa4yjcWEO/qn8wxPe+bIkGRpf+d45QISTv
jHzIxKruw9XcLvLQsw+8uMbg/SLZXUN5AQz4aWY20o9j6i2CQP6QesBrW4lGAG46FV+U3xfR5asc
dtrgyaBhllfjmjFkBns9oYQMP6yle9KyOsaU1Mmil7A1tSSaeyIpobzZUWq43XqyYHrUrRANAfb6
KFyGWAVpZ98sejod9YlqGUuPnLahSnxdiATpjJg8BkvUZ5nOhfP0Me5JAwiO18mBNEnBE/IAFJsx
P8MYD0BVSys1g7ycyaVU1bMdL8r9fs85i3aoTsr2B923blVoI86GJd5sjdytBdrMOTCebcYq2XeS
pjHGBIijtCm7+QHYzyeEg13QiH9X5SskUYsu2z9C35L3umyCart2FbPFU3l6ebf4M1EHe35A/U8n
416SD8AFpTUV716g4winlq6f9LuG8I5zlS2N5feGEAF7f8Xb9eCyVpEJrHuP7MD2jDIuAuXZbCMZ
w1uK/NVBesxcrckagZKo//hw3FlqgGj1VIeBsn6wgrWR36bVeLJCaYdVwD682cIxsNbwp2KKNWnd
yBbTy2hs7sCLnwvD9CXSn57UZAVhrfZJi86W4eoVpk/qGYz5KmsRgp26ahcECKb7KQz+eWY9gouI
NAEGL8+BdHk8jp59s8OOqtMq3/9qnw1EcXQ+Cx0w9HLyeZq4Mbq/vMr9q61ps4dhOmD78rRwVnai
qxhYi5GSk83E7XHRlEMR3KWWo2iV6QMOT2yAZ5x6xUQ1x0VEH+coXiYPyNR7q7b0wNGVETit9tT2
RgNJ3ZcoRmVRboumRcbpUYj1nqATeaiKJTMmJHMNDyVAGPlv6aMjmHAWlxAaTTVnRK2OOMj/oOMD
ajGVWXUKLvdFjMy9fw98fmBWKSHrp6RshdgI7pS7AgRfHwqqykyalzO73Te7xO8Wie71hMVKIj6z
oholmbEPtuPNgDWOA2pdadvPfQe71TebzoX8mE0KVKTf0tPKlNww3HAMLMpmnJTueWFT1qPG8qOz
ANZXWwkBhj16ynY1vgRhTaRqI0MMW0TUA65ddMLDJhDEs6WbZnv2n0QRNMJkLrruClNIzQDJq+I3
ldHuItOdrHUVgclder6b/eeev+LWS7eTy6hEp+ECv9w68wF1H+PjwCMHxQsoxSdz8ppcvG3d6x49
2LwiVHdp9C9c73fPlVTK8krdBnVA81LNpstNG9vplSDZZa2xZRMS1iTDw26jDAMWqm+I8MWzNQTn
8amVg7OxifwOGtnLpGhzUL4wnzjQoGGI81Ny4demk3pQGW4D9B1bO6WCkIjaCFwH2YHXLixzrMJ9
9RUQLamW3GtwTSWJsmSPdLVetyq17FRUc/mw5qjHheG5BNTEk+6hdIth+SOMqhhiFLF4z6Cpr22P
7hHZLcRVBoVLyxFHncGr1y8FpLLpJ1F4VacVI1H0bPECNGMaud5FeA5YxP4b366DKgoCvUAUd1Cu
H2zuGW7EWgcE/0N4HwjKBvjcu07kSDzydzEbzGEfaSsTdJm0ABiM1A2eX0yY8QBP7TzdIcUgQCbb
LPCkXeBjGt+2fiqg7p0Iay7/1+ds0mM0jCDK4cq21z1EJwHEfPUZPhqy/wY8QUWgsUP/so4MUbzA
y/MfdJBwYdeNWjP99gXaBPqnd8bAo9s+yrkOEzIFErQk6um8eclBnx1auQwuRgeuRsArsQM+JsO7
/lgFFuRQYdWqsDcNV0sqUUmlc3p+wMQR3uGdRP0IyAdsOW4dNT+4wQTubD3Go84JgliGaFTHVqmZ
Q9dc3f3KY+xm1A2mDBmE8YG+HpvhMuHVCSgEViM9uxaH9XLJPeWO705MLIq4vVFH4V3P2D7NYEuq
60QuNCVgT4zbVvsPpPkdT30yf3oq/hNS0lH4fjoq8WVTHdr8dVHnlSym8E9B9h1SKUDx/xYjZIoB
VLtVCdlh3E38tWFXj64rf83z2RWsjLmEtgK1kPGlpR9KfM/P5NvucpXrLWmgJzF/jkSMxGukLgZv
N613kBpDOfZhux0EuE0gOMr3fqu4WIsfkazJ174RM2mRiwsUI2agC0PqHTSJzBqPooCQo4G+cr8d
dg7WhPFH3qXGhLq2qxK+iLBXqtLnSVCo6bbFOYSo/UVVKuF2jyZD4WBmlRDg9i7O3nNnsoebDXA0
YKsRQE7uvzQzMrgB2Qw+yh8Gops5lFWsHqH9bN2P/ejVHpIIXtNOGl4vlTL1PzqVHC5G6Y1zNSw3
+aZwi+WILqxB0XxkBo6fRxKVzATygOBfFR7aShuCQjwYxR0bYq7qchy6zyfbNsm1gGJjMZnJiT8j
nhKRS+R71Q6WKvqYw7rtiSGCfH/tgwV4MoysuWNxhO1oJA7FxnEBymFvGDMNbU4XQ+tZqajOiP4O
ayaVoo6aeAZhT3Fms4BPYtQmy1x5iPuy1XZEtZwjb5YVoVMdkCps0Prd2GHWq9ZOEZ75XXLl6zff
4H1mAiBctyFXGV2gcojsTWzeDu4bGihsijrFBoCN2j018Hk33Ac8nza2jW4UgE6Bw4IJebTdgH5x
NLNCXYdiXVZ/N4OQEfHSnZ3FGhIqCBGVxj8EG1GQL/+2uSolGZezY2wWPAJPHVJ/3O0eknhWjpOc
x9NHNbMHGyiRxKPOGHB1ffe1q+S6QUQ3ghngo2rKsZbR7C8nijdFcgUI0tpCqGwUA+72TYtIi2ui
QxGfJvXgXYsAn5gFbrrpxRaT0yYr5OaMuZuCmJopKyTDE/2mjuxaexFTklhMgClTULWnOuBv5j2b
FFDrtIJTHuM8F1laq5k5ehiWVRYWjh3ZMTBWeecEoWaIobMNYvTD3xbSzx6SH+20T59rdR8p0mJB
ECVc0pl3QQugE5w0Qrp7/CJ2Pxrmcc7tCWdnVOjglp3JcUBL2ZRJeQBPk5Bm6OCczR+sviFux2Me
MF/3E7TSRspBPscL9XHHH8eBznnjZ8fJAu0YAhTGjzL1DOjjVZ9KNlxWwGG+mCALm+XU8DpJNKg9
Nuq2uYSRu4p5K4+lEAyRM2cdiPLVcDuGKQpBGQnhsB6DslLImiYXSzy6OcHIsUf4kyAGes5tsBxR
i1IfNHcW4G/7i4VUy+530PqA0+TECNkpgiGxrevWk0gF0NgD+DDNgDzZRjJaRpMx0ufbP9twVvv+
6J/meqKiykYcU/NUYV/TuNiERKrOOWZs697IyY/g3nPWHZurZXJbmk9MpND2wn5PZzRTx7qyBVfn
nenl/WtSVMmKA4D1dLnHoeN1hoAyQgrfqS4yymL26UemhCXIV87hAYwwoAbpfr4=
This is how I perform my encryption:
public static string EncryptContent(string content, X509Certificate2 certificate)
{
byte[] contentBytes = Encoding.ASCII.GetBytes(content);
var envelopedCms = new EnvelopedCms(SubjectIdentifierType.IssuerAndSerialNumber, new ContentInfo(contentBytes));
var recipient = new CmsRecipient(SubjectIdentifierType.IssuerAndSerialNumber, certificate);
envelopedCms.Encrypt(recipient);
var encodedData = envelopedCms.Encode();
var encodedDataBase64 = Convert.ToBase64String(encodedData, Base64FormattingOptions.InsertLineBreaks);
return encodedDataBase64;
}
and this is how I attempt to decrypt:
var primarySecureMimeContext = CreateSecureMimeContext(certificateInfo.PrimaryCertificate,
certificateInfo.PrimaryPassword);
var primaryDecryptedEntity = entity.Decrypt(primarySecureMimeContext);
private SecureMimeContext CreateSecureMimeContext(string certificateFilename, string certificatePassword)
{
var secureMimeContext = new WindowsSecureMimeContext();
var certificate = new X509Certificate2(certificateFilename,
certificatePassword);
var bouncyX509Certificate = Org.BouncyCastle.Security.DotNetUtilities.FromX509Certificate(certificate);
secureMimeContext.Import(bouncyX509Certificate);
return secureMimeContext;
}
When I decrypt the content myself using enveloped cms directly, there are no issues.
This is the email after my own decryption:
Content-Type: multipart/mixed;
boundary="5511bd79-26dc-41e5-ac96-7adfdea5f6e5"
--5511bd79-26dc-41e5-ac96-7adfdea5f6e5
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: quoted-printable
--5511bd79-26dc-41e5-ac96-7adfdea5f6e5
Content-Type: application/octet-stream;
name="TestFile.txt"
Content-Transfer-Encoding: base64
Content-Disposition: attachment;
filename="TestFile.txt"
77u/VGVlZWVlZXN0
--5511bd79-26dc-41e5-ac96-7adfdea5f6e5--
Can anyone see what is causing this?
After having using the DummySecureMimeContext as proposed by jstedfast it works. A more thorough walkthrough can be found here: https://github.com/jstedfast/MimeKit/issues/38

I think the problem is the way you are adding the certificate to the context:
private SecureMimeContext CreateSecureMimeContext(string certificateFilename, string certificatePassword)
{
var secureMimeContext = new WindowsSecureMimeContext();
var certificate = new X509Certificate2(certificateFilename,
certificatePassword);
var bouncyX509Certificate = Org.BouncyCastle.Security.DotNetUtilities.FromX509Certificate(certificate);
secureMimeContext.Import(bouncyX509Certificate);
return secureMimeContext;
}
What this is doing is adding the certificate to the AddressBook certificate store, but where you actually want to add it in order to decrypt it (because you'll need the private key password as well) is the personal cert store.
Try this:
private SecureMimeContext CreateSecureMimeContext (string certificateFilename, string certificatePassword)
{
var secureMimeContext = new WindowsSecureMimeContext ();
using (var stream = File.OpenRead (certificateFilename))
secureMimeContext.Import (stream, certificatePassword);
return secureMimeContext;
}
The exception message you are getting isn't very helpful, but I am guessing that it means that it can't find the certificate and/or private key. I wrote a test program and have been unsuccessful in reproducing this bug, so I could be wrong... but since my certificates/private keys are already imported into my personal cert store, I'm not sure how to remove them to test this theory.
Let me know how that works out for you.
Update: Oops, I done goofed. Just updated CreateSecureMimeContext() above to open the certificate file stream because WindowsSecureMimeContext.Import() takes a stream, not a file name.

Related

C# Azure - Specified Resource not found after moving from Microsoft.Azure.Cosmos.Table to Azure.Data.Tables

I have an Azure storage account with a table that we are trying to access using C# in a function app. I migrated over from the deprecated Microsoft.Azure.Cosmos.Table library to Azure.Data.Tables.
I get an error when trying to query the table for an entity.
{
"The specified resource does not exist.
RequestId:8612b003-0002-0071-64b2-054424000000
Time:2022-12-01T18:27:02.5504487ZrnStatus: 404 (Not Found)
ErrorCode: ResourceNotFound
Content:
{
"odata.error":
{
"code":"ResourceNotFound",
"message":
{
"lang":"en-US",
"value":"The specified resource does not exist.
RequestId:8612b003-0002-0071-64b2-054424000000
Time:2022-12-01T18:27:02.5504487Z"
}
}
}
rnrnHeaders:rnCache-Control: no-cacher
Transfer-Encoding: chunked
Server: Windows-Azure-Table/1.0,
Microsoft-HTTPAPI/2.0
x-ms-request-id: 8612b003-0002-0071-64b2-054424000000
x-ms-client-request-id: c1668171-b91f-4eba-b2d1-1fef1120595a
x-ms-version: REDACTED
X-Content-Type-Options: REDACTED
Date: Thu, 01 Dec 2022 18:27:02 GMT
Content-Type: application/json;
odata=minimalmetadata;
streaming=true;
charset=utf-8rn"
}
Old previous working code
var primaryCloudStorageAccount = CloudStorageAccount.Parse(Environment.GetEnvironmentVariable("EntityRegistryStorageAccountConnectionString"));
var tableClient = primaryCloudStorageAccount.CreateCloudTableClient();
_registry = tableClient.GetTableReference("EntityRegistry");
Code with new libary that is not working
private readonly TableClient _registry;
_registry = new TableClient(Environment.GetEnvironmentVariable("EntityRegistryStorageAccountConnectionString"), "EntityRegistry");
Also tried this
var tableClient = new TableServiceClient(Environment.GetEnvironmentVariable("EntityRegistryStorageAccountConnectionString"));
_registry = tableClient.GetTableClient("EntityRegistry");
Error is thrown in this code
var registryRecord = await _registry.GetEntityAsync<TableEntity>(entityType.ToString(), registryId);
This also returns a 404 error
var registryRecord = await _registry.GetEntityIfExistsAsync<TableEntity>(entityType.ToString(), registryId);
I know the table exists and it seems to be authenticating me, I can see the URL that is being set on the TableClient and it matched what I see in Azure. I also use the connection string from Azure that has the account and key.
What could be going on with this?
Important note!
In the past library, the GetEntity call would be okay with returning null if the record does not exist. In this case, you need to call GetEntityIFExistsAsync and parse the value returned, it won't just return null like it did previously if the value does not exist.
var registryRecord = await _registry.GetEntityIfExistsAsync<TableEntity>(entityType.ToString(), registryId);
if (registryRecord.HasValue)
return registryRecord.Value;
else
return null;

Construct MIME message for outlook compatible meeting invitation

I am failing to construct a MIME message that is displayed as a meeting invitation in Outlook, compared to when sending an invitation natively via Outlook.
What I want is this view (at least more or less):
What I get instead:
(The file displayed as .ics attachment can be opened and shows correct content).
Here's the meeting body (ics), that I construc programmatically:
BEGIN:VCALENDAR
VERSION:2.0
PRODID:123
CALSCALE:GREGORIAN
METHOD:REQUEST
BEGIN:VTIMEZONE
TZID:Europe/Amsterdam
BEGIN:STANDARD
TZOFFSETTO:+0100
TZOFFSETFROM:+0100
END:STANDARD
END:VTIMEZONE
BEGIN:VEVENT
DTSTART;TZID=Europe/Amsterdam:20201214T085500
DTEND;TZID=Europe/Amsterdam:20201214T095500
SUMMARY:Test Event
LOCATION:skico HQ
DESCRIPTION:A test in appointment chatbot
PRIORITY:3
END:VEVENT
END:VCALENDAR
The MIME message is built via MimeKit:
private static string BuildMimeContent(Mail mail)
{
var textBody = new TextPart("plain") { Text = mail.BodyText };
var htmlBody = new TextPart("html") { Text = mail.BodyHtml };
var alternative = new Multipart("alternative");
alternative.Add(textBody);
alternative.Add(htmlBody);
var multiPart = new Multipart("mixed") { alternative };
if (mail.Event != null)
{
var eventBody = mail.Event.Parse();
var calendarBody = new TextPart("calendar")
{
Text = eventBody,
ContentTransferEncoding = ContentEncoding.Base64
};
calendarBody.ContentType.Parameters.Add("method", "REQUEST");
calendarBody.ContentType.Parameters.Add("name", "meeting.ics");
alternative.Add(calendarBody);
}
var mimeMessage = new MimeMessage();
mimeMessage.From.Add(new MailboxAddress(mail.Sender.Name, mail.Sender.EMail));
mimeMessage.To.Add(new MailboxAddress(mail.Recipient.Name, mail.Recipient.EMail));
mimeMessage.Subject = mail.Subject;
mimeMessage.Body = multiPart;
// parse and return mime message
return mimeMessage.ToString();
}
yielding:
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="=-rdfmBTE1TuDNFI0Wzfmibg=="
--=-rdfmBTE1TuDNFI0Wzfmibg==
Content-Type: multipart/alternative; boundary="=-6bp3YWbl6STSnwQq7Fne2A=="
--=-6bp3YWbl6STSnwQq7Fne2A==
Content-Type: text/plain; charset=utf-8
Hi!
--=-6bp3YWbl6STSnwQq7Fne2A==
Content-Type: text/html; charset=utf-8
<strong>Hi!</strong>
--=-6bp3YWbl6STSnwQq7Fne2A==
Content-Type: text/calendar; charset=utf-8; method=REQUEST
Content-Id: <123#s.com>
BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//Microsoft Corporation//Outlook 15.0 MIMEDIR//EN
CALSCALE:GREGORIAN
METHOD:REQUEST
BEGIN:VTIMEZONE
TZID:Europe/Amsterdam
BEGIN:STANDARD
TZOFFSETTO:+0100
TZOFFSETFROM:+0100
END:STANDARD
END:VTIMEZONE
BEGIN:VEVENT
DTSTART;TZID=Europe/Amsterdam:20201214T120800
DTEND;TZID=Europe/Amsterdam:20201214T130800
SUMMARY:Test Event
LOCATION:skico HQ
DESCRIPTION:A test in appointment chatbot
PRIORITY:3
END:VEVENT
END:VCALENDAR
--=-6bp3YWbl6STSnwQq7Fne2A==--
--=-rdfmBTE1TuDNFI0Wzfmibg==--
How does the MIME content need to be constructed instead, such that the alternate view works in Outlook?
There was something wrong with my ICS content. This fixed it:
BEGIN:VCALENDAR
PRODID:-//Microsoft Corporation//Outlook 15.0 MIMEDIR//EN
VERSION:2.0
METHOD:REQUEST
BEGIN:VEVENT
DTSTART:20201214T121600Z
DTEND:20201214T131600Z
SEQUENCE:0
UID:56b39b14ebb641ab7de716a62bed46aa
DTSTAMP:20201210T121600Z
LAST-MODIFIED:20201210T121600Z
SUMMARY:Test Event
LOCATION:s HQ
DESCRIPTION:A test in appointment chatbot
END:VEVENT
END:VCALENDAR
I did not track it down to the root cause. Probably the UID is madatory or the date/timezone format was invalid before.

Using MimeKit to cms sign and verify

I am using Mimekit to do rsa pss cms sign, to simulate this openssl command
openssl cms -sign -in keys.zip -binary -nodetach -signer selfsigned.crt -inkey keypair.pem -out keys.zip.signed -keyopt rsa_padding_mode:pss
public byte[] Sign(byte[] data, byte[] signCert, byte[] privateKey, CmsKeyOpt cmsKeyOpt)
{
MimeMessage message = new MimeMessage
{
Body = new MimePart()
{
Content = new MimeContent(new MemoryStream(data)),
ContentTransferEncoding = ContentEncoding.Binary,
},
};
// Load private key from byte array
StreamReader stream = new StreamReader(new MemoryStream(privateKey), Encoding.Default);
AsymmetricCipherKeyPair keyPair = (AsymmetricCipherKeyPair)new PemReader(stream).ReadObject();
// load certifacte from byte array
X509CertificateParser parser = new X509CertificateParser();
X509Certificate certificate = parser.ReadCertificate(signCert);
// Create RSA PSS CMS signer
CmsSigner signer = new CmsSigner(certificate, keyPair.Private)
{
RsaSignaturePadding = RsaSignaturePadding.Pss,
DigestAlgorithm = DigestAlgorithm.Sha256,
};
// Create BouncyCastle Secure MimeContext
BouncyCastleSecureMimeContext ctx = new TemporarySecureMimeContext();
ctx.EncapsulatedSign(signer, new MemoryStream(data));
// Get signed message body and override it
message.Body = MultipartSigned.Create(ctx, signer, message.Body);
byte[] singedData;
using (var memory = new MemoryStream())
{
message.WriteTo(memory);
singedData = memory.ToArray();
}
return singedData;
}
And everything works fine, my question how I can achieve verify by Mimekit/BouncyCastle, to simulate this openssl command
openssl cms -verify -in keys.zip.signed.dec -CAfile selfsigned.crt -out keys_dec_unsigned.zip
I tried this but I got exception System.NotSupportedException: 'SQLite is not available on pkcs7.Verify(out original) line
public byte[] Verify(byte[] data, byte[] signCert, byte[] privateKey)
{
bool valid = false;
// Load private key from byte array
StreamReader stream = new StreamReader(new MemoryStream(privateKey), Encoding.Default);
AsymmetricCipherKeyPair keyPair = (AsymmetricCipherKeyPair)new PemReader(stream).ReadObject();
// load certifacte from byte array
X509CertificateParser parser = new X509CertificateParser();
X509Certificate certificate = parser.ReadCertificate(signCert);
MimeMessage message = MimeMessage.Load(new MemoryStream(data));
// Create BouncyCastle Secure MimeContext
MimeEntity original;
ApplicationPkcs7Mime pkcs7 = message.Body as ApplicationPkcs7Mime;
if (pkcs7 != null && pkcs7.SecureMimeType == SecureMimeType.SignedData)
{
foreach (var signature in pkcs7.Verify(out original))
{
try
{
valid = signature.Verify();
}
catch (DigitalSignatureVerifyException)
{
// There was an error verifying the signature.
}
}
}
byte[] res = { 0 };
return res;
}
Is there any guide I can follow to verify and return the data to it's origin forum, or an example?
By default, MimeKit tries to instantiate a S/MIME verify context based on its SQLite backend for certificate storage.
If you don't have SQLite installed and/or don't have your certificates stored in the SQLite database that MimeKit will maintain for you, then you need to either register a different backend for certificate storage/retrieval or instantiate your own S/MIME context (like you did for signing).
MimeKit comes with 2 options:
TemporarySecureMimeContext which stores certificates in memory and is what you used to sign the message in your code snippet above.
WindowsSecureMimeContext which uses the Windows OS X.509 certificate store.
Once you decide on which of those to use, you will need to import your certificate(s) into the context (which will import them into the appropriate backend storage location).
Then, after that, you can do this:
using (BouncyCastleSecureMimeContext ctx = new TemporarySecureMimeContext()) {
ctx.Import (...);
foreach (var signature in pkcs7.Verify(ctx, out original)) {
// ...
}
}
Update:
This devolved into misuse of the openssl cms sign command and an inability to verify the signature using MimeKit because MimeKit expects the encapsulated signed data to be in MIME format as it is supposed to be according to the S/MIME specifications.
Here's the deal:
The openssl cms sign command can be used to sign arbitrary data and the corresponding openssl cms verify command can be used to verify such signed output. HOWEVER, it is only valid S/MIME if the original content signed by the openssl cms sign command is/was in MIME format.
MimeKit expects valid S/MIME because it is... surprise, surprise... a MIME library.
As you might have noticed, the Verify() method has an output parameter (out MimeEntity originalEntity). This means that the Verify() method extracts the encapsulated content from within the signed data and parses it into a MIME entity and returns it to you, the caller, in the form of said output parameter.
If the encapsulated content is not in MIME format, then, obviously, the parser will fail to parse it.
Additional background with how CMS signatures work:
When you sign content using the CMS signing routine (e.g. openssl cms sign ...), it produces something that looks a bit like this:
MIME-Version: 1.0
Content-Disposition: attachment; filename="smime.p7m"
Content-Type: application/pkcs7-mime; smime-type=signed-data; name="smime.p7m"
Content-Transfer-Encoding: base64
MIIQgAYJKoZIhvcNAQcCoIIQcTCCEG0CAQExDTALBglghkgBZQMEAgEwggkPBgkq...
The base64 content in the above MIME part includes both the original content and the CMS signature data (i.e. a list of signatures).
Therefor, MimeKit's Verify() method needs to separate the signatures from the original content after base64 decoding it. MimeKit then returns to you, the caller, the original content (which it expects to be in MIME format) and the list of signatures that you can then independently verify the authenticity of.
When I kept repeating myself that it mattered what format the file.bin file was in when you signed the content, I was not saying that openssl or MimeKit needed to parse file.bin when verifying the signature, I was saying that file.bin has exactly the same content as what would be extracted from the base64 blob in the S/MIME output produced by openssl cms sign ... and therefore, it needs to be in MIME format.

Verify pkcs7 Signature received from AS2 trading partner

I am receiving an AS2 message from my trading partner. I have successfully decrypted it and it has following content:
Content-Type: multipart/signed; boundary="----1E2FB76A361B53C9D12B3971C32BC0D8"; protocol="application/pkcs7-signature"; micalg="sha-256"
------1E2FB76A361B53C9D12B3971C32BC0D8
Content-Transfer-Encoding: binary
Content-Disposition: attachment; filename="edi.dat"
Content-Type: application/octet-stream; charset="ascii"; name="edi.dat"
ISA*00* *00* *ZZ*SPSAS2 *ZZ*SPSAS2 *140919*1159*|*00501*100000001*0*P*>
GS*PO*AS2S3REC*AS2S3SEND*20140919*1159*123*X*005010
ST*850*1234
BEG*00*SA*SPSAS2TEST**20121017
REF*IA*TEST
PER*OC*Someone*TE*2844994944
DTM*001*20121025
N1*ST*SomeoneElse
N3*My address is private
N4*ST THOMAS*VI*00801
PO1*54812*1*EA***SK*123546*VP*123546*UP*123456987111
CTT*1
SE*11*1234
GE*1*123
IEA*1*100000001
------1E2FB76A361B53C9D12B3971C32BC0D8
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="smime.p7s"
Content-Type: application/pkcs7-signature; name="smime.p7s"
MIIL5gYJKoZIhvcNAQcCoIIL1zCCC9MCAQExDzANBglghkgBZQMEAgEFADALBgkq
hkiG9w0BBwGgggg3MIIIMzCCBxugAwIBAgIQCq+jbObLeCwtsdF61BAtBzANBgkq
hkiG9w0BAQsFADBNMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5j
MScwJQYDVQQDEx5EaWdpQ2VydCBTSEEyIFNlY3VyZSBTZXJ2ZXIgQ0EwHhcNMTgw
MjA5MDAwMDAwWhcNMjEwMjE3MTIwMDAwWjCBgjELMAkGA1UEBhMCVVMxEjAQBgNV
BAgTCU1pbm5lc290YTEUMBIGA1UEBxMLTWlubmVhcG9saXMxGzAZBgNVBAoTElNQ
UyBDb21tZXJjZSwgSW5jLjELMAkGA1UECxMCSVQxHzAdBgNVBAMTFnNwc2FzMi5j
b21tZXJjZXZhbi5jb20wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCw
1fJZ14+32k+Qutklk2+YYxaPMe2ASv41lfR5945H6M2SmdgFqqF2LPNZqWofcBPQ
HbMWctbBHOW1shOS2XvBRUFT5tuyQKcG4iYz7FEHFGpu4oGyC0eUYSuBBtTQMmRi
zk8bMwwNhRUUyzxa/y3OePK0lEDdaQsSKi8WHLkfkVZBo7Lk9CPyR4WZ8q8uo/qW
tNMDbk1Fn2CtXqYrXFTmLJ81ScXGTp5zoIUhrkGcUzumK+25EBT9p+2XcVMCUj9S
LY1DWyTnWx2mgT0ekeHM0pXV2MPDuUG99SiQB4Q0CH0I3J4ZafP2rCzBVkvNlTFJ
ZojaQyfcP9W73ZiYSgUmQ3mCa/BjACTO8wztu9DBelUNVjSxCYysGUdKNyl6hAAI
OAPe8z0mmDCVA7S4rnTYkliW+2JQdOTaKc0GOiaHQjrd+Gta1aAJHRR1pxjSX2FC
apS3DkiJl4i5vdyPZM53QhS51XCxGHtCCcJ574MIPkthI4SLwKJkk6rSgvb7B0ai
7jbDmvp1FjY0SgKoHyN+QNH1J4rMeK7IUp2N0R+YrJa6kEaocIptSoPToDGKWk+o
qAx65r3T2n21jEfiCzN6JyqxNfE1T35Pekpvu4ioUEfW1ICf6AOQ5oQHWLr/Fhk2
sVzptYw5Lmtkb/sPGP1R/hBy88HAlTAh+QFrRJHHWwIDAQABo4ID1zCCA9MwHwYD
VR0jBBgwFoAUD4BhHIIxYdUvKOeNRji0LOHG2eIwHQYDVR0OBBYEFJs5x7uPOhBe
2Mp1aThYg8urrQ4FMCEGA1UdEQQaMBiCFnNwc2FzMi5jb21tZXJjZXZhbi5jb20w
DgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjBr
BgNVHR8EZDBiMC+gLaArhilodHRwOi8vY3JsMy5kaWdpY2VydC5jb20vc3NjYS1z
aGEyLWc2LmNybDAvoC2gK4YpaHR0cDovL2NybDQuZGlnaWNlcnQuY29tL3NzY2Et
c2hhMi1nNi5jcmwwTAYDVR0gBEUwQzA3BglghkgBhv1sAQEwKjAoBggrBgEFBQcC
ARYcaHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzAIBgZngQwBAgIwfAYIKwYB
BQUHAQEEcDBuMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20w
RgYIKwYBBQUHMAKGOmh0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2Vy
dFNIQTJTZWN1cmVTZXJ2ZXJDQS5jcnQwDAYDVR0TAQH/BAIwADCCAfYGCisGAQQB
1nkCBAIEggHmBIIB4gHgAHYApLkJkLQYWBSHuxOizGdwCjw1mAT5G9+443fNDsgN
3BAAAAFhezY//QAABAMARzBFAiEA/peliWFFZt3DPuaO1JekVr9XQhfW/SeCVONq
Rmju3zECIDByDCYP5dzgszieTnkpP3w5dsOfiVmJ+RRmuNORjb0rAHYAh3W/51l8
+IxDmV+9827/Vo1HVjb/SrVgwbTq/16ggw8AAAFhezZA2gAABAMARzBFAiEAmlnD
uPy34+XDxNZU8r0dD4fI+hFJwxQQkatA9zkIzegCIFxT3jLCCf9pVoEIeWYBOv3C
BjVqsn0jDqXLYSVOJTQVAHYAu9nfvB+KcbWTlCOXqpJ7RzhXlQqrUugakJZkNo4e
0YUAAAFhezZAzAAABAMARzBFAiEAwAWMiOFLxRBqVjLc/cktB7SjMujisPPx5WQA
Bat22NoCIAtVJcU2yoj6c66x8o/YI2lfSdZqF46K51WGb6/J79UdAHYAb1N2rDHw
MRnYmQCkURX/dxUcEdkCwQApBo2yCJo32RMAAAFhezZDCwAABAMARzBFAiAqzLuy
gkPgUSELvuB2xF9bFxPOj2YjBoiggQbUGfCMqgIhAL3VnGsi6xXUBswPEMn0M3P5
Cgnz6UGp2M4ItBE69YQnMA0GCSqGSIb3DQEBCwUAA4IBAQBbxA1NvqhkXddENUT5
qHY1pF91metZG38DwUS7c0xgS/LoY/WZZJ2cv0rEMoGCzRwwYijiiTc1MY6muiGE
hpdNja9Tu3bYJ9Z1bkiJJVKknqcqs64ibIbD762a7L/J0O9DzFKHeUwXAhpzT+rh
Z2eIPSR9BpUbiBpok73F/TvW2beJb2ncEiQJujK+UKlB9XeSsghrMOBiGnNJFB5t
Y155GAQb6oGiwRkkhWiJYZOq6riU5dmUbyqAqaxHij6hZOUzDL/fM5oeOpusedR0
4+eYgTe7LBq2teDNjchSceapKRXbbtz4UNDp0Ce3ZQyU4T4ndAsF9QiQnq7478SO
2ZgpMYIDczCCA28CAQEwYTBNMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNl
cnQgSW5jMScwJQYDVQQDEx5EaWdpQ2VydCBTSEEyIFNlY3VyZSBTZXJ2ZXIgQ0EC
EAqvo2zmy3gsLbHRetQQLQcwDQYJYIZIAWUDBAIBBQCggeQwGAYJKoZIhvcNAQkD
MQsGCSqGSIb3DQEHATAcBgkqhkiG9w0BCQUxDxcNMTgwODMwMTkxMjQ3WjAvBgkq
hkiG9w0BCQQxIgQgh0UxRgyVkgQvRpk0/2ZBwHWFEqKH5Hu6qgpvjX9ETjUweQYJ
KoZIhvcNAQkPMWwwajALBglghkgBZQMEASowCwYJYIZIAWUDBAEWMAsGCWCGSAFl
AwQBAjAKBggqhkiG9w0DBzAOBggqhkiG9w0DAgICAIAwDQYIKoZIhvcNAwICAUAw
BwYFKw4DAgcwDQYIKoZIhvcNAwICASgwDQYJKoZIhvcNAQEBBQAEggIAEb1tlBKO
lSv69TDq4Jlhmtqt2szWKZazOhTMDUo68j3rJ6xJS9so7NKrQv+aeo8DdAblU/G/
OD2U6XS5iDdYg94aIyNEjuCZOfvibV8U1PA6WP+8VTo3vEDP0JoAt/NgWJKiKESS
iQ/8waAcLqxECW1Pa11KxdvO6xhJKpNI/xpl/t0007mYrZDseuLZNcyQjOOrP0Kj
E/21geSIyTTN842R0Zg6qTn6XlkPUq/bSa9MnlCUDNGxFn25Uqv+3nYlJhEiGyHa
GQef4vZL1faz7ljxnx/MJKiWAbq07F7tYEHGyVTkO3MGF/wBe8vDlYs3U1T4v+2g
hjEWiOyREYTt9a4XJ1QcscjbGCRl28BajmxBBHibkSM2o5ztLxPUoiEKjY3XQc6J
oHX3Gmj63qMQPQz58AVoalGtwxOxlJiFc0Y13NIydbxMRuxep0XHVNE5XFQGE1K/
2r5iV4pS1f+EarDxfjzkrUwZFYJLdO27DqIL//6m6uTiIgZBXnzqulWlLxX17MCD
2yUOTRPGqo9eRhnrtbeh3PYGXG0zhGSdmzoTQr2mf2k7EDB/48BGvUWeHGsc7sQT
LUrlnLKqiG1uRB4sWTWMtxsKtH8kGP824ihszLh+13IXlMztCEg+kh472KQENguC
Yxt8DzcvxMi0rIsbsC/Thq3nxpFCGDV7m3Q=
------1E2FB76A361B53C9D12B3971C32BC0D8--
It has the signature in "Base64" format and "pkcs7-signature". I am not able to match signature. I am considering following part as main data:
ISA*00* *00* *ZZ*SPSAS2 *ZZ*SPSAS2 *140919*1159*|*00501*100000001*0*P*>
GS*PO*AS2S3REC*AS2S3SEND*20140919*1159*123*X*005010
ST*850*1234
BEG*00*SA*SPSAS2TEST**20121017
REF*IA*TEST
PER*OC*Someone*TE*2844994944
DTM*001*20121025
N1*ST*SomeoneElse
N3*My address is private
N4*ST THOMAS*VI*00801
PO1*54812*1*EA***SK*123546*VP*123546*UP*123456987111
CTT*1
SE*11*1234
GE*1*123
IEA*1*100000001
and base64 string as sign. and sung following function to match sign:
static bool Verify(string text, byte[] signature, string certPath)
{
X509Certificate2 cert = new X509Certificate2(certPath);
RSACryptoServiceProvider csp = (RSACryptoServiceProvider)cert.PublicKey.Key;
SHA1Managed sha1 = new SHA1Managed();
UnicodeEncoding encoding = new UnicodeEncoding();
byte[] data = encoding.GetBytes(text);
byte[] hash = sha1.ComputeHash(data);
// Verify the signature with the hash
return csp.VerifyHash(hash, CryptoConfig.MapNameToOID("SHA1"), signature);
}
But this function is not matching the signature.
Please help me with this problem.
Thank you...
I can't, personally, get the data to validate. (I'm assuming that either there are trailing spaces that aren't copying correctly or that the payload has been altered (e.g. "My address is private"))
The flow that I expect is happening:
The pkcs7 content is a CMS SignedData with detached content.
The signed content was specified in the first stream
So you need to do something like:
byte[] dataBytes = ReadFirstSegment();
byte[] signatureBytes = ReadSecondSegment();
SignedCms cms = new SignedCms(new ContentInfo(dataBytes), detached: true);
cms.Decode(signatureBytes);
// This next line throws a CryptographicException if the signature can't be verified
cms.CheckSignature(true);
SignerInfoCollection signers = cms.SignerInfos;
if (signers.Count != 1)
{
// probably fail
}
if (!IsExpectedCertificate(signers[0].Certificate))
{
// fail
}
// success

Word 2010 reports an error after saving to WebDAV server

I've got a custom WebDAV server, built using Sphoirum webdav server, that resides inside an ASP.NET MVC3 application. It's a .Net 4.0 project.
The document repository is a SharePoint, where our MVC application is a front end to it, and exposes the whole thing via the WebDAV. Just to note we don't have WebDAV publishing enabled on our IIS 7.5.
I've implemented the following HTTP verbs:
Get
Head
Lock
Options
PropFind
Put
Unlock
Now, when I open a word document, it's first in the read only mode. Getting the lock and into edit mode is successful, but when I want to save the changes in my document I get the following:
Your changes were saved but could not be uploaded because of an error.
The trick is that document is indeed saved correctly to the repository, and the response from our WebDAV server to word is HTTP/200 but the Word complains nonetheless.
I've also tried editing in Word directly from the SharePoint repository, just to confirm that my Office isn't broken somehow - all works.
Here's the response from PUT request when saving the document from Word:
HTTP/1.1 200 OK
Date: Tue, 06 Sep 2011 12:25:47 GMT
Server: Microsoft-IIS/6.0
X-Powered-By: ASP.NET
MicrosoftSharePointTeamServices: 12.0.0.6545
Last-Modified: Tue, 06 Sep 2011 12:25:47 GMT
ETag: "{F4A63494-D302-4C9B-9C57-D0CB0937A2B0},9"
ResourceTag: rt:F4A63494-D302-4C9B-9C57-D0CB0937A2B0#00000000009
X-MSDAVEXTLockTimeout: Second-3600
Lock-Token: opaquelocktoken:{F4A63494-D302-4C9B-9C57-D0CB0937A2B0}20110906T122532Z
Expires: Mon, 22 Aug 2011 12:25:47 GMT
Cache-Control: private,max-age=0
Content-Length: 0
Public-Extension: http://schemas.microsoft.com/repl-2
Set-Cookie: WSS_KeepSessionAuthenticated=40689; path=/
And here's the same response, for the same document, from our WebDAV server:
HTTP/1.1 200 OK
Cache-Control: private,max-age=0
Content-Length: 0
Expires: Wed, 24 Aug 2011 08:03:28 GMT
Last-Modified: Wed, 07 Sep 2011 08:03:28 GMT
ETag: "{4a4331a8-7df6-43e6-bd5f-bb80765e83a2},1"
Server: Microsoft-IIS/7.5
MS-Author-Via: DAV
ResourceTag: rt:4a4331a8-7df6-43e6-bd5f-bb80765e83a2#00000000001
Lock-Token: opaquelocktoken:{4a4331a8-7df6-43e6-bd5f-bb80765e83a2}20110907T080328Z
X-MSDAVEXTLockTimeout: Second-3600
Public-Extension: http://schemas.microsoft.com/repl-2
MicrosoftSharePointTeamServices: 12.0.0.6545
Set-Cookie: WSS_KeepSessionAuthenticated=40689; path=/
X-Powered-By: ASP.NET
Date: Wed, 07 Sep 2011 08:03:27 GMT
So I've tried to mimic some of the headers SharePoint emits, like MicrosoftSharePointTeamServices but to no avail.
By the way, I found the bug in Sphorium webdav that was causing this. The bug was in the method DavLockBase_InternalProcessDavRequest() and the incorrect line of code was:
string[] _lockTokens = this.RequestLock.GetLockTokens();
which should be:
string[] _lockTokens = this.ResponseLock.GetLockTokens();
After that change, saving files in Word 2010 worked fine.
If someone ever runs into this again, here is a fix that was built based on the above answer, and on what I have found from working with word 2010. Basically the fix involves replacing the code for the "DavLockBase_InternalProcessDavRequest" method (I've added some comments for each "correction").
As a note (found some info here): the behavior of the webdav implementation for word 2010 differs on whether there is a patch installed on the client side or not; therefore the 3rd correction may not be needed in all cases!
Hope it helps!
private int DavLockBase_InternalProcessDavRequest(object sender, EventArgs e)
{
int _responseCode = (int)DavLockResponseCode.Ok;
//string[] _lockTokens = this.RequestLock.GetLockTokens();
//#1 the above line is incorrect. replaced with the following:
string[] _lockTokens = this.ResponseLock.GetLockTokens();
//Check to see if a lock refresh was requested
if (base.HttpApplication.Request.Headers["If"] != null)
{
if (_lockTokens.Length == 1)
{
//#2 not sure why this should be done (or not), however I've seen this in other people corrections.
//DavRefreshEventArgs _refreshEventArgs = new DavRefreshEventArgs(_lockTokens[0], this.RequestLock.LockTimeout);
//OnRefreshLockDavRequest(_refreshEventArgs);
}
base.HttpApplication.Response.AppendHeader("Timeout", "Second-" + this.ResponseLock.LockTimeout);
}
else
{
//New lock request
StringBuilder _opaquelockTokens = new StringBuilder();
//#3 finally, added the check below, as most of the times, when using word 2010 there are no lock requests
if (_lockTokens.Length > 0)
{
foreach (string _lockToken in _lockTokens)
_opaquelockTokens.Append("<opaquelocktoken:" + _lockToken + ">");
base.HttpApplication.Response.AppendHeader("Lock-Token", _opaquelockTokens.ToString());
}
}
//Check to see if there were any process errors...
Enum[] _errorResources = this.ProcessErrorResources;
if (_errorResources.Length > 0)
{
//Append a response node
XmlDocument _xmlDocument = new XmlDocument();
XmlNode _responseNode = _xmlDocument.CreateNode(XmlNodeType.Element, _xmlDocument.GetPrefixOfNamespace("DAV:"), "response", "DAV:");
//Add the HREF
XmlElement _requestLockHrefElement = _xmlDocument.CreateElement("href", "DAV:");
_requestLockHrefElement.InnerText = base.RelativeRequestPath;
_responseNode.AppendChild(_requestLockHrefElement);
//Add the propstat
XmlElement _propstatElement = _xmlDocument.CreateElement("propstat", "DAV:");
XmlElement _propElement = _xmlDocument.CreateElement("prop", "DAV:");
XmlElement _lockDiscoveryElement = _xmlDocument.CreateElement("lockdiscovery", "DAV:");
_propElement.AppendChild(_lockDiscoveryElement);
_propstatElement.AppendChild(_propElement);
XmlElement _statusElement = _xmlDocument.CreateElement("status", "DAV:");
_statusElement.InnerText = InternalFunctions.GetEnumHttpResponse(DavLockResponseCode.FailedDependency);
_propstatElement.AppendChild(_statusElement);
_responseNode.AppendChild(_propstatElement);
base.SetResponseXml(InternalFunctions.ProcessErrorRequest(this.ProcessErrors, _responseNode));
_responseCode = (int)ServerResponseCode.MultiStatus;
}
else
{
//No issues
using (Stream _responseStream = new MemoryStream())
{
XmlTextWriter _xmlWriter = new XmlTextWriter(_responseStream, new UTF8Encoding(false));
_xmlWriter.Formatting = Formatting.Indented;
_xmlWriter.IndentChar = '\t';
_xmlWriter.Indentation = 1;
_xmlWriter.WriteStartDocument();
//Open the prop element section
_xmlWriter.WriteStartElement("D", "prop", "DAV:");
_xmlWriter.WriteStartElement("lockdiscovery", "DAV:");
this.ResponseLock.ActiveLock.WriteTo(_xmlWriter);
_xmlWriter.WriteEndElement();
_xmlWriter.WriteEndElement();
_xmlWriter.WriteEndDocument();
_xmlWriter.Flush();
base.SetResponseXml(_responseStream);
_xmlWriter.Close();
}
}
return _responseCode;
}
Observation: the lock token uses an invalid syntax (so does Sharepoints). Also; most of these headers shouldn't be needed (being proprietary) or do not apply to a PUT response (such as Lock-Token).
I would recommend to try publishing to Apache with mod_dav first, and to observe the HTTP exchange.

Categories

Resources