SecKeyRawVerify returning -67808

I am calling SecKeyRawVerify with a public key extracted from a certificate. The extraction of the public key seems to work but when I try and verify the signature I get the odd and generally undocumented ( as far as I can see) -67808. ( I have also tried this with a Sha256 hash).


The only reference to -67808 I can see anywhere is some mention on people seeing something similar with iCloud - access is restricted. The key is added to the keychain and seems legit. There are no obvious restrictions.



-(SecKeyRef)getSyncrPublicKeyfromfile{
   
    NSMutableString *string = [[NSMutableString alloc] init];
   
    NSString *certPath = [[NSBundle mainBundle] pathForResource:@"*.acme.net" ofType:@"cer"];
    NSData *certData = [NSData dataWithContentsOfFile:certPath];
    SecCertificateRef localCertificate = SecCertificateCreateWithData(NULL, (__bridge CFDataRef)certData);
   
   
   
    SecKeyRef localKey = NULL;
    SecTrustRef localTrust = NULL;
    SecCertificateRef certRefs[1] = {localCertificate};
    CFArrayRef certArray = CFArrayCreate(kCFAllocatorDefault, (void *)certRefs, 1, NULL);
    SecPolicyRef policy = SecPolicyCreateBasicX509();
    OSStatus status = SecTrustCreateWithCertificates(certArray, policy, &localTrust);
   
   
    SecTrustResultType resultType;
    OSStatus statusTrustEval =  SecTrustEvaluate(localTrust, &resultType);
   
    NSString *result = [NSString stringWithFormat:@"Certificate Trust Evaluate result : %@\n",[self getCertificateResultStringFromResultCode:resultType]];
    [string appendString:result];
   
   
    if (status == errSecSuccess)
        localKey = SecTrustCopyPublicKey(localTrust);
   
    [string appendString:[NSString stringWithFormat:@"Public Key Object : %@",localKey]];
   
    [self.pemResultTextView setString:string];
   
    [self verifiySignautreFromCer:localKey];
   
    return localKey;
   

}


- (void) verifiySignautreFromCer:(SecKeyRef)publicKeyRef {
    NSString *signauteDataStr = @"SNXprRB2Z5Xg7CiiEG+QMiRcACsGBvuPo/6bJLtONcSYP5kGpQAG0ZrEtS/49vbVK6d7jhbvLK+kfpCLIc8hfeRLyhZhGehYB9Q/BDwHT1VufQXUSp9hSTN3yPznWO7V1DvscLhhHiWypTodkjYAma5aa7P/6nspWPYoxe9RjvvTEhSmnPPVVkmiwZ5AL5sC/
  
    NSData *signatureData = [[NSData alloc] initWithBase64EncodedString:signauteDataStr options:NSDataBase64DecodingIgnoreUnknownCharacters];
  
    NSData *plainTextData = [self plainTextFileAsData];
  
    BOOL valid = NO;
  
    if (publicKeyRef != NULL) {
        valid = [self PKCSVerifyBytesSHA256withRSA:plainTextData signature:signatureData publicKey:publicKeyRef];
    }
  
  
    if (valid) {
        NSLog(@"Verified");
    }
}



- (BOOL)PKCSVerifyBytesSHA256withRSA:(NSData *)plainData signature:(NSData *)signature publicKey:(SecKeyRef)publicKey {
    size_t signedHashBytesSize = SecKeyGetBlockSize(publicKey);
    const uint8_t* signedHashBytes = [signature bytes];
    size_t plainDataHashSize = CC_SHA1_DIGEST_LENGTH;
    uint8_t* plainDataHashBytes = malloc(plainDataHashSize);
    if (!CC_SHA1([plainData bytes], (CC_LONG)[plainData length], plainDataHashBytes)) {
        free(plainDataHashBytes);
        return NO;
    }

    OSStatus status = SecKeyRawVerify(publicKey,
                                      kSecPaddingPKCS1SHA1,
                                      plainDataHashBytes,
                                      plainDataHashSize,
                                      signedHashBytes,
                                      signedHashBytesSize);
    free(plainDataHashBytes);
    return status == errSecSuccess;
}
Answered by EoinN in 249590022

This seems to work, modified from CrytoCompatability, which turned out to be useful. Thanks for that link. I dont suppose that a bug report on the failure in SecKeyRawVerify is needed as you have a fix in later OS. I would suggest that some of the older API be marked as deprecated. Theres a lot of code on the internet use SecAddItem and SecKeyRawVerify which have problems on older OSes. As you know. Maybe the documentation should mention CryptoCompatibility in the headers.


-

