I am using Apple Security Framework . I can sign and then successfully verify everything on OS X, but when I try to use SecKeyRawVerify on iOS, it fails with error -9809.
I played with various PKCS add-ons and many other attributes, but I just can't verify it correctly.
Please note that the code below probably has leaks all over the place, just trying to get it to function normally in the first place.
OS X Signature Code:
NSData* signData(NSData* plainData, SecKeyRef privateKey) { CFErrorRef error; SecTransformRef signer = SecSignTransformCreate(privateKey, &error); if (error) { CFShow(error); exit(-1); } SecTransformSetAttribute(signer, kSecPaddingKey, kSecPaddingPKCS1Key, &error); if (error) { CFShow(error); exit(-1); } SecTransformSetAttribute(signer, kSecDigestTypeAttribute, kSecDigestSHA1, &error); if (error) { CFShow(error); exit(-1); } SecTransformSetAttribute(signer, kSecTransformInputAttributeName, plainData, &error); if (error) { CFShow(error); exit(-1); } CFTypeRef signature = SecTransformExecute(signer, &error); if (error || !signature) { CFShow(error); exit(-1); } CFRelease(signer); return signature; }
and iOS verification code:
+ (NSData *)verifyData:(NSData *)data usingKey:(SecKeyRef)publicKey { size_t signatureByteLength = SecKeyGetBlockSize(publicKey); if (signatureByteLength > data.length) { NSLog(@"Signature length is greater that data length."); return nil; } NSData *signature = [data subdataWithRange:NSMakeRange(0, signatureByteLength)]; NSData *plainData = [data subdataWithRange:NSMakeRange(signatureByteLength, data.length - signatureByteLength)]; NSLog(@"signatureLength='%lu', signatureBytes='%@', plainDataLength=%lu", (unsigned long)signature.length, signature, (unsigned long)plainData.length); size_t hashByteLength = CC_SHA1_DIGEST_LENGTH; uint8_t* hashBytes = (uint8_t *)malloc(hashByteLength); if (CC_SHA1([plainData bytes], (CC_LONG)[plainData length], hashBytes)) { NSData *b = [NSData dataWithBytes:hashBytes length:hashByteLength]; NSLog(@"hashBytesLength='%lu', hashBytes=%@", (unsigned long)b.length, b); OSStatus status = SecKeyRawVerify(publicKey, kSecPaddingPKCS1SHA1,
I created the private and public keys through the command line using the following OpenSSL commands:
1. // Generate private and public key pair openssl genrsa -out rsaPrivate.pem 1024 1a. // Generate public key openssl rsa -in rsaPrivate.pem -pubout -outform PEM -out rsaPublic.pem 2. //Create a certificate signing request with the private key openssl req -new -key rsaPrivate.pem -out rsaCertReq.csr 3. //Create a self-signed certificate with the private key and signing request openssl x509 -req -days 3650 -in rsaCertReq.csr -signkey rsaPrivate.pem -out rsaCert.crt 4. //Convert the certificate to DER format: the certificate contains the public key openssl x509 -outform der -in rsaCert.crt -out rsaCert.der
Any help is greatly appreciated.