Skip to content

Instantly share code, notes, and snippets.

@mattstevens
Created August 27, 2012 23:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mattstevens/3493552 to your computer and use it in GitHub Desktop.
Save mattstevens/3493552 to your computer and use it in GitHub Desktop.
#import <Foundation/Foundation.h>
#import <Security/Security.h>
static const char *public_key = "-----BEGIN DSA PUBLIC KEY-----\n"
"MIHxMIGoBgcqhkjOOAQBMIGcAkEAvPM8vp7lHRrWFhpso2I/Wrq1qV8TSl7/YITH\n"
"7cHsINCP/xrZZpTlx14pKNkKwEEf3t3bdkKY97NQKRJ+cIRyawIVAMDJQP8l7EVy\n"
"fcqtVnJjJupPIccxAkBhLjwIRUNerlWb0kW357ABc4+65XB90lQIdcwVLGqRsx9A\n"
"wKoeeMUEyVdQhjJMnclvYJU+xqnl2AP9224QOGGLA0QAAkEAkFQyL1jGMfEjer1O\n"
"QjBq7knMY8zHEUVNRbPXBNS5QenFg07rgMUFL/Bj6/876pWvubwpDAcXkiK+SR3A\n"
"FRF/VA==\n"
"-----END DSA PUBLIC KEY-----\n";
/*
-----BEGIN DSA PRIVATE KEY-----
MIH4AgEAAkEAvPM8vp7lHRrWFhpso2I/Wrq1qV8TSl7/YITH7cHsINCP/xrZZpTl
x14pKNkKwEEf3t3bdkKY97NQKRJ+cIRyawIVAMDJQP8l7EVyfcqtVnJjJupPIccx
AkBhLjwIRUNerlWb0kW357ABc4+65XB90lQIdcwVLGqRsx9AwKoeeMUEyVdQhjJM
nclvYJU+xqnl2AP9224QOGGLAkEAkFQyL1jGMfEjer1OQjBq7knMY8zHEUVNRbPX
BNS5QenFg07rgMUFL/Bj6/876pWvubwpDAcXkiK+SR3AFRF/VAIUYOxpRfxp9Y+q
PirXRY83qU9vUXo=
-----END DSA PRIVATE KEY-----
*/
BOOL verify_separate(SecKeyRef publicKey, NSData *base32SignatureData, NSData *digest) {
BOOL result = NO;
SecTransformRef decoder = SecDecodeTransformCreate(kSecBase32Encoding, NULL);
SecTransformSetAttribute(decoder, kSecTransformInputAttributeName, base32SignatureData, NULL);
CFDataRef signature = SecTransformExecute(decoder, NULL);
SecTransformRef verifier = SecVerifyTransformCreate(publicKey, signature, NULL);
SecTransformSetAttribute(verifier, kSecTransformInputAttributeName, digest, NULL);
SecTransformSetAttribute(verifier, kSecDigestTypeAttribute, kSecDigestSHA1, NULL);
CFErrorRef error;
CFBooleanRef transformResult = SecTransformExecute(verifier, &error);
if (transformResult) {
result = (transformResult == kCFBooleanTrue);
CFRelease(transformResult);
} else if (error) {
CFShow(error);
}
CFRelease(verifier);
CFRelease(signature);
CFRelease(decoder);
return result;
}
BOOL verify_group(SecKeyRef publicKey, NSData *base32SignatureData, NSData *digest) {
BOOL result = NO;
SecGroupTransformRef group = SecTransformCreateGroupTransform();
SecTransformRef decoder = SecDecodeTransformCreate(kSecBase32Encoding, NULL);
SecTransformSetAttribute(decoder, kSecTransformInputAttributeName, base32SignatureData, NULL);
SecTransformRef verifier = SecVerifyTransformCreate(publicKey, NULL, NULL);
SecTransformSetAttribute(verifier, kSecTransformInputAttributeName, digest, NULL);
SecTransformSetAttribute(verifier, kSecDigestTypeAttribute, kSecDigestSHA1, NULL);
SecTransformConnectTransforms(decoder, kSecTransformOutputAttributeName,
verifier, kSecSignatureAttributeName,
group, NULL);
CFErrorRef error;
CFBooleanRef transformResult = SecTransformExecute(group, &error);
if (transformResult) {
result = (transformResult == kCFBooleanTrue);
CFRelease(transformResult);
} else if (error) {
CFShow(error);
}
CFRelease(verifier);
CFRelease(decoder);
CFRelease(group);
return result;
}
int main(int argc, char *argv[]) {
@autoreleasepool {
int i;
NSData *publicKeyData = [NSData dataWithBytes:public_key length:strlen(public_key)];
SecItemImportExportKeyParameters params = {};
SecExternalItemType keyType = kSecItemTypePublicKey;
SecExternalFormat keyFormat = kSecFormatPEMSequence;
CFArrayRef importArray = NULL;
SecItemImport((CFDataRef)publicKeyData,
NULL,
&keyFormat,
&keyType,
0,
&params,
NULL,
&importArray);
SecKeyRef publicKey = (SecKeyRef)CFArrayGetValueAtIndex(importArray, 0);
NSString *base32Signature = @"GAWAEFANCOPCYDRNUWUNG3OPNKNV6RR6QO4UWFICCQMR2YFHMGYWMWWT2OZIOBS7WTMTJ6APNI======";
NSData *base32SignatureData = [base32Signature dataUsingEncoding:NSUTF8StringEncoding];
NSData *digest = [@"Test" dataUsingEncoding:NSUTF8StringEncoding];
// This always works
for (i=0; i < 100; i++) {
if (!verify_separate(publicKey, base32SignatureData, digest)) {
NSLog(@"Failed at iteration %d", i);
return 1;
}
}
// This doesn't
for (i=0; i < 100; i++) {
if (!verify_group(publicKey, base32SignatureData, digest)) {
NSLog(@"Failed at iteration %d", i);
return 1;
}
}
NSLog(@"Passed");
CFRelease(importArray);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment