mirror of https://github.com/oxen-io/session-ios
Identity Key QR verification
• this plumbs in the QR verification for iOS, both scanning contact and having your fingerprint scanned. Reviewed-by: @FredericJacobspull/1/head
parent
f67e0d13f0
commit
6b4f339d7e
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,15 @@
|
|||||||
|
//
|
||||||
|
// PresentIdentityQRCodeViewController.h
|
||||||
|
// Signal-iOS
|
||||||
|
//
|
||||||
|
// Created by Christine Corbett Moran on 3/30/14.
|
||||||
|
// Copyright (c) 2014 Open Whisper Systems. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <UIKit/UIKit.h>
|
||||||
|
|
||||||
|
@interface PresentIdentityQRCodeViewController : UIViewController
|
||||||
|
@property(nonatomic,strong) IBOutlet UIImageView* qrCodeView;
|
||||||
|
@property(nonatomic,strong) NSData* identityKey;
|
||||||
|
|
||||||
|
@end
|
@ -0,0 +1,75 @@
|
|||||||
|
//
|
||||||
|
// PresentIdentityQRCodeViewController.m
|
||||||
|
// Signal-iOS
|
||||||
|
//
|
||||||
|
// Created by Christine Corbett Moran on 3/30/14.
|
||||||
|
// Copyright (c) 2014 Open Whisper Systems. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "PresentIdentityQRCodeViewController.h"
|
||||||
|
#import "NSData+Base64.h"
|
||||||
|
|
||||||
|
|
||||||
|
@implementation PresentIdentityQRCodeViewController
|
||||||
|
|
||||||
|
|
||||||
|
- (void)didReceiveMemoryWarning {
|
||||||
|
[super didReceiveMemoryWarning];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
- (void) viewDidLoad {
|
||||||
|
[super viewDidLoad];
|
||||||
|
|
||||||
|
CIFilter *filter = [CIFilter filterWithName:@"CIQRCodeGenerator"];
|
||||||
|
|
||||||
|
[filter setDefaults];
|
||||||
|
|
||||||
|
[filter setValue:[[self.identityKey base64EncodedString] dataUsingEncoding:NSUTF8StringEncoding] forKey:@"inputMessage"];
|
||||||
|
|
||||||
|
CIImage *outputImage = [filter outputImage];
|
||||||
|
|
||||||
|
CIContext *context = [CIContext contextWithOptions:nil];
|
||||||
|
CGImageRef cgImage = [context createCGImage:outputImage fromRect:[outputImage extent]];
|
||||||
|
|
||||||
|
UIImage *image = [UIImage imageWithCGImage:cgImage scale:1. orientation:UIImageOrientationUp];
|
||||||
|
|
||||||
|
// Resize without interpolating
|
||||||
|
UIImage *resized = [self resizeImage:image withQuality:kCGInterpolationNone rate:5.0];
|
||||||
|
|
||||||
|
self.qrCodeView.image = resized;
|
||||||
|
|
||||||
|
CGImageRelease(cgImage);
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark - Action
|
||||||
|
- (IBAction)closeButtonAction:(id)sender
|
||||||
|
{
|
||||||
|
[UIView animateWithDuration:0.6 delay:0. options:UIViewAnimationOptionCurveEaseInOut animations:^{
|
||||||
|
[self.view setAlpha:0];
|
||||||
|
} completion:^(BOOL succeeded){
|
||||||
|
[self dismissViewControllerAnimated:YES completion:nil];
|
||||||
|
}];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#pragma mark - Private
|
||||||
|
|
||||||
|
- (UIImage *)resizeImage:(UIImage *)image withQuality:(CGInterpolationQuality)quality rate:(CGFloat)rate {
|
||||||
|
UIImage *resized = nil;
|
||||||
|
CGFloat width = image.size.width * rate;
|
||||||
|
CGFloat height = image.size.height * rate;
|
||||||
|
|
||||||
|
UIGraphicsBeginImageContext(CGSizeMake(width, height));
|
||||||
|
CGContextRef context = UIGraphicsGetCurrentContext();
|
||||||
|
CGContextSetInterpolationQuality(context, quality);
|
||||||
|
[image drawInRect:CGRectMake(0, 0, width, height)];
|
||||||
|
resized = UIGraphicsGetImageFromCurrentImageContext();
|
||||||
|
UIGraphicsEndImageContext();
|
||||||
|
|
||||||
|
return resized;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
@ -0,0 +1,22 @@
|
|||||||
|
//
|
||||||
|
// ScanIdentityBarcodeViewController.h
|
||||||
|
// Signal-iOS
|
||||||
|
//
|
||||||
|
// Created by Christine Corbett Moran on 3/29/14.
|
||||||
|
// Copyright (c) 2014 Open Whisper Systems. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <UIKit/UIKit.h>
|
||||||
|
#import <AVFoundation/AVFoundation.h>
|
||||||
|
@interface ScanIdentityBarcodeViewController : UIViewController<AVCaptureMetadataOutputObjectsDelegate>
|
||||||
|
|
||||||
|
@property(nonatomic,strong) AVCaptureSession *session;
|
||||||
|
@property(nonatomic,strong) AVCaptureDevice *device;
|
||||||
|
@property(nonatomic,strong) AVCaptureDeviceInput *input;
|
||||||
|
@property(nonatomic,strong) AVCaptureMetadataOutput *output;
|
||||||
|
@property(nonatomic,strong) AVCaptureVideoPreviewLayer *prevLayer;
|
||||||
|
|
||||||
|
@property(nonatomic,strong) UIView *highlightView;
|
||||||
|
@property(nonatomic,strong) UILabel *label;
|
||||||
|
@property(nonatomic,strong) NSData *identityKey;
|
||||||
|
@end
|
@ -0,0 +1,124 @@
|
|||||||
|
//
|
||||||
|
// ScanIdentityBarcodeViewController.m
|
||||||
|
// Signal-iOS
|
||||||
|
//
|
||||||
|
// Created by Christine Corbett Moran on 3/29/14.
|
||||||
|
// Copyright (c) 2014 Open Whisper Systems. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "ScanIdentityBarcodeViewController.h"
|
||||||
|
#import "NSData+Base64.h"
|
||||||
|
#import "NSData+hexString.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@implementation ScanIdentityBarcodeViewController
|
||||||
|
|
||||||
|
- (void)viewDidLoad {
|
||||||
|
[super viewDidLoad];
|
||||||
|
self.title = @"Scan key";
|
||||||
|
|
||||||
|
self.highlightView = [[UIView alloc] init];
|
||||||
|
self.highlightView.autoresizingMask = UIViewAutoresizingFlexibleTopMargin|UIViewAutoresizingFlexibleLeftMargin|UIViewAutoresizingFlexibleRightMargin|UIViewAutoresizingFlexibleBottomMargin;
|
||||||
|
self.highlightView.layer.borderColor = [UIColor greenColor].CGColor;
|
||||||
|
self.highlightView.layer.borderWidth = 4;
|
||||||
|
[self.view addSubview:self.highlightView];
|
||||||
|
|
||||||
|
self.label = [[UILabel alloc] init];
|
||||||
|
self.label.frame = CGRectMake(0, self.view.bounds.size.height - 40, self.view.bounds.size.width, 40);
|
||||||
|
self.label.autoresizingMask = UIViewAutoresizingFlexibleTopMargin;
|
||||||
|
self.label.backgroundColor = [UIColor colorWithWhite:0.15 alpha:0.65];
|
||||||
|
self.label.textColor = [UIColor whiteColor];
|
||||||
|
self.label.textAlignment = NSTextAlignmentCenter;
|
||||||
|
self.label.text = @"(none)";
|
||||||
|
[self.view addSubview:self.label];
|
||||||
|
|
||||||
|
self.session = [[AVCaptureSession alloc] init];
|
||||||
|
self.device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
|
||||||
|
NSError *error = nil;
|
||||||
|
|
||||||
|
self.input = [AVCaptureDeviceInput deviceInputWithDevice:self.device error:&error];
|
||||||
|
if (self.input) {
|
||||||
|
[self.session addInput:self.input];
|
||||||
|
} else {
|
||||||
|
NSLog(@"Error: %@", error);
|
||||||
|
}
|
||||||
|
|
||||||
|
self.output = [[AVCaptureMetadataOutput alloc] init];
|
||||||
|
[self.output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
|
||||||
|
[self.session addOutput:self.output];
|
||||||
|
|
||||||
|
self.output.metadataObjectTypes = [self.output availableMetadataObjectTypes];
|
||||||
|
|
||||||
|
self.prevLayer = [AVCaptureVideoPreviewLayer layerWithSession:self.session];
|
||||||
|
self.prevLayer.frame = self.view.bounds;
|
||||||
|
self.prevLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
|
||||||
|
[self.view.layer addSublayer:self.prevLayer];
|
||||||
|
|
||||||
|
[self.session startRunning];
|
||||||
|
|
||||||
|
[self.view bringSubviewToFront:self.highlightView];
|
||||||
|
[self.view bringSubviewToFront:self.label];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection {
|
||||||
|
CGRect highlightViewRect = CGRectZero;
|
||||||
|
AVMetadataMachineReadableCodeObject *barCodeObject;
|
||||||
|
NSString *detectionString = nil;
|
||||||
|
NSArray *barCodeTypes = @[AVMetadataObjectTypeQRCode];
|
||||||
|
|
||||||
|
for (AVMetadataObject *metadata in metadataObjects) {
|
||||||
|
NSLog(@"metadata %@",metadata);
|
||||||
|
for (NSString *type in barCodeTypes) {
|
||||||
|
if ([metadata.type isEqualToString:type]) {
|
||||||
|
barCodeObject = (AVMetadataMachineReadableCodeObject *)[self.prevLayer transformedMetadataObjectForMetadataObject:(AVMetadataMachineReadableCodeObject *)metadata];
|
||||||
|
highlightViewRect = barCodeObject.bounds;
|
||||||
|
detectionString = [(AVMetadataMachineReadableCodeObject *)metadata stringValue];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (detectionString != nil) {
|
||||||
|
self.label.text = detectionString;
|
||||||
|
NSData* detectionData = [NSData dataFromBase64String:detectionString];
|
||||||
|
if([detectionData isEqualToData:self.identityKey]) {
|
||||||
|
self.label.text = @"verified!";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
self.label.text = @"identity keys do not match";
|
||||||
|
}
|
||||||
|
[self.session stopRunning];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
self.label.text = @"searching...";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if([self.label.text isEqualToString:@"verified!"]) {
|
||||||
|
[self performSegueWithIdentifier:@"UnwindToIdentityKeyWasVerifiedSegue" sender:self];
|
||||||
|
}
|
||||||
|
|
||||||
|
self.highlightView.frame = highlightViewRect;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark - Action
|
||||||
|
- (IBAction)closeButtonAction:(id)sender
|
||||||
|
{
|
||||||
|
[UIView animateWithDuration:0.6 delay:0. options:UIViewAnimationOptionCurveEaseInOut animations:^{
|
||||||
|
[self.view setAlpha:0];
|
||||||
|
} completion:^(BOOL succeeded){
|
||||||
|
[self dismissViewControllerAnimated:YES completion:nil];
|
||||||
|
}];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue