Unable to obtain public key for StrongNameKeyPair

665 views
Skip to first unread message

inoodle

unread,
Jun 8, 2006, 1:30:21 PM6/8/06
to Rhino.Mocks
Hi,
I'm running version 2.8.5.15236 of Rhino Mocks, and I'm getting an
ArgumentException with the above error when using
CreateMock<T>(IMyInterface);

IMyInterface is defined in a different assembly to the test assembly.

It could be permission related, as I'm running under a LUA (non admin
account).

I know this has come up before in the group, but the solution of
running sn.exe - c didn't work for me (in fact unless run as admin, it
just gave a registry access permission error, which sounds fair
enough)...

anyway any ideas ?

Thanks.

Ayende Rahien

unread,
Jun 8, 2006, 3:59:52 PM6/8/06
to Rhino...@googlegroups.com
The different assembly is signed or not?
Do you see which registry key is the problematic one?
Check the previous thread, there was a problematic permissions for a file
path there as well, IIRC.

Can you make it work on another machine?

Ayende Rahien

unread,
Jun 8, 2006, 5:29:28 PM6/8/06
to Rhino...@googlegroups.com
The path that I mentioned is:
C:\Documents and
Settings\AllUsers\ApplicationData\Microsoft\Crypto\RSA\MachineKeys

Check the permissions on that one.

-----Original Message-----
From: Rhino...@googlegroups.com [mailto:Rhino...@googlegroups.com] On
Behalf Of inoodle
Sent: Thursday, June 08, 2006 7:30 PM
To: Rhino.Mocks
Subject: Unable to obtain public key for StrongNameKeyPair

inoodle

unread,
Jun 9, 2006, 7:48:10 AM6/9/06
to Rhino.Mocks
Hi, thanks for your help.
That was the issue, although it took me half a day of Reflectoring to
work it out :) Its strange that I needed Full access to that directory,
not just Read access, as I don't think any new certs are generated.

I suspect it might also work (and perhaps be more secure) by using sn
-m n which I believe sets it to use a user based certificate store
instead of machine based. I'm not sure what effects this might have on
other applications which are already installed though, so I'll leave it
to some other brave soul :)

In my reflector travels I noticed a couple of things. It seems that
when generating an interface based proxy, the code (in castle
dynamicproxy) will ALWAYS sign the generated assembly even if the
interface comes from an assembly which isn't signed.
This is not the case when a class is proxied - in that case the
generated assembly is signed only if the assembly of the original class
is signed. It seems like it would be better to check whether the
interfaces assembly was signed rather than always do it, but this is
the first time I've looked into DynamicProxy and I'm sure there are
issues and reasons why this is not the case.
The other thing, is that it looks like RhinoMocks has the DynamicProxy
source compiled within its own source code, so I just wondered why the
dynamicProxy dll was needed in the distribution (licencing?) ?

Thanks again for the swift help.

Aaron Robson

Ayende Rahien

unread,
Jun 9, 2006, 9:02:56 AM6/9/06
to Rhino...@googlegroups.com
The DynamicProxy is in the distribution for historic reasons, we needed it
as some point, and then I started using ILMerge, so it became pointless. I
just forgot to remove it :-)

Are you sure about proxies for interfaces from unsigned assemblies being
generated to signed assemblies? I think that the CLR prevents that.
As far as I can see, both classes & interfaces has the same code path in
this region.

-----Original Message-----
From: Rhino...@googlegroups.com [mailto:Rhino...@googlegroups.com] On
Behalf Of inoodle

inoodle

unread,
Jun 9, 2006, 8:34:31 AM6/9/06
to Rhino.Mocks
Sure ? Never ;)
The code I looked at begins around about:
InterfaceProxyGenerator.GenerateCode(Type[], Type)

Following it through, it ends up calling the EasyType constructor:
EasyType(ModuleScope modulescope, string name, Type baseType, Type[]
interfaces, bool serializable) : this()

This constructor seems to determine whether to sign the assembly based
on the baseType arg which is typeof(object) in this case if followed
through from this line in GenerateCode:

this.CreateTypeBuilder(this.GenerateTypeName(targetType,
interfaces), typeof(object), interfaces);

What do you think ? I would have thought the CLR prevention only worked
in the opposite case - ie trying to create an unsigned assembly which
uses an interface obtained from a signed assembly.

Ayende Rahien

unread,
Jun 9, 2006, 10:03:47 AM6/9/06
to Rhino...@googlegroups.com
Good catch, I didn't consider this.

