Search code examples
iossecuritydigital-signatureseckeyref

SecKeyRawSign returns OSStatus = noErr, but random signature objects


I am using SecKeyRawSign to digitally sign a PDF´s SHA digest, and SecKeyRawSign reports OSStatus = noErr, but I get random signature objects every time I run the project.

The privateKey is always the same (saved in the Keychain). I also verified that the document digest is the same (converting to base64 and also with hexdump)

So the issue is: Given the same inputs, SecKeyRawSign reports status = noErr, but different output.

This is the code I am using:

NSData *hashData = [self getHashData];
SecKeyRef privateKey = [self getPrivateKeyFromKeychain];

size_t signatureBytesSize = SecKeyGetBlockSize(privateKey); 
uint8_t *signatureBytes = malloc(signatureBytesSize * sizeof(uint8_t));
memset((void *)signatureBytes, 0x0, signatureBytesSize);

OSStatus status = noErr;
status = SecKeyRawSign(privateKey, kSecPaddingSHA1, (const unsigned char *)hashData.bytes, SecKeyGetBlockSize(privateKey), signatureBytes, &signatureBytesSize);

if (status == noErr) {
    NSLog(@"Signing OK");
    NSLog(@"Signature: \"%s\"", signatureBytes);
} else {
    NSLog(@"Error signing data: result code: %d", (int)status);
}

I always get status = noErr, "Signing OK", but the signatureBytes are random and random size.

I tried with different Padding. Also set the signature buffer size to the key size - 11 (as per the documentations)

Researching the documentation I could´t find much details about the signature object type (sig). I assume it is raw bytes that can be converted to Base64.

Any help will be appreciated.... e


Solution

  • I found the problem and was able to sign a PDF hash and verify the signature. I was using SecKeyGetBlockSize(privateKey) instead of hashData.length in the dataToSignLen variable of SecKeyRawSign

    size_t signatureBytesSize = SecKeyGetBlockSize(privateKey);
    uint8_t *signatureBytes = malloc(signatureBytesSize * sizeof(uint8_t));
    memset((void *)signatureBytes, 0x0, signatureBytesSize);
    OSStatus signStatus = SecKeyRawSign(directPrivateKey, kSecPaddingPKCS1SHA1, (const unsigned char *)hashData.bytes, hashData.length, signatureBytes, &signatureBytesSize);