PageRenderTime 41ms CodeModel.GetById 25ms app.highlight 13ms RepoModel.GetById 1ms app.codeStats 1ms

/core/autoinstaller/UpdateEngineExtensions/Signer.m

http://macfuse.googlecode.com/
Objective C | 124 lines | 91 code | 26 blank | 7 comment | 13 complexity | 9a8b925e41c8462a3739ff582c662ace MD5 | raw file
  1//
  2//  Signer.h
  3//  autoinstaller
  4//
  5//  Created by Greg Miller on 7/18/08.
  6//  Copyright 2008 Google Inc. All rights reserved.
  7//
  8
  9#include <openssl/pem.h>
 10#include <openssl/evp.h>
 11#include <openssl/rsa.h>
 12#import "Signer.h"
 13
 14
 15@implementation Signer
 16
 17+ (id)signerWithPublicKey:(NSData *)publicKey
 18               privateKey:(NSData *)privateKey {
 19  return [[[self alloc] initWithPublicKey:publicKey
 20                               privateKey:privateKey] autorelease];
 21}
 22
 23- (id)init {
 24  return [self initWithPublicKey:nil privateKey:nil];
 25}
 26
 27- (id)initWithPublicKey:(NSData *)publicKey
 28             privateKey:(NSData *)privateKey {
 29  if ((self = [super init])) {
 30    [self setPublicKey:publicKey];
 31    [self setPrivateKey:privateKey];
 32  }
 33  return self;
 34}
 35
 36- (void)dealloc {
 37  [publicKey_ release];
 38  [privateKey_ release];
 39  [super dealloc];
 40}
 41
 42- (NSData *)publicKey {
 43  return publicKey_;
 44}
 45
 46- (void)setPublicKey:(NSData *)publicKey {
 47  [publicKey_ autorelease];
 48  publicKey_ = [publicKey retain];
 49}
 50
 51- (NSData *)privateKey {
 52  return privateKey_;
 53}
 54
 55- (void)setPrivateKey:(NSData *)privateKey {
 56  [privateKey_ autorelease];
 57  privateKey_ = [privateKey retain];
 58}
 59
 60- (NSData *)signData:(NSData *)data {
 61  if (!data || !privateKey_)
 62    return nil;
 63  
 64  int success = 0;
 65  NSMutableData *signature = nil;
 66  
 67  const unsigned char *bytes = (const unsigned char *)[privateKey_ bytes];
 68  RSA *rsa = d2i_RSAPrivateKey(NULL, &bytes, [privateKey_ length]);
 69  if (rsa) {
 70    EVP_PKEY *keyWrapper = EVP_PKEY_new();
 71    EVP_PKEY_set1_RSA(keyWrapper, rsa);
 72    
 73    EVP_MD_CTX context;
 74    EVP_MD_CTX_init(&context);
 75    
 76    if (EVP_SignInit(&context, EVP_sha1()) &&
 77        EVP_SignUpdate(&context, [data bytes], [data length])) {
 78      signature = [NSMutableData dataWithLength:EVP_PKEY_size(keyWrapper)];
 79      unsigned int len = 0;
 80      success = EVP_SignFinal(&context,
 81                              [signature mutableBytes],
 82                              &len, keyWrapper);
 83      if (success)
 84        [signature setLength:len];
 85    }
 86    
 87    EVP_MD_CTX_cleanup(&context);
 88    EVP_PKEY_free(keyWrapper);
 89    RSA_free(rsa);
 90  }
 91  
 92  return success == 1 ? signature : nil;
 93}
 94
 95- (BOOL)isSignature:(NSData *)signature validForData:(NSData *)data {
 96  if (!signature || !data || !publicKey_)
 97    return NO;
 98  
 99  int success = 0;
100  
101  unsigned char *bytes = (unsigned char *)[publicKey_ bytes];
102  RSA *rsa = d2i_RSA_PUBKEY(NULL, &bytes, [publicKey_ length]);
103  if (rsa) {    
104    EVP_PKEY *keyWrapper = EVP_PKEY_new();
105    EVP_PKEY_set1_RSA(keyWrapper, rsa);
106    
107    EVP_MD_CTX context;
108    EVP_MD_CTX_init(&context);
109    
110    if (EVP_VerifyInit(&context, EVP_sha1()) &&
111        EVP_VerifyUpdate(&context, [data bytes], [data length])) {
112      success = EVP_VerifyFinal(&context, (UInt8 *)[signature bytes],
113                                [signature length], keyWrapper);
114    }
115    
116    EVP_MD_CTX_cleanup(&context);
117    EVP_PKEY_free(keyWrapper);
118    RSA_free(rsa);
119  }
120  
121  return (success == 1);
122}
123
124@end