[Mono-list] Problem with crypto in assembly wrapped in COM

Sebastien Pouliot sebastien.pouliot at gmail.com
Wed Feb 8 09:23:37 EST 2006


Hello Kim,

On Wed, 2006-02-08 at 13:24 +0100, Hellan.Kim KHE wrote:
> We have an assembly containing crypto functionality (X.509 certificates,
> PKCS#12, PKCS#7...) from Mono.Security.dll. So far it has been running
> fine in both WinForm and Webform environments (.NET 2.0).
> We have had to wrap this assembly in COM to allow it to be run from old
> ASP platforms.

Nice. As far as I know you're the first to use Mono.Security.dll via
COM. I'm glad it works (even if not completely ;-)

> We now get the following errors when the .NET/COM component is called
> from a webpage:
> 
> Error: exception=System.Security.Cryptography.CryptographicException:
> The system cannot find the file specified.
> 
>    at System.Security.Cryptography.Utils.CreateProvHandle(CspParameters
> parameters, Boolean randomKeyContainer)
>    at
> System.Security.Cryptography.RSACryptoServiceProvider.ImportParameters(R
> SAParameters parameters)
>    at Mono.Security.Cryptography.PKCS8.PrivateKeyInfo.DecodeRSA(Byte[]
> keypair)
>    at Mono.Security.X509.PKCS12.AddPrivateKey(PrivateKeyInfo pki)
>    at Mono.Security.X509.PKCS12.ReadSafeBag(ASN1 safeBag)
>    at Mono.Security.X509.PKCS12.Decode(Byte[] data)
>    at Mono.Security.X509.PKCS12.LoadFromFile(String filename, String
> password)
> ....
> ....
> 
> 
> I have a theory what is happening...
> In DecodeRSA() you have the following lines:
> 
> RSA rsa = RSA.Create ();
> rsa.ImportParameters (param);
> 
> I have seen before that ImportParameters() had problems in
> webapplications, because it apparently tries to access some keystores,
> that the IIS user does not have access to. A COM wrapped assembly
> probably have even less rights than a standalone assembly.
> This is the code I used instead in my application to solve the problem:

Yes. Even if the .NET API makes key containers optional (for importing
or using keyparis), MS implementation is dependent on CryptoAPI, which
is dependent on the key stores, which depends on the current user (and
its permissions).

> CspParameters CSPParam = new CspParameters();
> CSPParam.Flags = CspProviderFlags.UseMachineKeyStore;
> RSACryptoServiceProvider rsa;
> if(System.Web.HttpContext.Current == null)	// WinForm
>   rsa = new RSACryptoServiceProvider();
> else			// WebForm - Uses Machine store for keys
>   rsa = new RSACryptoServiceProvider(CSPParam);
> rsa.ImportParameters(rsaParam);

This will work for your own code. However Mono can't adopt this as this
would make Mono.Security.dll depends on System.Web (and create more
circular dependencies on Mono).

> Has anyone else had this problem and do you have a solution for it?

This is a well known problem (on Windows + .NET crypto). IIRC there is a
few knowledge base article on the subject. It is also a common question
on MS newsgroups. 

> Maybe you have to change some security settings in .NET or elsewhere to
> allow this...I don't know.

Google should find them easily (kb + newsgroups). There may be a "fix"
for this. IIRC there was one .config trick that I think it works only
for WSE stuff... but I may be wrong.

> I'm a bit stuck since I can't control what Mono is doing.

Please do look at Google and see if and how this can be fixed. It would
be nice to report the finding on this mailing-list (i.e. giving Google
another chance to index the answer ;-).

If a fix isn't possible then I think I could change Mono.Security's
source code to trap the first ImportParameters for a
CryptographicException, then re-try the ImportParameters using the
UseMachineKeyStore (as a second/last chance).
-- 
Sebastien Pouliot  <sebastien at ximian.com>
Blog: http://pages.infinit.net/ctech/



More information about the Mono-list mailing list