(BOOL)verifyUsingTransForm:(NSData*)inputData signatureData:(NSData*)signatureData publicKey:(SecKeyRef)publicKey{
    BOOL                success;
    SecTransformRef     transform;
    CFBooleanRef        result;
    CFErrorRef          errorCF;

    result = NULL;
    errorCF = NULL;

    /

    transform = SecVerifyTransformCreate(publicKey, (__bridge CFDataRef)signatureData, &errorCF);
    success = (transform != NULL);

    /

    if (success) {
        success = setupTransformForAlgorithm(transform, &errorCF);
    }

    if (success) {
        success = SecTransformSetAttribute(transform, kSecTransformInputAttributeName, (__bridge CFDataRef) inputData, &errorCF) != false;
    }

    /

    if (success) {
        result = SecTransformExecute(transform, &errorCF);
        success = (result != NULL);
    }

    /

    if (success) {
        Boolean verified = (CFBooleanGetValue(result) != false);
        if (verified){
            NSLog(@"verified");
        } else {
            NSLog(@"Not verified");
        }
    } else {
        NSError* error  = (__bridge NSError *) errorCF;
        NSLog(@"error is %@", error);
    }

    /

    if (result != NULL) {
        CFRelease(result);
    }
    if (errorCF != NULL) {
        CFRelease(errorCF);
    }
    if (transform != NULL) {
        CFRelease(transform);
    }

    return success;
}

The extraction of the public key seems to work but when I try and verify the signature I get the odd and generally undocumented ( as far as I can see) -67808.

Ah, um, -67808 is

errSecVerifyFailed
(see
<Security/SecBase.h>
), which is exactly what you’d expect to get when the verification fails.

I recommend that you take a look at the CryptoCompatibility sample code. It shows, amongst other things, how to do signature verification using all three APIs (the new unified API, the macOS legacy security transforms API, and the iOS legacy raw API) in a way that matches other common security toolkits (like OpenSSL and Java).

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

ok but we could verify on other devices. Including iOS.


I downloaded the cryto currency code before but it doesnt build on the 10.10 SDK, although it does run. Running it on 10.13 and adding some of the new API to my test project I noticed that the SecKeyRawVerify was continuing to fail but SecKeyVerifySignature -- new in 10.12 -- does in fact work. The difference this time from running on the 10.10 SDK is that there is a new and different error code -9809 indicating that there is a error inthe underlying crypto ( for the failure in SecKeyRawVerify).


So it looks like the new API works in this case. Thats 10.12 sorted, but I need to work backwards. Will try the transfrom code


- (BOOL)PKCSVerifyBytesSHA256withRSA:(NSData *)inputData signature:(NSData*)signatureData publicKey:(SecKeyRef)publicKey {
    CFErrorRef errorCF = nil;

    NSMutableData* digest = [[NSMutableData alloc] initWithLength:CC_SHA256_DIGEST_LENGTH];
    (void) CC_SHA256(inputData.bytes, (CC_LONG) inputData.length, digest.mutableBytes);

    // dinnae work
    OSStatus status = SecKeyRawVerify(
                                      publicKey,
                                      kSecPaddingPKCS1SHA256,
                                      digest.bytes,
                                      digest.length,
                                      signatureData.bytes,
                                      signatureData.length
                                      );

    // works

    Boolean verified = SecKeyVerifySignature(publicKey, kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA256, (__bridge CFDataRef) digest,  (__bridge CFDataRef) signatureData, &errorCF);

    if (verified == false){
        NSError* error = CFBridgingRelease(errorCF);
        NSLog(@"error is %@", error);
    }

    return status == errSecSuccess;
}
Accepted Answer

This seems to work, modified from CrytoCompatability, which turned out to be useful. Thanks for that link. I dont suppose that a bug report on the failure in SecKeyRawVerify is needed as you have a fix in later OS. I would suggest that some of the older API be marked as deprecated. Theres a lot of code on the internet use SecAddItem and SecKeyRawVerify which have problems on older OSes. As you know. Maybe the documentation should mention CryptoCompatibility in the headers.


-

(BOOL)verifyUsingTransForm:(NSData*)inputData signatureData:(NSData*)signatureData publicKey:(SecKeyRef)publicKey{
    BOOL                success;
    SecTransformRef     transform;
    CFBooleanRef        result;
    CFErrorRef          errorCF;

    result = NULL;
    errorCF = NULL;

    /

    transform = SecVerifyTransformCreate(publicKey, (__bridge CFDataRef)signatureData, &errorCF);
    success = (transform != NULL);

    /

    if (success) {
        success = setupTransformForAlgorithm(transform, &errorCF);
    }

    if (success) {
        success = SecTransformSetAttribute(transform, kSecTransformInputAttributeName, (__bridge CFDataRef) inputData, &errorCF) != false;
    }

    /

    if (success) {
        result = SecTransformExecute(transform, &errorCF);
        success = (result != NULL);
    }

    /

    if (success) {
        Boolean verified = (CFBooleanGetValue(result) != false);
        if (verified){
            NSLog(@"verified");
        } else {
            NSLog(@"Not verified");
        }
    } else {
        NSError* error  = (__bridge NSError *) errorCF;
        NSLog(@"error is %@", error);
    }

    /

    if (result != NULL) {
        CFRelease(result);
    }
    if (errorCF != NULL) {
        CFRelease(errorCF);
    }
    if (transform != NULL) {
        CFRelease(transform);
    }

    return success;
}
SecKeyRawVerify returning -67808
 
 
Q