Operations/QCCRSASHASignature.m
/* |
Copyright (C) 2016 Apple Inc. All Rights Reserved. |
See LICENSE.txt for this sample’s licensing information |
Abstract: |
Implements RSA SHA signature signing and verification using the unified crypto API. |
*/ |
#import "QCCRSASHASignature.h" |
#include <CommonCrypto/CommonCrypto.h> |
static SecKeyAlgorithm _Nonnull secAlgorithmForAlgorithm(QCCRSASHASignatureAlgorithm algorithm) { |
switch (algorithm) { |
case QCCRSASHASignatureAlgorithmSHA1: { return kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA1; } break; |
case QCCRSASHASignatureAlgorithmSHA2_224: { return kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA224; } break; |
case QCCRSASHASignatureAlgorithmSHA2_256: { return kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA256; } break; |
case QCCRSASHASignatureAlgorithmSHA2_384: { return kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA384; } break; |
case QCCRSASHASignatureAlgorithmSHA2_512: { return kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA512; } break; |
default: { abort(); } break; |
} |
} |
#pragma mark - Sign |
NS_ASSUME_NONNULL_BEGIN |
@interface QCCRSASHAVerify () |
// read/write versions of public properties |
@property (atomic, copy, readwrite, nullable) NSError * error; |
@property (atomic, assign, readwrite) BOOL verified; |
@end |
NS_ASSUME_NONNULL_END |
@implementation QCCRSASHAVerify |
- (instancetype)init { |
abort(); |
} |
- (instancetype)initWithAlgorithm:(QCCRSASHASignatureAlgorithm)algorithm inputData:(NSData *)inputData publicKey:(SecKeyRef)publicKey signatureData:(NSData *)signatureData { |
NSParameterAssert(inputData != nil); |
NSParameterAssert(publicKey != NULL); |
NSParameterAssert(signatureData != nil); |
self = [super init]; |
if (self != nil) { |
self->_algorithm = algorithm; |
self->_inputData = [inputData copy]; |
self->_publicKey = publicKey; |
self->_signatureData = [signatureData copy]; |
} |
return self; |
} |
- (void)runUsingUnified { |
CFErrorRef errorCF = NULL; |
// Verify the signature against our input data. We don't need to calculate our own digest |
// because we're using a kSecKeyAlgorithmRSASignatureMessageXxx algorithm, which takes an |
// input message and generate the digest internally. |
// |
// If you /need/ to verify a digest rather than a message, check out the code for |
// QCCRSASHAVerifyCompat which shows how to do that. |
self.verified = SecKeyVerifySignature( |
self.publicKey, |
secAlgorithmForAlgorithm(self.algorithm), |
(__bridge CFDataRef) self.inputData, |
(__bridge CFDataRef) self.signatureData, |
&errorCF |
) != false; |
// Deal with the results. |
if ( ! self.verified ) { |
NSError * error; |
error = CFBridgingRelease( errorCF ); |
if ([error.domain isEqual:NSOSStatusErrorDomain] && (error.code == errSecVerifyFailed)) { |
// An explicit verify failure is not considered an error. |
assert(self.error == nil); |
} else { |
self.error = error; |
} |
} |
} |
- (void)main { |
[self runUsingUnified]; |
} |
@end |
#pragma mark - Sign |
NS_ASSUME_NONNULL_BEGIN |
@interface QCCRSASHASign () |
// read/write versions of public properties |
@property (atomic, copy, readwrite, nullable) NSError * error; |
@property (atomic, copy, readwrite, nullable) NSData * signatureData; |
@end |
NS_ASSUME_NONNULL_END |
@implementation QCCRSASHASign |
- (instancetype)initWithAlgorithm:(QCCRSASHASignatureAlgorithm)algorithm inputData:(NSData *)inputData privateKey:(SecKeyRef)privateKey { |
NSParameterAssert(inputData != nil); |
NSParameterAssert(privateKey != NULL); |
self = [super init]; |
if (self != nil) { |
self->_algorithm = algorithm; |
self->_inputData = [inputData copy]; |
self->_privateKey = privateKey; |
} |
return self; |
} |
- (instancetype)init { |
abort(); |
} |
- (void)runUsingUnified { |
CFErrorRef errorCF = NULL; |
NSData * resultData; |
// Sign the input data. We don't need to calculate our own digest because we're using |
// a kSecKeyAlgorithmRSASignatureMessageXxx algorithm, which takes an input message |
// and generate the digest internally. |
// |
// If you /need/ to sign a digest rather than a message, check out the code for |
// QCCRSASHASignCompat which shows how to do that. |
resultData = CFBridgingRelease( SecKeyCreateSignature( |
self.privateKey, |
secAlgorithmForAlgorithm(self.algorithm), |
(__bridge CFDataRef) self.inputData, |
&errorCF |
) ); |
// Deal with the results. |
if (resultData == nil) { |
self.error = CFBridgingRelease( errorCF ); |
} else { |
self.signatureData = resultData; |
} |
} |
- (void)main { |
[self runUsingUnified]; |
} |
@end |
Copyright © 2016 Apple Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2016-11-17