Extracting Public Key Blobs
(Updated 12/3/04 for code refactoring)
Before letting another two months pass, its time to once again update the managed sn.exe port. Today's update adds three modes, each of which allow extraction of a public key blob from various sources:
Flag | Description | StrongName API |
-e | Extract the public key from an assembly | StrongNameTokenFromAssemblyEx |
-p | Extract the public key from a key blob | StrongNameGetPublicKey |
-pc | Extract the public key from a key container | StrongNameGetPublicKey |
These are both relatively easy APIs, so lets take a look at them one at a time.
StrongNameTokenFromAssemblyEx
StrongNameTokenFromAssemblyEx extracts the public key token from an assembly's PE file, however it also extracts the public key from the file. Since it gives both pieces of information, we can use this API to implement the -e flag, and just throw away the token. StrongNameTokenFromAssemblyEx takes five parameters:
Parameter | Use |
wszFilePath | full path to the assembly to extract the key/token from |
ppbStrongNameToken | [out] pointer to a buffer containing the token |
pcbStrongNameToken | [out] size of the buffer returned in ppbStrongNameToken |
ppbPublicKeyBlob | [out] pointer to a buffer containing the public key blob |
pcbPublicKeyBlob | [out] size of the buffer returned in ppbPublicKeyBlob |
Using this method is extremely easy. Simply pass the path of the assembly who's public key information is required in, and it passes you out the public key token and public key blob for that assembly. Of course you must call StrongNameFreeBuffer on both of the output buffers, or your code will leak memory.
Since this method is very straight forward to use, you'll find the code in Keys::ExtractPublicKeyFromAssembly (in MS.StrongName\Keys.cs) very easy to follow as well. All this method does is call into the StrongNameFromTokenEx method, copy the returned byte array into a managed array, then free the two returned arrays.
StrongNameGetPublicKey
StrongNameGetPublicKey is almost as easy to use as StrongNameTokenFromAssembly. It also requires five parameters:
Parameter | Use |
wszKeyContainer | key container to extract the public key from |
pbKeyBlob | key blob to extract the public key from |
cbKeyBlob | size of pbKeyBlob |
ppbPublicKeyBlob | [out] pointer to a buffer containing the public key blob |
pcbPublicKeyBlob | [out] size of the buffer returned in ppbPublicKeyBlob |
StrongNameGetPublicKey is overloaded to get the public key out of a key blob that is either stored in a key container, or held in a key pair blob. Either way, the return value is placed in a buffer pointed to by ppbPublicKeyBlob, and that buffer's size is placed in pcbKeyBlob. Again, you must call StrongNameFreeBuffer on this key blob, or you'll end up leaking memory.
If you'd like to extract the public key from a key container, simply pass in the key container name in the wszKeyContainer parameter, and place null values in pbKeyBlob and cbKeyBlob. This is the approach taken by Keys::ExtractPublicKeyFromKeyContainer in MS.StrongName\Keys.cs. This method simply pases the key container name into StrongNameGetPublicKey, copies the key into a managed array, and releases the buffer allocated by the API.
Extracting a public key from a key pair is just as easy. This time, pass null for the key container name, and pass in the key pair blob in pbKeyBlob and cbKeyBlob. You'll recall from how we generate keys that .snk files are simply raw dumps of key pair blobs. Since the -p mode is used to extract the public key from a .snk file, all we need to do is read the .snk into a byte array, and pass that to StrongNameGetPublicKey. You'll see that's exactly what Keys::ExtractPublicKeyFromKeyPair() (again in MS.StrongName\Keys.cs) does.
Source Changes
Modified
- msn\msn.cs
- added the -e, -p, and -pc modes
- msn\msn.resx
- added extra resources to support public key extraction
Added
- StrongName.Native\Extraction.cs
- P/Invoke declarations for StrongNameGetPublicKey and StrongNameTokenFromAssemblyEx
- msn\Extraction.cs
- Implementation of -e, -p, and -pc
Comments
- Anonymous
October 20, 2005
The comment has been removed - Anonymous
April 20, 2006
i've got the same question..