I am developing a tool, that encrypts emails with S/MIME in bulk within Outlook 2013. It works so far, but when I am trying to encrypt a REALLY BIG email (in the test case it was about 60MB raw). I get a COMException stating unsufficient ressources.
I can go around this, by working direktly with EWS and MimeKit (which works like a charm! Thank you #jstedfast), but I'd like to find a way to work in Outlook, for network traffic considerations. I know these changes will be synched to Exchange eventually, but during the process itself, it is independent of bandwidth.
I am also looking at MapiEx, but if there is an easier solution, than having yet another dependency (and with MFC too), I'd be happy! Maybe there are some settings, I'd have to make before.
A bit of code. The Exception it caught somewhere else.
public void String SetEncryption(MailItem mailItem)
{
PropertyAccessor pa = null;
try
{
pa = mailItem.PropertyAccessor;
Int32 prop = (int)pa.GetProperty(_PR_SECURITY_FLAGS);
Int32 newprop = prop | 1;
pa.SetProperty(_PR_SECURITY_FLAGS, newprop);
}
finally
{
Marshal.FinalReleaseComObject(pa);
pa = null;
}
}
Edit: The Exception is not coming, when the encryption is set, but when the result is saved, after the encryption is set.
SetEncryption(mailItem);
mailItem.Save();
I solved it myself.
Since I had the problems in Outlook itself, I was trying MAPIEx to access the raw S/MIME Attachment in the email and de-/encrypt it using MimeKit/BouncyCastle.
The same problem occoured, but with a different error message, which lead me to the following site: ASN.1 value too large.
To sum it up: The Crypto API has two signatures. One which takes a byte array and one, which takes a stream. The first one has an arbitrary imposed (!!!) limit of 100 Million Bytes. Since the enveloped CMS has double base64 the ratio of this 100 MB is 9/16, which is round about 56 MB.
I assume, that Outlook uses the same API-Call and therefore has this limit.
I know it is not a fact, but the evidence strongly supports this theory. :)
Check if KB 2480994 is installed: http://support.microsoft.com/kb/2480994
Related
I'm making a windows form application using Visual Studio. The application allows you to enter the what you want the photo to be named, and then saves that image to a specific location on the network. It works great when I use it on my laptop. However, when I try to run it on the a desktop, it does not work. Instead I get the message:
System.Runtime.InteropServices.COMException (0x80040217): No
combination of intermediate filters could be found to make the
connection.
at DirectShowLib.DsError.ThrowExceptionForHR(Int32 hr)
at OrderProductCapture.Capture.SetupGraph(DsDevice dev, Int32 iWidth,
Int32 iHeight, Int16 iBPP, Control hControl)
at OrderProductCapture.Capture.ctor(Int32 iDeviceNum, Int32 iWidth,
Int32 iHeight, Int16 iBPP, Control hControl)
at OrderProductCapture.frmMain.ctor()
The Call Stack says:
OrderProductCapture.exe!OrderProductCapture.Capture(int iDeviceNum, int iWidth, int iHeight, short iBPP, System.Windows.Forms.Control hControl) Line 82
OrderProductCapture.exe!OrderProductCapture.frmMain.frmMain() Line 50
OrderProductCapture.exe!OrderProductCapture.Program.Main() Line 19
I have already googled this many times, and I've looked at most of the similar questions on SO. Both computers are using Windows 7 professional. Any help would be fantastic.
This is the code where my code catches the exception. I do not think the code is wrong, because it works fine on my laptop.
public Capture(int iDeviceNum, int iWidth, int iHeight, short iBPP, Control hControl)
{
DsDevice [] capDevices;
// Get the collection of video devices
capDevices = DsDevice.GetDevicesOfCat(FilterCategory.VideoInputDevice);
if (iDeviceNum + 1 > capDevices.Length)
{
throw new Exception("No video capture devices found at that index!");
}
try
{
// Set up the capture graph
SetupGraph( capDevices[iDeviceNum], iWidth, iHeight, iBPP, hControl);
// tell the callback to ignore new images
m_PictureReady = new ManualResetEvent(false);
}
catch
{
Dispose();
throw;
}
}
When having to convert between media formats, you can programmatically force it to use some specific filter chain and configure it tightly to your needs, but DirectSHOW also has the ability of "guessing" the right tools to use. It knows all the tiny media handlers that are oficially installed in the OS, and tries to match them so that final required "conversion" is built.
However, DirectShow still needs those tiny converters to be installed. DS is able to analyze and connect them, but will not provide you any support for exotic media types. Often, even non-exotic can be problematic if the OS is "fresh-n-clean".
If I remember correctly, that error basically means that (on this problematic machine) some "codecs" are missing.
These things often come with any:
drivers for webcams/microphones/soundcards
audio-processing software (sound editors, media recorders, media players, ..)
"codec packs" like CCCP (really, don't get confused by their logo)
specific codec/filter packages
(...)
First thing I'd now do would be:
recall what I tried to convert
try to read all error messages and logs and find out if there's some faulty filter mentioned, maybe it needs reinstalling
compare what audio-related software is installed on machines where the program WORKS versus the problematic machine
basing on the above, try to deduce what codec is missing
find it, download, install
Also, you may read the code of SetupGraph() function. I bet there's a clear reference to the format that is being used, and this may point out what codec is missing.
Codecs also sometimes get damaged (actually not themselves, but their configuration and registration entries may get damaged). If you are sure that the correct codecs are available on the machine, reinstalling or "repairing" (if they have such option) them can help.
I'm calling the iOS SecKeyGeneratePair method to generate an RSA key pair. Now I want to extract the RSA parameters from it (both public and private data). How can I do that?
I've found the CryptoExercise sample but I don't see that it's actually exporting keys to their raw data. Besides, it's Objective-C which I am really struggling to grok.
I'm doing this in a Xamarin.iOS (C#) mobile app so I need my ultimate solution to be written in C# by calling the necessary interop APIs into iOS (just like my call to SecKeyGeneratePair).
For those familiar with Xamarin, yes, I know I can use new RSACryptoServiceProvider() to do it much more easily. The difference is 2-3 orders of magnitude perf improvement when I use native APIs for RSA key generation (and even the encryption bit itself). So while I must use native APIs for the RSA work, I also need to get the raw data out so that I can be cross-platform.
AFAIK you cannot directly extract the parameters. There was some talk on the Apple developer forums about this (you might want to check). Sadly the Apple engineer answer was the assumptions (about the posted code) were implementation details and subject to change at any time.
Still you might be able to do this indirectly using the available API, e.g. export it as a PKCS#12 and then get the RSA parameters from it.
UPDATE: upon verification you can only import PKCS#12 - so this would not help exporting the private key. I'm back to the there's no supported way of doing it. The only safe option, beside the use of managed code, I can think of is to include native code (3rd party library) to generate the keypairs.
I once tried something similar (it was import, not export) but the time required for the extra operations made my code slower than using only C#. Your situation is different so YMMV.
note: it seemed to me that the keychain access (which is out of process, encrypted...) caused much of the slowdown. It was not worth importing a public key for a one-time use - but if you're (re)using it multiple time then the (one-time) cost might be acceptable to you.
The SecKeyGeneratePair is an older API replaced by SecKeyCreateRandomKey that's only available as of iOS 10. So I will answer using the older functions that the question asks about. I'll stick to Core Foundation APIs for interoperability with C#.
You can export the public and private raw key data by adding it to the keychain and returning it as data bytes. Here's an example:
//Convert key object into data
SecKeyRef givenKey = publicOrPrivateFromSecKeyGeneratePair;
static const uint8_t publicKeyIdentifier[] = "com.company.myTempRSAKey"; //make it unique per key
CFDataRef publicTag = CFDataCreate(kCFAllocatorDefault, publicKeyIdentifier, sizeof(publicKeyIdentifier));
if (publicTag)
{
OSStatus sanityCheck = noErr;
CFDataRef publicKeyBits = NULL;
//Create a dictionary info object describing that we are using RSA
CFMutableDictionaryRef queryPublicKey = CFDictionaryCreateMutable(kCFAllocatorDefault, 5, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
if (queryPublicKey)
{
CFDictionaryAddValue(queryPublicKey, kSecClass, kSecClassKey);
CFDictionaryAddValue(queryPublicKey, kSecAttrApplicationTag, publicTag);
CFDictionaryAddValue(queryPublicKey, kSecAttrKeyType, kSecAttrKeyTypeRSA);
CFDictionaryAddValue(queryPublicKey, kSecAttrKeyClass, kSecAttrKeyClassPublic); //for public or:
//CFDictionaryAddValue(queryPublicKey, kSecAttrKeyClass, kSecAttrKeyClassPrivate); //for private
CFDictionaryAddValue(queryPublicKey, kSecAttrAccessible, kSecAttrAccessibleWhenUnlockedThisDeviceOnly); //other options...
CFMutableDictionaryRef attributes = CFDictionaryCreateMutableCopy(kCFAllocatorDefault, 7, queryPublicKey);
if (attributes)
{
// Temporarily add key to the Keychain, return as data:
CFDictionaryAddValue(attributes, kSecValueRef, givenKey);
CFDictionaryAddValue(attributes, kSecReturnData, kCFBooleanTrue);
CFTypeRef result = NULL;
sanityCheck = SecItemAdd(attributes, &result);
if (sanityCheck == errSecSuccess)
{
publicKeyBits = (CFDataRef)result; // Use the RAW key here
// Remove the temp key from the Keychain
sanityCheck = SecItemDelete(queryPublicKey);
if (sanityCheck != errSecSuccess)
{
//... Error deleting temporary public key from keychain
}
}
// else - failsafe code if key exists, try to delete first and then add item etc.
CFRelease(attributes);
}
CFRelease(queryPublicKey);
}
CFRelease(publicTag);
}
This gets you the raw data. It's raw because it's missing the header that most systems outside of Apple expect. The ASN.1 OID value for RSA public keys followed by a terminating NULL byte, for example.
//HEX: 30 0d 06 09 2a 86 48 86 f7 0d 01 01 01 05 00
/*
SEQUENCE {
OBJECTIDENTIFIER 1.2.840.113549.1.1.1 (rsaEncryption)
NULL
}
*/
So if you're looking for the raw data you have it. If by "parameters" you're trying to extract the modulus and exponent from the raw data, you can do that too (ex. a bit stream: mod + exp). Let me know if that is what you're after.
My question is related with the C# implementation of the google protocol buffers (protobuf-csharp-port, by jon skeet, great job!)
I am experiencing troubles with the extensions: let's say I wrote:
"transport_file.proto" with a "transport message" and some code to
deal with it "code_old".
and I wrote an extension of the transport message on
"Mytransport.proto" file, and new code to read it "code_new".
I'm trying to read a new message (from MyTransport.proto) with the code_old expecting to ignore the extension, but I get an exception in the merge method from TextFormat: "transport" has no field named "whatever_new_field"
Transport.Builder myAppConfigB = new Transport.Builder();
System.IO.StreamReader fich = System.IO.File.OpenText("protocolBus.App.cfg");
TextFormat.Merge(fich.ReadToEnd(),myAppConfigB);
fich.Close();
new extended file looks like:
...
Transport
{
TransportName: "K6Server_0"
DllImport: "protocolBus.Transports.CentralServer"
TransportClass: "K6Server"
K6ServerParams
{
K6Server { host: "85.51.11.23" port: 40069 }
Service: "TZinTalk"
...
}
}
...
while the old one, not extended:
...
Transport
{
TransportName: "K6Server_0"
DllImport: "Default"
TransportClass: "Multicast"
}
...
The whole idea is to use the text based protocol buffer as a config file in which I write some params, and based on one of those I load and assembly (which will read the whole message with the new extension (params to initialize the object).
Any idea? (it is a desperate question :D )
I'm using MSVC# 2008Express edition, protobuf-csharp-port version 0.9.1 (someday I'll upgrade everything).
THANKS in advance.
I'm working on a non centrilized Publish-Subscribe framework of messages (for any written message in a proto file I auto create a Publish and a Subscriber class) with different transports. By the default I use multicast, but broadcast and a "UDP star" are also included. I let the extension mechanism to let people add new transports with its owm config params that should be read by my main code_old (just to load the assembly) and let the new transport (.dll) read it again (fully).
Curious? the previous, almost functional, version is in http://protocolbus.casessite.org
Update 1
Extended types in text format are enclosed in brackets (good to know, I was not aware of it :D ) so I should have written:
[K6ServerParams]
{
K6Server { host: "85.51.11.23" port: 40069 }
Service: "TZinTalk"
...
}
Protocol buffers are designed to be backwards and forwards compatible when using their binary format, but certainly the current code doesn't expect to parse the text format with unknown fields. It could potentially be changed to do that, but I'd want to check with the Java code to try to retain parity with that.
Is there any reason you're not using the binary representation to start with? That's the normal intended usage, and the one where the vast majority of the work has gone in. (Having said which, it all seems a bit of a blur after this long away from the code...)
Hi I have written a C# client/server application using the Zeroc Ice communication libary (v3.4.2).
I am transferring a sequence of objects from the server which are then displaying them in the client in a tabular format. Simple enough.
I defined following slice types
enum DrawType { All, Instant, Raffle };
struct TicketSoldSummary {
int scheduleId;
DrawType dType;
string drawName;
long startDate;
long endDate;
string winningNumbers;
int numTicket;
string status;
};
sequence<TicketSoldSummary> TicketSoldSummaryList;
interface IReportManager {
[..]
TicketSoldSummaryList getTicketSoldSummary(long startTime, long endTime);
};
When I call this method it usually works fine, but occasionally (approx 25% of the time) the caller gets a Ice::MemoryLimitException. We are usually running 2-3 clients at a time.
I searched on the Internet for answers and I was told to increase Ice.MessageSizeMax, which I did. I have increased MessageSizeMax right up to 2,000,000 Kb, but it made no difference, I just did a test with 31,000 records (approximately 1.8 Megs of data) and still get Ice.MemoryLimitException. 1.8 Megs is not very big!
Am I doing something wrong or is there a bug in Zeroc Ice?
Thanks so much to anyone that can offer some help.
I believe MessageSizeMax needs to be configured on the client as well as the server side. Also have tracing enabled with max value (3) and check the size of the messages (on the wire)
Turn on Ice.Warn.Connections on the server side and see the logs. Also make sure the client max message size gets applied correctly. I set Ice.MessageSizeMax on the client as below,
Ice.Properties properties = Ice.Util.createProperties();
properties.setProperty("Ice.MessageSizeMax", "2097152");//2gb in kb
Ice.InitializationData initData = new Ice.InitializationData();
initData.properties = properties;
Ice.Communicator communicator = Ice.Util.initialize(initData);
I have coding I almost always use with my Omnikey RFID CardMan 5321 smart cards. Problem is we received new cards today which are marked "HID iCLASS GL" which do not appear to be working well with our coding.
Without going through the whole source, our problem is arising when we are calling the following line, which basically tells us the length of the data:
lResult = SCardTransmit(hCard, 0, bytCommand, lLen, 0, byReadBuffer, iReturnlength)
We are returning only a length of 2, which the data is marked as "x69 x86". Even if I tell it to read all 255 chr's the rest are just marked as null.
Now I know our reader can read these cards since the OMNIKEY Diagnostic tool is showing us the following:
Status: Smart Card Inserted
FW: 5.10
Port: USB
Lib: 1.0
Smart Card Nme: iCLASS 32KS 8x2+16
ART: Valid
Protocol: ISO 15693 (Part 2)
PICCtoPCD: 26,48 kbps
PCDtoPICC: 26,48 kbps
Frequ: 13.56 MHz
As I explained before, everything is working fine in my coding except no data is being returned for my card besides "x69 x86", which is surely not correct.
If anyone has any experience reading from a HID iCLASS card, I would greatly appreciate some feedback on how to. Even if we have to license software, that is ok.
Thanks in advance!
in case you are trying to access physical access data, I would thoroughly check the crypto protocol between reader and host first and also meke sure you are using a reader with teh latest firmware (5.20 for the OMNIKEY 5321).
I would also introduce code to check the card system withour secure communication channel between host and reader application.
Further references:
http://www.hidglobal.com/documents/ok_contactless_developer_guide_an_en.pdf
The reason cause you get a 2 Byte array is cause your command runs on an error so the chip returns only SW1 and SW2 Flag
in your case it's meaning is
x69 --> Command not allowed (further qualification in SW2, see table 17)
x86 --> Command not allowed (no current EF)
So you might proof that your application file on the chip is correctly selected
further information #
http://www.cardwerk.com/smartcards/smartcard_standard_ISO7816-4_5_basic_organizations.aspx#table17