The prevention is something like: "signed types use and inherit only signed
types".
"Unsigned types can use / inherit both signed and unsigned types."
It is possible that it is not making this check for interfaces, since there
is no behavior in an interface.
It is also possible that this is a compiler limitation, and not a CLR one.

-----Original Message-----
From: Rhino...@googlegroups.com [mailto:Rhino...@googlegroups.com] On
Behalf Of inoodle
Sent: Friday, June 09, 2006 2:35 PM
To: Rhino.Mocks
Subject: Re: Unable to obtain public key for StrongNameKeyPair

inoodle

unread,
Jun 9, 2006, 9:52:39 AM6/9/06
to Rhino.Mocks
Glad I found something :)

None of my assemblies are actually signed, so I don't think its
possible to prevent the generated assembly being signed without the
DynamicProxy code being changed for the case of proxying interfaces...
if thats actually viable.

Ayende Rahien

unread,
Jun 9, 2006, 11:21:49 AM6/9/06
to Rhino...@googlegroups.com
In general, I would say that this doesn't matter.
The exception that you got is a machine problem, not a bug.

-----Original Message-----
From: Rhino...@googlegroups.com [mailto:Rhino...@googlegroups.com] On
Behalf Of inoodle
Sent: Friday, June 09, 2006 3:53 PM
To: Rhino.Mocks
Subject: Re: Unable to obtain public key for StrongNameKeyPair

inoodle

unread,
Jun 9, 2006, 11:24:55 AM6/9/06
to Rhino.Mocks
Hmmm, I'm not sure that it is a machine problem. It's forced me to
alter the security on my machine so that my non admin account can be
used to modify sensitive data on my machine. I think the settings I had
were all correct to begin with for a LUA.

I think ideally, something should be changed - some developers working
in an enterprise scenario wouldn't be able to alter the security
settings on that folder. Perhaps a local key store could be used or
something.

The underlying problem seems to be that the native implementation (of
nGetPublicKey) requires more than just read access. On top of that,
DynamicProxy then tries to sign the generated assembly when it doesn't
have to.

So we have a workaround here, which is escalating privileges on the
LUA, but it could be avoided.
Having said all that, maybe it is only on my machine :) - it does seem
odd that more people haven't had the issue, especially as it would
occur with NHibernate as well AFAIK. Although maybe its just that not
many people develop without being an administrator - it was pretty
tricky before VS2005.

At least I can keep coding now anyway!

Ayende Rahien

unread,
Jun 9, 2006, 3:22:35 PM6/9/06
to Rhino...@googlegroups.com
Here is the permissions on that directory in a default install:
D:\Documents and Settings\All Users\Application
Data\Microsoft\Crypto\RSA>cacls MachineKeys
D:\Documents and Settings\All Users\Application
Data\Microsoft\Crypto\RSA\MachineKeys Everyone:(special access:)

READ_CONTROL

SYNCHRONIZE

FILE_GENERIC_READ

FILE_GENERIC_WRITE

FILE_READ_DATA

FILE_WRITE_DATA

FILE_APPEND_DATA

FILE_READ_EA

FILE_WRITE_EA

FILE_READ_ATTRIBUTES

FILE_WRITE_ATTRIBUTES


BUILTIN\Administrators:F

Everyone has read/write/create permissions, but only admin can delete.

Just to note, this particular problem prevents you from signing assemblies
as well, so it is not something that I would call correct behavior.
Sadly, too much software is developed as admin, so it requires privileges
that is shouldn't.


-----Original Message-----
From: Rhino...@googlegroups.com [mailto:Rhino...@googlegroups.com] On
Behalf Of inoodle
Sent: Friday, June 09, 2006 5:25 PM
To: Rhino.Mocks
Subject: Re: Unable to obtain public key for StrongNameKeyPair

inoodle

unread,
Jun 9, 2006, 3:18:18 PM6/9/06
to Rhino.Mocks
I think my Everyone group may have been missing FILE_APPEND_DATA. It
was certainly missing something anyway.

Hopefully anyone else who gets this problem should be able to solve it
quickly now.
Thanks for the help.

Ayende Rahien

unread,
Jun 9, 2006, 4:22:36 PM6/9/06
to Rhino...@googlegroups.com
Hopefully.
I posted about it, so it is now googlable.

-----Original Message-----
From: Rhino...@googlegroups.com [mailto:Rhino...@googlegroups.com] On
Behalf Of inoodle
Sent: Friday, June 09, 2006 9:18 PM
To: Rhino.Mocks
Subject: Re: Unable to obtain public key for StrongNameKeyPair

Reply all
Reply to author
Forward
0 new messages