Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SecKeyRawVerify and OSError -9809

I am using digital certificates to sign data files in my App. The code fragment below fails when the call to SecKeyRawVerify returns with -9809. This is running on an iPhone. I can't even identify exactly what this error code means

The prior Security Framework calls to load and create the SecTrustRef from which the public key is obtained seem fine - no errors. The only slight issue is that the call to SecTrustEvaluate returns a kSecTrustResultUnspecified, but I assume that is because the policy I am using is the boilerplate one returned by the SecPolicyCreateBasicX509 call.

Any assistance or insight would be very much appreciated.

Thanks

SecKeyRef keyRef = SecTrustCopyPublicKey (trustRef);

fileURL = [[NSBundle mainBundle] URLForResource:@"data" withExtension:@"txt"];
NSData *data = [NSData dataWithContentsOfURL:fileURL];

fileURL = [[NSBundle mainBundle] URLForResource:@"data" withExtension:@"sgn"];
NSData *signature = [NSData dataWithContentsOfURL:fileURL];

NSLog(@"Hash block size = %zu",SecKeyGetBlockSize(keyRef));

status = SecKeyRawVerify (keyRef,
                          kSecPaddingPKCS1SHA1,
                          (const uint8_t *)[data bytes],
                          (size_t)[data length],
                          (const uint8_t *)[signature bytes],
                          (size_t)[signature length]
                          );
like image 474
drew Avatar asked May 25 '12 15:05

drew


2 Answers

That error is defined (along with other related ones) in /System/Library/Frameworks/Security.framework/Headers/SecureTransport.h as errSSLCrypto. The comment there calls it "underlying cryptographic error", which is not a particularly descriptive description.

One thought: kSecTrustResultUnspecified means that the trust level is equal to the default system policy. Are all the certificates in the chain trusted?

like image 132
Andrew Schleifer Avatar answered Sep 28 '22 06:09

Andrew Schleifer


I've discovered what's happening. The SecKeyRawVerify call takes the digest of your data as the input, not the data itself. The code below works - and incidentally, if the signature is not verified because the underlying data has changed, then the status return is -9809.

Thanks

CC_SHA1((const void *)[data bytes], [data length], (unsigned char *)hash);

status = SecKeyRawVerify (keyRef,
                          kSecPaddingPKCS1SHA1,
                          hash,
                          20,
                          (const uint8_t *)[signature bytes],
                          SecKeyGetBlockSize(keyRef)
                          );
like image 34
drew Avatar answered Sep 28 '22 05:09

drew