/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. #include <openssl/pem.h>
  9. #include <openssl/evp.h>
  10. #include <openssl/rsa.h>
  11. #import "Signer.h"
  12. @implementation Signer
  13. + (id)signerWithPublicKey:(NSData *)publicKey
  14. privateKey:(NSData *)privateKey {
  15. return [[[self alloc] initWithPublicKey:publicKey
  16. privateKey:privateKey] autorelease];
  17. }
  18. - (id)init {
  19. return [self initWithPublicKey:nil privateKey:nil];
  20. }
  21. - (id)initWithPublicKey:(NSData *)publicKey
  22. privateKey:(NSData *)privateKey {
  23. if ((self = [super init])) {
  24. [self setPublicKey:publicKey];
  25. [self setPrivateKey:privateKey];
  26. }
  27. return self;
  28. }
  29. - (void)dealloc {
  30. [publicKey_ release];
  31. [privateKey_ release];
  32. [super dealloc];
  33. }
  34. - (NSData *)publicKey {
  35. return publicKey_;
  36. }
  37. - (void)setPublicKey:(NSData *)publicKey {
  38. [publicKey_ autorelease];
  39. publicKey_ = [publicKey retain];
  40. }
  41. - (NSData *)privateKey {
  42. return privateKey_;
  43. }
  44. - (void)setPrivateKey:(NSData *)privateKey {
  45. [privateKey_ autorelease];
  46. privateKey_ = [privateKey retain];
  47. }
  48. - (NSData *)signData:(NSData *)data {
  49. if (!data || !privateKey_)
  50. return nil;
  51. int success = 0;
  52. NSMutableData *signature = nil;
  53. const unsigned char *bytes = (const unsigned char *)[privateKey_ bytes];
  54. RSA *rsa = d2i_RSAPrivateKey(NULL, &bytes, [privateKey_ length]);
  55. if (rsa) {
  56. EVP_PKEY *keyWrapper = EVP_PKEY_new();
  57. EVP_PKEY_set1_RSA(keyWrapper, rsa);
  58. EVP_MD_CTX context;
  59. EVP_MD_CTX_init(&context);
  60. if (EVP_SignInit(&context, EVP_sha1()) &&
  61. EVP_SignUpdate(&context, [data bytes], [data length])) {
  62. signature = [NSMutableData dataWithLength:EVP_PKEY_size(keyWrapper)];
  63. unsigned int len = 0;
  64. success = EVP_SignFinal(&context,
  65. [signature mutableBytes],
  66. &len, keyWrapper);
  67. if (success)
  68. [signature setLength:len];
  69. }
  70. EVP_MD_CTX_cleanup(&context);
  71. EVP_PKEY_free(keyWrapper);
  72. RSA_free(rsa);
  73. }
  74. return success == 1 ? signature : nil;
  75. }
  76. - (BOOL)isSignature:(NSData *)signature validForData:(NSData *)data {
  77. if (!signature || !data || !publicKey_)
  78. return NO;
  79. int success = 0;
  80. unsigned char *bytes = (unsigned char *)[publicKey_ bytes];
  81. RSA *rsa = d2i_RSA_PUBKEY(NULL, &bytes, [publicKey_ length]);
  82. if (rsa) {
  83. EVP_PKEY *keyWrapper = EVP_PKEY_new();
  84. EVP_PKEY_set1_RSA(keyWrapper, rsa);
  85. EVP_MD_CTX context;
  86. EVP_MD_CTX_init(&context);
  87. if (EVP_VerifyInit(&context, EVP_sha1()) &&
  88. EVP_VerifyUpdate(&context, [data bytes], [data length])) {
  89. success = EVP_VerifyFinal(&context, (UInt8 *)[signature bytes],
  90. [signature length], keyWrapper);
  91. }
  92. EVP_MD_CTX_cleanup(&context);
  93. EVP_PKEY_free(keyWrapper);
  94. RSA_free(rsa);
  95. }
  96. return (success == 1);
  97. }
  98. @end