Watch, Follow, &
Connect with Us

For forums, blogs and more please visit our
Developer Tools Community.


Welcome, Guest
Guest Settings
Help

Thread: CryptVerifySignature() fails with ERROR_NOT_ENOUGH_MEMORY


This question is answered. Helpful answers available: 2. Correct answers available: 1.


Permlink Replies: 1 - Last Post: Jul 3, 2014 2:43 AM Last Post By: Martin Nijhoff Threads: [ Previous | Next ]
Martin Nijhoff

Posts: 75
Registered: 8/26/10
CryptVerifySignature() fails with ERROR_NOT_ENOUGH_MEMORY  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Aug 15, 2012 5:08 AM
Hi,

First, is this the correct group for questions about the Microsoft cryptography API? If not, please let me know, so I can post this in the correct group.

I'm trying to verify a message signature using the Microsoft cryptography API.

I have a message in plaintext, a 48 byte signature of the message (= signed SHA1 hash) and a public key with a 48 byte modulus and 4 byte exponent.

I wrote this routine to generate a public key BLOB for a Base64 encoded modulus and exponent:

bool CreatePublicKey (UnicodeString Modulus, UnicodeString Exponent, TBytes &Key)
{
    TBytes M = TIdDecoderMIME::DecodeBytes(Modulus),
           E = TIdDecoderMIME::DecodeBytes(Exponent);
 
    if (E.Length > 4)
        return false;
 
    Key.Length = sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) + M.Length;
 
    BLOBHEADER *Header = (BLOBHEADER *) &Key[0];
    RSAPUBKEY *RSAPubKey = (RSAPUBKEY *) &Header[1];
 
    Header->bType = PUBLICKEYBLOB;
    Header->bVersion = CUR_BLOB_VERSION;
    Header->reserved = 0;
    Header->aiKeyAlg = CALG_RSA_SIGN;
 
    RSAPubKey->magic = 0x31415352;
    RSAPubKey->bitlen = M.Length * 8;
    RSAPubKey->pubexp = 0;
 
    memcpy(&RSAPubKey->pubexp, &E[0], E.Length);
    memcpy(&RSAPubKey[1], &M[0], M.Length);
 
    return true;
}


This is how I'm trying to verify the message signature:

// Convert Base64 encoded signature to byte array (= 48 bytes).
TBytes Signature = TIdDecoderMIME::DecodeBytes("..."),
       RSAKey;
 
// Convert Base64 encoded modulus (= 48 bytes) and exponent (4 bytes) to public key BLOB.
CreatePublicKey("...", "AQAB", RSAKey);
 
HCRYPTPROV hProv = NULL;
HCRYPTKEY hKey = NULL;
HCRYPTHASH hHash = NULL;
char *Msg = "...";
int Len = strlen(Msg);
 
// Get CSP context.
if (CryptAcquireContext(&hProv, NULL, MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
{
    // Import public key BLOB.
    if (CryptImportKey(hProv, &RSAKey[0], RSAKey.Length, 0, 0, &hKey))
    {
        // Create SHA1 hash.
        if (CryptCreateHash(hProv, CALG_SHA1, 0, 0, &hHash))
        {
            // Hash the message.
            if (CryptHashData(hHash, Msg, Len, 0))
            {
                // Verify the message signature.
                if (CryptVerifySignature(hHash, &Signature[0], Signature.Length, hKey, NULL, 0))
                    Memo1->Lines->Add("Signature is valid");
                else
                {
                    int Error = GetLastError();
 
                    if (Error == 0)
                        Memo1->Lines->Add("Signature is invalid");
                    else
                        Memo1->Lines->Add("Error 0x" + IntToHex(Error, 8) + ": " + SysErrorMessage(Error));
                }
            }
        }
    }
}
 
// Cleanup.
if (hHash != NULL) CryptDestroyHash(hHash);
if (hKey  != NULL) CryptDestroyKey(hKey);
if (hProv != NULL) CryptReleaseContext(hProv, 0);


The call to CryptVerifySignature() returns false with the error 0x00000008 (ERROR_NOT_ENOUGH_MEMORY).

Any ideas on what I'm doing wrong?

--
Martin
Martin Nijhoff

Posts: 75
Registered: 8/26/10
Re: CryptVerifySignature() fails with ERROR_NOT_ENOUGH_MEMORY  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jul 3, 2014 2:31 AM   in response to: Martin Nijhoff in response to: Martin Nijhoff
Reversing the byte order of the public key and signature fixed the problem.
Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02